Merge topic 'revert-explicit-LANGUAGE-flag'

30aa715fac Revert "specify language flag when source LANGUAGE property is set"

Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !5519
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 5550c2f..626071a 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -52,7 +52,7 @@
         - .cmake_doc_artifacts
         - .run_only_for_package
 
-.upload:source-package:
+upload:source-package:
     extends:
         - .rsync_upload
         - .run_only_for_package
@@ -175,7 +175,7 @@
     needs:
         - prep:doc-package
 
-.upload:linux-x86_64-package:
+upload:linux-x86_64-package:
     extends:
         - .rsync_upload
         - .run_only_for_package
@@ -250,7 +250,7 @@
     needs:
         - prep:doc-package
 
-.upload:macos-package:
+upload:macos-package:
     extends:
         - .rsync_upload
         - .run_only_for_package
diff --git a/.gitlab/ci/configure_debian10_ninja.cmake b/.gitlab/ci/configure_debian10_ninja.cmake
index 2340543..90556bf 100644
--- a/.gitlab/ci/configure_debian10_ninja.cmake
+++ b/.gitlab/ci/configure_debian10_ninja.cmake
@@ -19,6 +19,7 @@
 set(CMake_TEST_FindGTest "ON" CACHE BOOL "")
 set(CMake_TEST_FindGTK2 "ON" CACHE BOOL "")
 set(CMake_TEST_FindIconv "ON" CACHE BOOL "")
+set(CMake_TEST_FindIntl "ON" CACHE BOOL "")
 set(CMake_TEST_FindJPEG "ON" CACHE BOOL "")
 set(CMake_TEST_FindJsonCpp "ON" CACHE BOOL "")
 set(CMake_TEST_FindLAPACK "ON" CACHE BOOL "")
diff --git a/.gitlab/ci/configure_fedora33_makefiles.cmake b/.gitlab/ci/configure_fedora33_makefiles.cmake
index 8d2454f..db2d005 100644
--- a/.gitlab/ci/configure_fedora33_makefiles.cmake
+++ b/.gitlab/ci/configure_fedora33_makefiles.cmake
@@ -19,6 +19,7 @@
 set(CMake_TEST_FindGTest "ON" CACHE BOOL "")
 set(CMake_TEST_FindGTK2 "ON" CACHE BOOL "")
 set(CMake_TEST_FindIconv "ON" CACHE BOOL "")
+set(CMake_TEST_FindIntl "ON" CACHE BOOL "")
 set(CMake_TEST_FindJPEG "ON" CACHE BOOL "")
 set(CMake_TEST_FindJsonCpp "ON" CACHE BOOL "")
 set(CMake_TEST_FindLAPACK "ON" CACHE BOOL "")
diff --git a/.gitlab/os-linux.yml b/.gitlab/os-linux.yml
index c69302a..6684d71 100644
--- a/.gitlab/os-linux.yml
+++ b/.gitlab/os-linux.yml
@@ -52,7 +52,7 @@
     image: "kitware/cmake:ci-fedora33-x86_64-2020-11-13"
 
     variables:
-        GIT_CLONE_PATH: "$CI_BUILDS_DIR/cmake ci"
+        GIT_CLONE_PATH: "$CI_BUILDS_DIR/cmake ci/long file name for testing purposes"
 
 #### Lint builds
 
diff --git a/Auxiliary/cmake-mode.el b/Auxiliary/cmake-mode.el
index caaf0d5..c3733ab 100644
--- a/Auxiliary/cmake-mode.el
+++ b/Auxiliary/cmake-mode.el
@@ -258,7 +258,8 @@
     (save-selected-window
       (select-window (display-buffer buffer 'not-this-window))
       (cmake-mode)
-      (read-only-mode 1))
+      (read-only-mode 1)
+      (view-mode 1))
     )
   )
 
diff --git a/Auxiliary/vim/extract-upper-case.pl b/Auxiliary/vim/extract-upper-case.pl
index 204b496..1179199 100755
--- a/Auxiliary/vim/extract-upper-case.pl
+++ b/Auxiliary/vim/extract-upper-case.pl
@@ -3,6 +3,8 @@
 use strict;
 use warnings;
 use POSIX qw(strftime);
+use JSON;
+use File::Basename;
 
 #my $cmake = "/home/pboettch/devel/upstream/cmake/build/bin/cmake";
 my $cmake = "cmake";
@@ -96,6 +98,28 @@
 # transform all properties in a hash
 my %properties = map { $_ => 1 } @properties;
 
+# read in manually written files
+my $modules_dir =  dirname(__FILE__) . "/modules";
+opendir(DIR, $modules_dir) || die "can't opendir $modules_dir: $!";
+my @json_files = grep { /\.json$/ && -f "$modules_dir/$_" } readdir(DIR);
+closedir DIR;
+
+foreach my $file (@json_files) {
+	local $/; # Enable 'slurp' mode
+	open my $fh, "<", $modules_dir."/".$file;
+	my $json = <$fh>;
+	close $fh;
+
+	my $mod = decode_json($json);
+	foreach my $var (@{$mod->{variables}}) {
+		$variables{$var} = 1;
+	}
+
+	while (my ($cmd, $keywords) = each %{$mod->{commands}}) {
+		$keywords{$cmd} = [ sort @{$keywords} ];
+	}
+}
+
 # version
 open(CMAKE, "$cmake --version|");
 my $version = 'unknown';
diff --git a/Auxiliary/vim/syntax/cmake.vim b/Auxiliary/vim/syntax/cmake.vim
index 2dd3174..a9bcf47 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.14.20190529-g067a4f
+" Version:      cmake version 3.19.20201028-gdab947f
 " 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:  2019 May 29
+" Last Change:  2020 oct. 28
 "
 " Licence:      The CMake license applies to this file. See
 "               https://cmake.org/licensing
@@ -44,7 +44,9 @@
             \ ADDITIONAL_CLEAN_FILES
             \ ADDITIONAL_MAKE_CLEAN_FILES
             \ ADVANCED
+            \ AIX_EXPORT_ALL_SYMBOLS
             \ ALIASED_TARGET
+            \ ALIAS_GLOBAL
             \ ALLOW_DUPLICATE_CUSTOM_TARGETS
             \ ANDROID_ANT_ADDITIONAL_OPTIONS
             \ ANDROID_API
@@ -79,6 +81,7 @@
             \ AUTOMOC_EXECUTABLE
             \ AUTOMOC_MACRO_NAMES
             \ AUTOMOC_MOC_OPTIONS
+            \ AUTOMOC_PATH_PREFIX
             \ AUTOMOC_SOURCE_GROUP
             \ AUTOMOC_TARGETS_FOLDER
             \ AUTORCC
@@ -100,8 +103,8 @@
             \ CACHE_VARIABLES
             \ CLEAN_NO_CUSTOM
             \ CMAKE_CONFIGURE_DEPENDS
-            \ CMAKE_CXX_KNOWN_FEATURES
             \ CMAKE_CUDA_KNOWN_FEATURES
+            \ CMAKE_CXX_KNOWN_FEATURES
             \ CMAKE_C_KNOWN_FEATURES
             \ CMAKE_ROLE
             \ COMMON_LANGUAGE_RUNTIME
@@ -123,9 +126,11 @@
             \ CPACK_START_MENU_SHORTCUTS
             \ CPACK_WIX_ACL
             \ CROSSCOMPILING_EMULATOR
+            \ CUDA_ARCHITECTURES
             \ CUDA_EXTENSIONS
             \ CUDA_PTX_COMPILATION
             \ CUDA_RESOLVE_DEVICE_SYMBOLS
+            \ CUDA_RUNTIME_LIBRARY
             \ CUDA_SEPARABLE_COMPILATION
             \ CUDA_STANDARD
             \ CUDA_STANDARD_REQUIRED
@@ -142,8 +147,11 @@
             \ DEPENDS
             \ DEPLOYMENT_ADDITIONAL_FILES
             \ DEPLOYMENT_REMOTE_DIRECTORY
+            \ DEPRECATION
             \ DISABLED
             \ DISABLED_FEATURES
+            \ DISABLE_PRECOMPILE_HEADERS
+            \ DOTNET_TARGET_FRAMEWORK
             \ DOTNET_TARGET_FRAMEWORK_VERSION
             \ ECLIPSE_EXTRA_CPROJECT_CONTENTS
             \ ECLIPSE_EXTRA_NATURES
@@ -202,6 +210,7 @@
             \ INCLUDE_DIRECTORIES
             \ INCLUDE_REGULAR_EXPRESSION
             \ INSTALL_NAME_DIR
+            \ INSTALL_REMOVE_ENVIRONMENT_RPATH
             \ INSTALL_RPATH
             \ INSTALL_RPATH_USE_LINK_PATH
             \ INTERFACE_AUTOUIC_OPTIONS
@@ -214,11 +223,14 @@
             \ INTERFACE_LINK_LIBRARIES
             \ INTERFACE_LINK_OPTIONS
             \ INTERFACE_POSITION_INDEPENDENT_CODE
+            \ INTERFACE_PRECOMPILE_HEADERS
             \ INTERFACE_SOURCES
             \ INTERFACE_SYSTEM_INCLUDE_DIRECTORIES
             \ INTERPROCEDURAL_OPTIMIZATION
             \ IN_TRY_COMPILE
             \ IOS_INSTALL_COMBINED
+            \ ISPC_HEADER_DIRECTORY
+            \ ISPC_INSTRUCTION_SETS
             \ JOB_POOLS
             \ JOB_POOL_COMPILE
             \ JOB_POOL_LINK
@@ -242,6 +254,8 @@
             \ LINK_WHAT_YOU_USE
             \ LISTFILE_STACK
             \ LOCATION
+            \ MACHO_COMPATIBILITY_VERSION
+            \ MACHO_CURRENT_VERSION
             \ MACOSX_BUNDLE
             \ MACOSX_BUNDLE_INFO_PLIST
             \ MACOSX_FRAMEWORK_INFO_PLIST
@@ -255,18 +269,29 @@
             \ NAME
             \ NO_SONAME
             \ NO_SYSTEM_FROM_IMPORTED
+            \ OBJCXX_EXTENSIONS
+            \ OBJCXX_STANDARD
+            \ OBJCXX_STANDARD_REQUIRED
+            \ OBJC_EXTENSIONS
+            \ OBJC_STANDARD
+            \ OBJC_STANDARD_REQUIRED
             \ OBJECT_DEPENDS
             \ OBJECT_OUTPUTS
+            \ OPTIMIZE_DEPENDENCIES
             \ OSX_ARCHITECTURES
             \ OUTPUT_NAME
             \ PACKAGES_FOUND
             \ PACKAGES_NOT_FOUND
             \ PARENT_DIRECTORY
             \ PASS_REGULAR_EXPRESSION
+            \ PCH_INSTANTIATE_TEMPLATES
+            \ PCH_WARN_INVALID
             \ PDB_NAME
             \ PDB_OUTPUT_DIRECTORY
             \ POSITION_INDEPENDENT_CODE
             \ POST_INSTALL_SCRIPT
+            \ PRECOMPILE_HEADERS
+            \ PRECOMPILE_HEADERS_REUSE_FROM
             \ PREDEFINED_TARGETS_FOLDER
             \ PREFIX
             \ PRE_INSTALL_SCRIPT
@@ -278,6 +303,7 @@
             \ REPORT_UNDEFINED_PROPERTIES
             \ REQUIRED_FILES
             \ RESOURCE
+            \ RESOURCE_GROUPS
             \ RESOURCE_LOCK
             \ RULE_LAUNCH_COMPILE
             \ RULE_LAUNCH_CUSTOM
@@ -291,8 +317,10 @@
             \ SKIP_AUTORCC
             \ SKIP_AUTOUIC
             \ SKIP_BUILD_RPATH
+            \ SKIP_PRECOMPILE_HEADERS
             \ SKIP_REGULAR_EXPRESSION
             \ SKIP_RETURN_CODE
+            \ SKIP_UNITY_BUILD_INCLUSION
             \ SOURCES
             \ SOURCE_DIR
             \ SOVERSION
@@ -304,6 +332,7 @@
             \ SYMBOLIC
             \ Swift_DEPENDENCIES_FILE
             \ Swift_DIAGNOSTICS_FILE
+            \ Swift_LANGUAGE_VERSION
             \ Swift_MODULE_DIRECTORY
             \ Swift_MODULE_NAME
             \ TARGET_ARCHIVES_MAY_BE_SHARED_LIBS
@@ -315,6 +344,12 @@
             \ TIMEOUT
             \ TIMEOUT_AFTER_MATCH
             \ TYPE
+            \ UNITY_BUILD
+            \ UNITY_BUILD_BATCH_SIZE
+            \ UNITY_BUILD_CODE_AFTER_INCLUDE
+            \ UNITY_BUILD_CODE_BEFORE_INCLUDE
+            \ UNITY_BUILD_MODE
+            \ UNITY_GROUP
             \ USE_FOLDERS
             \ VALUE
             \ VARIABLES
@@ -329,9 +364,11 @@
             \ VS_DEPLOYMENT_CONTENT
             \ VS_DEPLOYMENT_LOCATION
             \ VS_DESKTOP_EXTENSIONS_VERSION
+            \ VS_DOTNET_DOCUMENTATION_FILE
             \ VS_DOTNET_REFERENCES
             \ VS_DOTNET_REFERENCES_COPY_LOCAL
             \ VS_DOTNET_TARGET_FRAMEWORK_VERSION
+            \ VS_DPI_AWARE
             \ VS_GLOBAL_KEYWORD
             \ VS_GLOBAL_PROJECT_TYPES
             \ VS_GLOBAL_ROOTNAMESPACE
@@ -342,6 +379,8 @@
             \ VS_KEYWORD
             \ VS_MOBILE_EXTENSIONS_VERSION
             \ VS_NO_SOLUTION_DEPLOY
+            \ VS_PACKAGE_REFERENCES
+            \ VS_PLATFORM_TOOLSET
             \ VS_PROJECT_IMPORT
             \ VS_RESOURCE_GENERATOR
             \ VS_SCC_AUXPATH
@@ -349,6 +388,7 @@
             \ VS_SCC_PROJECTNAME
             \ VS_SCC_PROVIDER
             \ VS_SDK_REFERENCES
+            \ VS_SETTINGS
             \ VS_SHADER_DISABLE_OPTIMIZATIONS
             \ VS_SHADER_ENABLE_DEBUG
             \ VS_SHADER_ENTRYPOINT
@@ -358,6 +398,7 @@
             \ VS_SHADER_OUTPUT_HEADER_FILE
             \ VS_SHADER_TYPE
             \ VS_SHADER_VARIABLE_NAME
+            \ VS_SOLUTION_DEPLOY
             \ VS_STARTUP_PROJECT
             \ VS_TOOL_OVERRIDE
             \ VS_USER_PROPS
@@ -376,11 +417,13 @@
             \ XCODE_FILE_ATTRIBUTES
             \ XCODE_GENERATE_SCHEME
             \ XCODE_LAST_KNOWN_FILE_TYPE
+            \ XCODE_LINK_BUILD_PHASE_MODE
             \ XCODE_PRODUCT_TYPE
             \ XCODE_SCHEME_ADDRESS_SANITIZER
             \ XCODE_SCHEME_ADDRESS_SANITIZER_USE_AFTER_RETURN
             \ XCODE_SCHEME_ARGUMENTS
             \ XCODE_SCHEME_DEBUG_AS_ROOT
+            \ XCODE_SCHEME_DEBUG_DOCUMENT_VERSIONING
             \ XCODE_SCHEME_DISABLE_MAIN_THREAD_CHECKER
             \ XCODE_SCHEME_DYNAMIC_LIBRARY_LOADS
             \ XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE
@@ -395,6 +438,7 @@
             \ XCODE_SCHEME_THREAD_SANITIZER_STOP
             \ XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER
             \ XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP
+            \ XCODE_SCHEME_WORKING_DIRECTORY
             \ XCODE_SCHEME_ZOMBIE_OBJECTS
             \ XCTEST
 
@@ -405,6 +449,7 @@
             \ BUILD_SHARED_LIBS
             \ CACHE
             \ CMAKE_ABSOLUTE_DESTINATION_FILES
+            \ CMAKE_AIX_EXPORT_ALL_SYMBOLS
             \ CMAKE_ANDROID_ANT_ADDITIONAL_OPTIONS
             \ CMAKE_ANDROID_API
             \ CMAKE_ANDROID_API_MIN
@@ -485,6 +530,9 @@
             \ CMAKE_ASM_LINKER_WRAPPER_FLAG
             \ CMAKE_ASM_LINKER_WRAPPER_FLAG_SEP
             \ CMAKE_ASM_LINK_EXECUTABLE
+            \ CMAKE_ASM_LINK_LIBRARY_FILE_FLAG
+            \ CMAKE_ASM_LINK_LIBRARY_FLAG
+            \ CMAKE_ASM_LINK_LIBRARY_SUFFIX
             \ CMAKE_ASM_MASM
             \ CMAKE_ASM_MASM_ANDROID_TOOLCHAIN_MACHINE
             \ CMAKE_ASM_MASM_ANDROID_TOOLCHAIN_PREFIX
@@ -535,6 +583,9 @@
             \ CMAKE_ASM_MASM_LINKER_WRAPPER_FLAG
             \ CMAKE_ASM_MASM_LINKER_WRAPPER_FLAG_SEP
             \ 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_OUTPUT_EXTENSION
             \ CMAKE_ASM_MASM_PLATFORM_ID
             \ CMAKE_ASM_MASM_SIMULATE_ID
@@ -594,6 +645,9 @@
             \ CMAKE_ASM_NASM_LINKER_WRAPPER_FLAG
             \ CMAKE_ASM_NASM_LINKER_WRAPPER_FLAG_SEP
             \ 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_OUTPUT_EXTENSION
             \ CMAKE_ASM_NASM_PLATFORM_ID
             \ CMAKE_ASM_NASM_SIMULATE_ID
@@ -620,6 +674,7 @@
             \ CMAKE_AUTOMOC_DEPEND_FILTERS
             \ CMAKE_AUTOMOC_MACRO_NAMES
             \ CMAKE_AUTOMOC_MOC_OPTIONS
+            \ CMAKE_AUTOMOC_PATH_PREFIX
             \ CMAKE_AUTOMOC_RELAXED_MODE
             \ CMAKE_AUTORCC
             \ CMAKE_AUTORCC_OPTIONS
@@ -640,6 +695,7 @@
             \ CMAKE_CACHE_MINOR_VERSION
             \ CMAKE_CACHE_PATCH_VERSION
             \ CMAKE_CFG_INTDIR
+            \ CMAKE_CLANG_VFS_OVERLAY
             \ CMAKE_CL_64
             \ CMAKE_CODEBLOCKS_COMPILER_ID
             \ CMAKE_CODEBLOCKS_EXCLUDE_EXTERNAL_FILES
@@ -655,6 +711,7 @@
             \ CMAKE_CPACK_COMMAND
             \ CMAKE_CROSSCOMPILING
             \ CMAKE_CROSSCOMPILING_EMULATOR
+            \ CMAKE_CROSS_CONFIGS
             \ CMAKE_CSharp
             \ CMAKE_CSharp_ANDROID_TOOLCHAIN_MACHINE
             \ CMAKE_CSharp_ANDROID_TOOLCHAIN_PREFIX
@@ -705,6 +762,9 @@
             \ CMAKE_CSharp_LINKER_WRAPPER_FLAG
             \ CMAKE_CSharp_LINKER_WRAPPER_FLAG_SEP
             \ CMAKE_CSharp_LINK_EXECUTABLE
+            \ CMAKE_CSharp_LINK_LIBRARY_FILE_FLAG
+            \ CMAKE_CSharp_LINK_LIBRARY_FLAG
+            \ CMAKE_CSharp_LINK_LIBRARY_SUFFIX
             \ CMAKE_CSharp_OUTPUT_EXTENSION
             \ CMAKE_CSharp_PLATFORM_ID
             \ CMAKE_CSharp_SIMULATE_ID
@@ -714,11 +774,13 @@
             \ CMAKE_CSharp_STANDARD_INCLUDE_DIRECTORIES
             \ CMAKE_CSharp_STANDARD_LIBRARIES
             \ CMAKE_CSharp_VISIBILITY_PRESET
+            \ CMAKE_CTEST_ARGUMENTS
             \ CMAKE_CTEST_COMMAND
             \ CMAKE_CUDA
             \ CMAKE_CUDA_ANDROID_TOOLCHAIN_MACHINE
             \ CMAKE_CUDA_ANDROID_TOOLCHAIN_PREFIX
             \ CMAKE_CUDA_ANDROID_TOOLCHAIN_SUFFIX
+            \ CMAKE_CUDA_ARCHITECTURES
             \ CMAKE_CUDA_ARCHIVE_APPEND
             \ CMAKE_CUDA_ARCHIVE_CREATE
             \ CMAKE_CUDA_ARCHIVE_FINISH
@@ -728,7 +790,6 @@
             \ CMAKE_CUDA_COMPILER_AR
             \ CMAKE_CUDA_COMPILER_ARCHITECTURE_ID
             \ CMAKE_CUDA_COMPILER_EXTERNAL_TOOLCHAIN
-            \ CMAKE_CUDA_COMPILE_FEATURES
             \ CMAKE_CUDA_COMPILER_ID
             \ CMAKE_CUDA_COMPILER_LAUNCHER
             \ CMAKE_CUDA_COMPILER_LOADED
@@ -737,6 +798,7 @@
             \ CMAKE_CUDA_COMPILER_TARGET
             \ CMAKE_CUDA_COMPILER_VERSION
             \ CMAKE_CUDA_COMPILER_VERSION_INTERNAL
+            \ CMAKE_CUDA_COMPILE_FEATURES
             \ CMAKE_CUDA_COMPILE_OBJECT
             \ CMAKE_CUDA_CPPCHECK
             \ CMAKE_CUDA_CPPLINT
@@ -768,8 +830,13 @@
             \ CMAKE_CUDA_LINKER_WRAPPER_FLAG
             \ CMAKE_CUDA_LINKER_WRAPPER_FLAG_SEP
             \ CMAKE_CUDA_LINK_EXECUTABLE
+            \ CMAKE_CUDA_LINK_LIBRARY_FILE_FLAG
+            \ CMAKE_CUDA_LINK_LIBRARY_FLAG
+            \ CMAKE_CUDA_LINK_LIBRARY_SUFFIX
             \ CMAKE_CUDA_OUTPUT_EXTENSION
             \ CMAKE_CUDA_PLATFORM_ID
+            \ CMAKE_CUDA_RESOLVE_DEVICE_SYMBOLS
+            \ CMAKE_CUDA_RUNTIME_LIBRARY
             \ CMAKE_CUDA_SEPARABLE_COMPILATION
             \ CMAKE_CUDA_SIMULATE_ID
             \ CMAKE_CUDA_SIMULATE_VERSION
@@ -782,6 +849,10 @@
             \ CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES
             \ CMAKE_CUDA_VISIBILITY_PRESET
             \ CMAKE_CURRENT_BINARY_DIR
+            \ CMAKE_CURRENT_FUNCTION
+            \ CMAKE_CURRENT_FUNCTION_LIST_DIR
+            \ CMAKE_CURRENT_FUNCTION_LIST_FILE
+            \ CMAKE_CURRENT_FUNCTION_LIST_LINE
             \ CMAKE_CURRENT_LIST_DIR
             \ CMAKE_CURRENT_LIST_FILE
             \ CMAKE_CURRENT_LIST_LINE
@@ -838,6 +909,9 @@
             \ CMAKE_CXX_LINKER_WRAPPER_FLAG
             \ CMAKE_CXX_LINKER_WRAPPER_FLAG_SEP
             \ CMAKE_CXX_LINK_EXECUTABLE
+            \ CMAKE_CXX_LINK_LIBRARY_FILE_FLAG
+            \ CMAKE_CXX_LINK_LIBRARY_FLAG
+            \ CMAKE_CXX_LINK_LIBRARY_SUFFIX
             \ CMAKE_CXX_OUTPUT_EXTENSION
             \ CMAKE_CXX_PLATFORM_ID
             \ CMAKE_CXX_SIMULATE_ID
@@ -900,6 +974,9 @@
             \ CMAKE_C_LINKER_WRAPPER_FLAG
             \ CMAKE_C_LINKER_WRAPPER_FLAG_SEP
             \ CMAKE_C_LINK_EXECUTABLE
+            \ CMAKE_C_LINK_LIBRARY_FILE_FLAG
+            \ CMAKE_C_LINK_LIBRARY_FLAG
+            \ CMAKE_C_LINK_LIBRARY_SUFFIX
             \ CMAKE_C_OUTPUT_EXTENSION
             \ CMAKE_C_PLATFORM_ID
             \ CMAKE_C_SIMULATE_ID
@@ -913,9 +990,13 @@
             \ CMAKE_C_VISIBILITY_PRESET
             \ CMAKE_DEBUG_POSTFIX
             \ CMAKE_DEBUG_TARGET_PROPERTIES
+            \ CMAKE_DEFAULT_BUILD_TYPE
+            \ CMAKE_DEFAULT_CONFIGS
             \ CMAKE_DEPENDS_IN_PROJECT_ONLY
             \ CMAKE_DIRECTORY_LABELS
+            \ CMAKE_DISABLE_PRECOMPILE_HEADERS
             \ CMAKE_DL_LIBS
+            \ CMAKE_DOTNET_TARGET_FRAMEWORK
             \ CMAKE_DOTNET_TARGET_FRAMEWORK_VERSION
             \ CMAKE_ECLIPSE_GENERATE_LINKED_RESOURCES
             \ CMAKE_ECLIPSE_GENERATE_SOURCE_PROJECT
@@ -936,6 +1017,7 @@
             \ CMAKE_EXTRA_GENERATOR
             \ CMAKE_EXTRA_SHARED_LIBRARY_SUFFIXES
             \ CMAKE_FIND_APPBUNDLE
+            \ CMAKE_FIND_DEBUG_MODE
             \ CMAKE_FIND_FRAMEWORK
             \ CMAKE_FIND_LIBRARY_CUSTOM_LIB_SUFFIX
             \ CMAKE_FIND_LIBRARY_PREFIXES
@@ -960,6 +1042,7 @@
             \ CMAKE_FIND_USE_PACKAGE_REGISTRY
             \ CMAKE_FIND_USE_PACKAGE_ROOT_PATH
             \ CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH
+            \ CMAKE_FIND_USE_SYSTEM_PACKAGE_REGISTRY
             \ CMAKE_FOLDER
             \ CMAKE_FRAMEWORK
             \ CMAKE_FRAMEWORK_PATH
@@ -1014,6 +1097,9 @@
             \ CMAKE_Fortran_LINKER_WRAPPER_FLAG
             \ CMAKE_Fortran_LINKER_WRAPPER_FLAG_SEP
             \ CMAKE_Fortran_LINK_EXECUTABLE
+            \ CMAKE_Fortran_LINK_LIBRARY_FILE_FLAG
+            \ CMAKE_Fortran_LINK_LIBRARY_FLAG
+            \ CMAKE_Fortran_LINK_LIBRARY_SUFFIX
             \ CMAKE_Fortran_MODDIR_DEFAULT
             \ CMAKE_Fortran_MODDIR_FLAG
             \ CMAKE_Fortran_MODOUT_FLAG
@@ -1048,7 +1134,6 @@
             \ CMAKE_HOST_UNIX
             \ CMAKE_HOST_WIN32
             \ CMAKE_IGNORE_PATH
-            \ CMAKE_ISPC_HEADER_DIRECTORY
             \ CMAKE_IMPORT_LIBRARY_PREFIX
             \ CMAKE_IMPORT_LIBRARY_SUFFIX
             \ CMAKE_INCLUDE_CURRENT_DIR
@@ -1062,11 +1147,14 @@
             \ CMAKE_INSTALL_NAME_DIR
             \ CMAKE_INSTALL_PREFIX
             \ CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT
+            \ CMAKE_INSTALL_REMOVE_ENVIRONMENT_RPATH
             \ CMAKE_INSTALL_RPATH
             \ CMAKE_INSTALL_RPATH_USE_LINK_PATH
             \ CMAKE_INTERNAL_PLATFORM_ABI
             \ CMAKE_INTERPROCEDURAL_OPTIMIZATION
             \ CMAKE_IOS_INSTALL_COMBINED
+            \ CMAKE_ISPC_HEADER_DIRECTORY
+            \ CMAKE_ISPC_INSTRUCTION_SETS
             \ CMAKE_JOB_POOLS
             \ CMAKE_JOB_POOL_COMPILE
             \ CMAKE_JOB_POOL_LINK
@@ -1121,6 +1209,9 @@
             \ CMAKE_Java_LINKER_WRAPPER_FLAG
             \ CMAKE_Java_LINKER_WRAPPER_FLAG_SEP
             \ CMAKE_Java_LINK_EXECUTABLE
+            \ CMAKE_Java_LINK_LIBRARY_FILE_FLAG
+            \ CMAKE_Java_LINK_LIBRARY_FLAG
+            \ CMAKE_Java_LINK_LIBRARY_SUFFIX
             \ CMAKE_Java_OUTPUT_EXTENSION
             \ CMAKE_Java_PLATFORM_ID
             \ CMAKE_Java_SIMULATE_ID
@@ -1151,6 +1242,10 @@
             \ CMAKE_MAKE_PROGRAM
             \ CMAKE_MATCH_COUNT
             \ CMAKE_MAXIMUM_RECURSION_DEPTH
+            \ CMAKE_MESSAGE_CONTEXT
+            \ CMAKE_MESSAGE_CONTEXT_SHOW
+            \ CMAKE_MESSAGE_INDENT
+            \ CMAKE_MESSAGE_LOG_LEVEL
             \ CMAKE_MFC_FLAG
             \ CMAKE_MINIMUM_REQUIRED_VERSION
             \ CMAKE_MINOR_VERSION
@@ -1165,12 +1260,23 @@
             \ CMAKE_NOT_USING_CONFIG_FLAGS
             \ CMAKE_NO_BUILTIN_CHRPATH
             \ CMAKE_NO_SYSTEM_FROM_IMPORTED
+            \ CMAKE_OBJCXX_CLANG_TIDY
+            \ CMAKE_OBJCXX_EXTENSIONS
+            \ CMAKE_OBJCXX_STANDARD
+            \ CMAKE_OBJCXX_STANDARD_REQUIRED
+            \ CMAKE_OBJC_CLANG_TIDY
+            \ CMAKE_OBJC_EXTENSIONS
+            \ CMAKE_OBJC_STANDARD
+            \ CMAKE_OBJC_STANDARD_REQUIRED
             \ CMAKE_OBJECT_PATH_MAX
+            \ CMAKE_OPTIMIZE_DEPENDENCIES
             \ CMAKE_OSX_ARCHITECTURES
             \ CMAKE_OSX_DEPLOYMENT_TARGET
             \ CMAKE_OSX_SYSROOT
             \ CMAKE_PARENT_LIST_FILE
             \ CMAKE_PATCH_VERSION
+            \ CMAKE_PCH_INSTANTIATE_TEMPLATES
+            \ CMAKE_PCH_WARN_INVALID
             \ CMAKE_PDB_OUTPUT_DIRECTORY
             \ CMAKE_POSITION_INDEPENDENT_CODE
             \ CMAKE_PREFIX_PATH
@@ -1236,6 +1342,9 @@
             \ CMAKE_RC_LINKER_WRAPPER_FLAG
             \ CMAKE_RC_LINKER_WRAPPER_FLAG_SEP
             \ CMAKE_RC_LINK_EXECUTABLE
+            \ CMAKE_RC_LINK_LIBRARY_FILE_FLAG
+            \ CMAKE_RC_LINK_LIBRARY_FLAG
+            \ CMAKE_RC_LINK_LIBRARY_SUFFIX
             \ CMAKE_RC_OUTPUT_EXTENSION
             \ CMAKE_RC_PLATFORM_ID
             \ CMAKE_RC_SIMULATE_ID
@@ -1335,7 +1444,11 @@
             \ CMAKE_Swift_LINKER_WRAPPER_FLAG
             \ CMAKE_Swift_LINKER_WRAPPER_FLAG_SEP
             \ CMAKE_Swift_LINK_EXECUTABLE
+            \ CMAKE_Swift_LINK_LIBRARY_FILE_FLAG
+            \ CMAKE_Swift_LINK_LIBRARY_FLAG
+            \ CMAKE_Swift_LINK_LIBRARY_SUFFIX
             \ CMAKE_Swift_MODULE_DIRECTORY
+            \ CMAKE_Swift_NUM_THREADS
             \ CMAKE_Swift_OUTPUT_EXTENSION
             \ CMAKE_Swift_PLATFORM_ID
             \ CMAKE_Swift_SIMULATE_ID
@@ -1350,6 +1463,8 @@
             \ CMAKE_TRY_COMPILE_PLATFORM_VARIABLES
             \ CMAKE_TRY_COMPILE_TARGET_TYPE
             \ CMAKE_TWEAK_VERSION
+            \ CMAKE_UNITY_BUILD
+            \ CMAKE_UNITY_BUILD_BATCH_SIZE
             \ CMAKE_USER_MAKE_RULES_OVERRIDE
             \ CMAKE_USER_MAKE_RULES_OVERRIDE_ASM
             \ CMAKE_USER_MAKE_RULES_OVERRIDE_ASM_MASM
@@ -1378,6 +1493,7 @@
             \ CMAKE_VS_PLATFORM_NAME_DEFAULT
             \ CMAKE_VS_PLATFORM_TOOLSET
             \ CMAKE_VS_PLATFORM_TOOLSET_CUDA
+            \ CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR
             \ CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE
             \ CMAKE_VS_PLATFORM_TOOLSET_VERSION
             \ CMAKE_VS_SDK_EXCLUDE_DIRECTORIES
@@ -1388,19 +1504,24 @@
             \ CMAKE_VS_SDK_REFERENCE_DIRECTORIES
             \ CMAKE_VS_SDK_SOURCE_DIRECTORIES
             \ CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION
+            \ CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION_MAXIMUM
             \ CMAKE_VS_WINRT_BY_DEFAULT
             \ CMAKE_WARN_DEPRECATED
             \ CMAKE_WARN_ON_ABSOLUTE_INSTALL_DESTINATION
             \ CMAKE_WIN32_EXECUTABLE
             \ CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS
+            \ CMAKE_XCODE_BUILD_SYSTEM
             \ CMAKE_XCODE_GENERATE_SCHEME
             \ CMAKE_XCODE_GENERATE_TOP_LEVEL_PROJECT_ONLY
+            \ CMAKE_XCODE_LINK_BUILD_PHASE_MODE
             \ CMAKE_XCODE_PLATFORM_TOOLSET
             \ CMAKE_XCODE_SCHEME_ADDRESS_SANITIZER
             \ CMAKE_XCODE_SCHEME_ADDRESS_SANITIZER_USE_AFTER_RETURN
+            \ CMAKE_XCODE_SCHEME_DEBUG_DOCUMENT_VERSIONING
             \ CMAKE_XCODE_SCHEME_DISABLE_MAIN_THREAD_CHECKER
             \ CMAKE_XCODE_SCHEME_DYNAMIC_LIBRARY_LOADS
             \ CMAKE_XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE
+            \ CMAKE_XCODE_SCHEME_ENVIRONMENT
             \ CMAKE_XCODE_SCHEME_GUARD_MALLOC
             \ CMAKE_XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP
             \ CMAKE_XCODE_SCHEME_MALLOC_GUARD_EDGES
@@ -1410,13 +1531,13 @@
             \ CMAKE_XCODE_SCHEME_THREAD_SANITIZER_STOP
             \ CMAKE_XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER
             \ CMAKE_XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP
+            \ CMAKE_XCODE_SCHEME_WORKING_DIRECTORY
             \ CMAKE_XCODE_SCHEME_ZOMBIE_OBJECTS
             \ CPACK_ABSOLUTE_DESTINATION_FILES
             \ CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY
             \ CPACK_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION
             \ CPACK_INCLUDE_TOPLEVEL_DIRECTORY
             \ CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS
-            \ CPACK_INSTALL_SCRIPT
             \ CPACK_PACKAGING_INSTALL_PREFIX
             \ CPACK_SET_DESTDIR
             \ CPACK_WARN_ON_ABSOLUTE_INSTALL_DESTINATION
@@ -1476,6 +1597,7 @@
             \ CTEST_P4_COMMAND
             \ CTEST_P4_OPTIONS
             \ CTEST_P4_UPDATE_OPTIONS
+            \ CTEST_RESOURCE_SPEC_FILE
             \ CTEST_RUN_CURRENT_SCRIPT
             \ CTEST_SCP_COMMAND
             \ CTEST_SITE
@@ -1493,6 +1615,283 @@
             \ CTEST_UPDATE_VERSION_OVERRIDE
             \ CTEST_USE_LAUNCHERS
             \ CYGWIN
+            \ DOXYGEN_ABBREVIATE_BRIEF
+            \ DOXYGEN_ALIASES
+            \ DOXYGEN_ALLEXTERNALS
+            \ DOXYGEN_ALLOW_UNICODE_NAMES
+            \ DOXYGEN_ALPHABETICAL_INDEX
+            \ DOXYGEN_ALWAYS_DETAILED_SEC
+            \ DOXYGEN_AUTOLINK_SUPPORT
+            \ DOXYGEN_BINARY_TOC
+            \ DOXYGEN_BRIEF_MEMBER_DESC
+            \ DOXYGEN_BUILTIN_STL_SUPPORT
+            \ DOXYGEN_CALLER_GRAPH
+            \ DOXYGEN_CALL_GRAPH
+            \ DOXYGEN_CASE_SENSE_NAMES
+            \ DOXYGEN_CHM_FILE
+            \ DOXYGEN_CHM_INDEX_ENCODING
+            \ DOXYGEN_CITE_BIB_FILES
+            \ DOXYGEN_CLANG_ASSISTED_PARSING
+            \ DOXYGEN_CLANG_DATABASE_PATH
+            \ DOXYGEN_CLANG_OPTIONS
+            \ DOXYGEN_CLASS_DIAGRAMS
+            \ DOXYGEN_CLASS_GRAPH
+            \ DOXYGEN_COLLABORATION_GRAPH
+            \ DOXYGEN_COLS_IN_ALPHA_INDEX
+            \ DOXYGEN_COMPACT_LATEX
+            \ DOXYGEN_COMPACT_RTF
+            \ DOXYGEN_CPP_CLI_SUPPORT
+            \ DOXYGEN_CREATE_SUBDIRS
+            \ DOXYGEN_DIAFILE_DIRS
+            \ DOXYGEN_DIA_PATH
+            \ DOXYGEN_DIRECTORY_GRAPH
+            \ DOXYGEN_DISABLE_INDEX
+            \ DOXYGEN_DISTRIBUTE_GROUP_DOC
+            \ DOXYGEN_DOCBOOK_OUTPUT
+            \ DOXYGEN_DOCBOOK_PROGRAMLISTING
+            \ DOXYGEN_DOCSET_BUNDLE_ID
+            \ DOXYGEN_DOCSET_FEEDNAME
+            \ DOXYGEN_DOCSET_PUBLISHER_ID
+            \ DOXYGEN_DOCSET_PUBLISHER_NAME
+            \ DOXYGEN_DOTFILE_DIRS
+            \ DOXYGEN_DOT_CLEANUP
+            \ DOXYGEN_DOT_FONTNAME
+            \ DOXYGEN_DOT_FONTPATH
+            \ DOXYGEN_DOT_FONTSIZE
+            \ DOXYGEN_DOT_GRAPH_MAX_NODES
+            \ DOXYGEN_DOT_IMAGE_FORMAT
+            \ DOXYGEN_DOT_MULTI_TARGETS
+            \ DOXYGEN_DOT_NUM_THREADS
+            \ DOXYGEN_DOT_PATH
+            \ DOXYGEN_DOT_TRANSPARENT
+            \ DOXYGEN_DOXYFILE_ENCODING
+            \ DOXYGEN_ECLIPSE_DOC_ID
+            \ DOXYGEN_ENABLED_SECTIONS
+            \ DOXYGEN_ENABLE_PREPROCESSING
+            \ DOXYGEN_ENUM_VALUES_PER_LINE
+            \ DOXYGEN_EXAMPLE_PATH
+            \ DOXYGEN_EXAMPLE_PATTERNS
+            \ DOXYGEN_EXAMPLE_RECURSIVE
+            \ DOXYGEN_EXCLUDE
+            \ DOXYGEN_EXCLUDE_PATTERNS
+            \ DOXYGEN_EXCLUDE_SYMBOLS
+            \ DOXYGEN_EXCLUDE_SYMLINKS
+            \ DOXYGEN_EXPAND_AS_DEFINED
+            \ DOXYGEN_EXPAND_ONLY_PREDEF
+            \ DOXYGEN_EXTENSION_MAPPING
+            \ DOXYGEN_EXTERNAL_GROUPS
+            \ DOXYGEN_EXTERNAL_PAGES
+            \ DOXYGEN_EXTERNAL_SEARCH
+            \ DOXYGEN_EXTERNAL_SEARCH_ID
+            \ DOXYGEN_EXTRACT_ALL
+            \ DOXYGEN_EXTRACT_ANON_NSPACES
+            \ DOXYGEN_EXTRACT_LOCAL_CLASSES
+            \ DOXYGEN_EXTRACT_LOCAL_METHODS
+            \ DOXYGEN_EXTRACT_PACKAGE
+            \ DOXYGEN_EXTRACT_PRIVATE
+            \ DOXYGEN_EXTRACT_PRIV_VIRTUAL
+            \ DOXYGEN_EXTRACT_STATIC
+            \ DOXYGEN_EXTRA_PACKAGES
+            \ DOXYGEN_EXTRA_SEARCH_MAPPINGS
+            \ DOXYGEN_EXT_LINKS_IN_WINDOW
+            \ DOXYGEN_FILE_PATTERNS
+            \ DOXYGEN_FILE_VERSION_FILTER
+            \ DOXYGEN_FILTER_PATTERNS
+            \ DOXYGEN_FILTER_SOURCE_FILES
+            \ DOXYGEN_FILTER_SOURCE_PATTERNS
+            \ DOXYGEN_FORCE_LOCAL_INCLUDES
+            \ DOXYGEN_FORMULA_FONTSIZE
+            \ DOXYGEN_FORMULA_TRANSPARENT
+            \ DOXYGEN_FULL_PATH_NAMES
+            \ DOXYGEN_GENERATE_AUTOGEN_DEF
+            \ DOXYGEN_GENERATE_BUGLIST
+            \ DOXYGEN_GENERATE_CHI
+            \ DOXYGEN_GENERATE_DEPRECATEDLIST
+            \ DOXYGEN_GENERATE_DOCBOOK
+            \ DOXYGEN_GENERATE_DOCSET
+            \ DOXYGEN_GENERATE_ECLIPSEHELP
+            \ DOXYGEN_GENERATE_HTML
+            \ DOXYGEN_GENERATE_HTMLHELP
+            \ DOXYGEN_GENERATE_LATEX
+            \ DOXYGEN_GENERATE_LEGEND
+            \ DOXYGEN_GENERATE_MAN
+            \ DOXYGEN_GENERATE_PERLMOD
+            \ DOXYGEN_GENERATE_QHP
+            \ DOXYGEN_GENERATE_RTF
+            \ DOXYGEN_GENERATE_TAGFILE
+            \ DOXYGEN_GENERATE_TESTLIST
+            \ DOXYGEN_GENERATE_TODOLIST
+            \ DOXYGEN_GENERATE_TREEVIEW
+            \ DOXYGEN_GENERATE_XML
+            \ DOXYGEN_GRAPHICAL_HIERARCHY
+            \ DOXYGEN_GROUP_GRAPHS
+            \ DOXYGEN_GROUP_NESTED_COMPOUNDS
+            \ DOXYGEN_HAVE_DOT
+            \ DOXYGEN_HHC_LOCATION
+            \ DOXYGEN_HIDE_COMPOUND_REFERENCE
+            \ DOXYGEN_HIDE_FRIEND_COMPOUNDS
+            \ DOXYGEN_HIDE_IN_BODY_DOCS
+            \ DOXYGEN_HIDE_SCOPE_NAMES
+            \ DOXYGEN_HIDE_UNDOC_CLASSES
+            \ DOXYGEN_HIDE_UNDOC_MEMBERS
+            \ DOXYGEN_HIDE_UNDOC_RELATIONS
+            \ DOXYGEN_HTML_COLORSTYLE_GAMMA
+            \ DOXYGEN_HTML_COLORSTYLE_HUE
+            \ DOXYGEN_HTML_COLORSTYLE_SAT
+            \ DOXYGEN_HTML_DYNAMIC_MENUS
+            \ DOXYGEN_HTML_DYNAMIC_SECTIONS
+            \ DOXYGEN_HTML_EXTRA_FILES
+            \ DOXYGEN_HTML_EXTRA_STYLESHEET
+            \ DOXYGEN_HTML_FILE_EXTENSION
+            \ DOXYGEN_HTML_FOOTER
+            \ DOXYGEN_HTML_HEADER
+            \ DOXYGEN_HTML_INDEX_NUM_ENTRIES
+            \ DOXYGEN_HTML_OUTPUT
+            \ DOXYGEN_HTML_STYLESHEET
+            \ DOXYGEN_HTML_TIMESTAMP
+            \ DOXYGEN_IDL_PROPERTY_SUPPORT
+            \ DOXYGEN_IGNORE_PREFIX
+            \ DOXYGEN_IMAGE_PATH
+            \ DOXYGEN_INCLUDED_BY_GRAPH
+            \ DOXYGEN_INCLUDE_FILE_PATTERNS
+            \ DOXYGEN_INCLUDE_GRAPH
+            \ DOXYGEN_INCLUDE_PATH
+            \ DOXYGEN_INHERIT_DOCS
+            \ DOXYGEN_INLINE_GROUPED_CLASSES
+            \ DOXYGEN_INLINE_INFO
+            \ DOXYGEN_INLINE_INHERITED_MEMB
+            \ DOXYGEN_INLINE_SIMPLE_STRUCTS
+            \ DOXYGEN_INLINE_SOURCES
+            \ DOXYGEN_INPUT
+            \ DOXYGEN_INPUT_ENCODING
+            \ DOXYGEN_INPUT_FILTER
+            \ DOXYGEN_INTERACTIVE_SVG
+            \ DOXYGEN_INTERNAL_DOCS
+            \ DOXYGEN_JAVADOC_AUTOBRIEF
+            \ DOXYGEN_JAVADOC_BANNER
+            \ DOXYGEN_LATEX_BATCHMODE
+            \ DOXYGEN_LATEX_BIB_STYLE
+            \ DOXYGEN_LATEX_CMD_NAME
+            \ DOXYGEN_LATEX_EMOJI_DIRECTORY
+            \ DOXYGEN_LATEX_EXTRA_FILES
+            \ DOXYGEN_LATEX_EXTRA_STYLESHEET
+            \ DOXYGEN_LATEX_FOOTER
+            \ DOXYGEN_LATEX_HEADER
+            \ DOXYGEN_LATEX_HIDE_INDICES
+            \ DOXYGEN_LATEX_MAKEINDEX_CMD
+            \ DOXYGEN_LATEX_OUTPUT
+            \ DOXYGEN_LATEX_SOURCE_CODE
+            \ DOXYGEN_LATEX_TIMESTAMP
+            \ DOXYGEN_LAYOUT_FILE
+            \ DOXYGEN_LOOKUP_CACHE_SIZE
+            \ DOXYGEN_MACRO_EXPANSION
+            \ DOXYGEN_MAKEINDEX_CMD_NAME
+            \ DOXYGEN_MAN_EXTENSION
+            \ DOXYGEN_MAN_LINKS
+            \ DOXYGEN_MAN_OUTPUT
+            \ DOXYGEN_MAN_SUBDIR
+            \ DOXYGEN_MARKDOWN_SUPPORT
+            \ DOXYGEN_MATHJAX_CODEFILE
+            \ DOXYGEN_MATHJAX_EXTENSIONS
+            \ DOXYGEN_MATHJAX_FORMAT
+            \ DOXYGEN_MATHJAX_RELPATH
+            \ DOXYGEN_MAX_DOT_GRAPH_DEPTH
+            \ DOXYGEN_MAX_INITIALIZER_LINES
+            \ DOXYGEN_MSCFILE_DIRS
+            \ DOXYGEN_MULTILINE_CPP_IS_BRIEF
+            \ DOXYGEN_OPTIMIZE_FOR_FORTRAN
+            \ DOXYGEN_OPTIMIZE_OUTPUT_FOR_C
+            \ DOXYGEN_OPTIMIZE_OUTPUT_JAVA
+            \ DOXYGEN_OPTIMIZE_OUTPUT_SLICE
+            \ DOXYGEN_OPTIMIZE_OUTPUT_VHDL
+            \ DOXYGEN_OUTPUT_DIRECTORY
+            \ DOXYGEN_OUTPUT_LANGUAGE
+            \ DOXYGEN_OUTPUT_TEXT_DIRECTION
+            \ DOXYGEN_PAPER_TYPE
+            \ DOXYGEN_PDF_HYPERLINKS
+            \ DOXYGEN_PERLMOD_LATEX
+            \ DOXYGEN_PERLMOD_MAKEVAR_PREFIX
+            \ DOXYGEN_PERLMOD_PRETTY
+            \ DOXYGEN_PLANTUML_CFG_FILE
+            \ DOXYGEN_PLANTUML_INCLUDE_PATH
+            \ DOXYGEN_PLANTUML_JAR_PATH
+            \ DOXYGEN_PREDEFINED
+            \ DOXYGEN_PROJECT_BRIEF
+            \ DOXYGEN_PROJECT_LOGO
+            \ DOXYGEN_PROJECT_NAME
+            \ DOXYGEN_PROJECT_NUMBER
+            \ DOXYGEN_QCH_FILE
+            \ DOXYGEN_QHG_LOCATION
+            \ DOXYGEN_QHP_CUST_FILTER_ATTRS
+            \ DOXYGEN_QHP_CUST_FILTER_NAME
+            \ DOXYGEN_QHP_NAMESPACE
+            \ DOXYGEN_QHP_SECT_FILTER_ATTRS
+            \ DOXYGEN_QHP_VIRTUAL_FOLDER
+            \ DOXYGEN_QT_AUTOBRIEF
+            \ DOXYGEN_QUIET
+            \ DOXYGEN_RECURSIVE
+            \ DOXYGEN_REFERENCED_BY_RELATION
+            \ DOXYGEN_REFERENCES_LINK_SOURCE
+            \ DOXYGEN_REFERENCES_RELATION
+            \ DOXYGEN_REPEAT_BRIEF
+            \ DOXYGEN_RTF_EXTENSIONS_FILE
+            \ DOXYGEN_RTF_HYPERLINKS
+            \ DOXYGEN_RTF_OUTPUT
+            \ DOXYGEN_RTF_SOURCE_CODE
+            \ DOXYGEN_RTF_STYLESHEET_FILE
+            \ DOXYGEN_SEARCHDATA_FILE
+            \ DOXYGEN_SEARCHENGINE
+            \ DOXYGEN_SEARCHENGINE_URL
+            \ DOXYGEN_SEARCH_INCLUDES
+            \ DOXYGEN_SEPARATE_MEMBER_PAGES
+            \ DOXYGEN_SERVER_BASED_SEARCH
+            \ DOXYGEN_SHORT_NAMES
+            \ DOXYGEN_SHOW_FILES
+            \ DOXYGEN_SHOW_GROUPED_MEMB_INC
+            \ DOXYGEN_SHOW_INCLUDE_FILES
+            \ DOXYGEN_SHOW_NAMESPACES
+            \ DOXYGEN_SHOW_USED_FILES
+            \ DOXYGEN_SIP_SUPPORT
+            \ DOXYGEN_SKIP_FUNCTION_MACROS
+            \ DOXYGEN_SORT_BRIEF_DOCS
+            \ DOXYGEN_SORT_BY_SCOPE_NAME
+            \ DOXYGEN_SORT_GROUP_NAMES
+            \ DOXYGEN_SORT_MEMBERS_CTORS_1ST
+            \ DOXYGEN_SORT_MEMBER_DOCS
+            \ DOXYGEN_SOURCE_BROWSER
+            \ DOXYGEN_SOURCE_TOOLTIPS
+            \ DOXYGEN_STRICT_PROTO_MATCHING
+            \ DOXYGEN_STRIP_CODE_COMMENTS
+            \ DOXYGEN_STRIP_FROM_INC_PATH
+            \ DOXYGEN_STRIP_FROM_PATH
+            \ DOXYGEN_SUBGROUPING
+            \ DOXYGEN_TAB_SIZE
+            \ DOXYGEN_TAGFILES
+            \ DOXYGEN_TCL_SUBST
+            \ DOXYGEN_TEMPLATE_RELATIONS
+            \ DOXYGEN_TOC_EXPAND
+            \ DOXYGEN_TOC_INCLUDE_HEADINGS
+            \ DOXYGEN_TREEVIEW_WIDTH
+            \ DOXYGEN_TYPEDEF_HIDES_STRUCT
+            \ DOXYGEN_UML_LIMIT_NUM_FIELDS
+            \ DOXYGEN_UML_LOOK
+            \ DOXYGEN_USE_HTAGS
+            \ DOXYGEN_USE_MATHJAX
+            \ DOXYGEN_USE_MDFILE_AS_MAINPAGE
+            \ DOXYGEN_USE_PDFLATEX
+            \ DOXYGEN_VERBATIM_HEADERS
+            \ DOXYGEN_VERBATIM_VARS
+            \ DOXYGEN_VERSION
+            \ DOXYGEN_WARNINGS
+            \ DOXYGEN_WARN_AS_ERROR
+            \ DOXYGEN_WARN_FORMAT
+            \ DOXYGEN_WARN_IF_DOC_ERROR
+            \ DOXYGEN_WARN_IF_UNDOCUMENTED
+            \ DOXYGEN_WARN_LOGFILE
+            \ DOXYGEN_WARN_NO_PARAMDOC
+            \ DOXYGEN_XML_NS_MEMB_FILE_SCOPE
+            \ DOXYGEN_XML_OUTPUT
+            \ DOXYGEN_XML_PROGRAMLISTING
             \ ENV
             \ EXECUTABLE_OUTPUT_PATH
             \ GHS-MULTI
@@ -1541,9 +1940,11 @@
             \ BUILD_BYPRODUCTS
             \ BUILD_COMMAND
             \ BUILD_IN_SOURCE
+            \ CHECKOUT
             \ CMAKE_ARGS
             \ CMAKE_CACHE_ARGS
             \ CMAKE_CACHE_DEFAULT_ARGS
+            \ CMAKE_EP_GIT_REMOTE_UPDATE_STRATEGY
             \ CMAKE_TLS_CAINFO
             \ CMAKE_TLS_VERIFY
             \ COMMENT
@@ -1568,14 +1969,17 @@
             \ EP_STEP_TARGETS
             \ EP_UPDATE_DISCONNECTED
             \ EXCLUDE_FROM_ALL
+            \ FALSE
             \ FORCE
             \ GHS
             \ GIT_CONFIG
             \ GIT_PROGRESS
             \ GIT_REMOTE_NAME
+            \ GIT_REMOTE_UPDATE_STRATEGY
             \ GIT_REPOSITORY
             \ GIT_SHALLOW
             \ GIT_SUBMODULES
+            \ GIT_SUBMODULES_RECURSE
             \ GIT_TAG
             \ HG_REPOSITORY
             \ HG_TAG
@@ -1583,6 +1987,7 @@
             \ HTTP_PASSWORD
             \ HTTP_USERNAME
             \ IGNORED
+            \ INACTIVITY_TIMEOUT
             \ INDEPENDENT_STEP_TARGETS
             \ INSTALL_COMMAND
             \ INSTALL_DIR
@@ -1609,6 +2014,8 @@
             \ PATCH_COMMAND
             \ PREFIX
             \ PROPERTY
+            \ REBASE
+            \ REBASE_CHECKOUT
             \ REQUIRED
             \ SOURCE_DIR
             \ SOURCE_SUBDIR
@@ -1671,12 +2078,16 @@
             \ MAIN_DEPENDENCY
             \ NOT
             \ OUTPUT
+            \ PATH
             \ POST_BUILD
             \ PRE_BUILD
             \ PRE_LINK
             \ SYMBOLIC
             \ TARGET_FILE
+            \ TARGET_LINKER_FILE
+            \ TARGET_PDB_FILE
             \ TARGET_PROPERTY
+            \ TARGET_SONAME_FILE
             \ USES_TERMINAL
             \ VERBATIM
             \ WORKING_DIRECTORY
@@ -1695,8 +2106,13 @@
             \ JOB_POOL
             \ JOB_POOLS
             \ JOIN
+            \ PATH
             \ SOURCES
+            \ TARGET_FILE
+            \ TARGET_LINKER_FILE
+            \ TARGET_PDB_FILE
             \ TARGET_PROPERTY
+            \ TARGET_SONAME_FILE
             \ USES_TERMINAL
             \ VERBATIM
             \ WORKING_DIRECTORY
@@ -1710,6 +2126,7 @@
 
 syn keyword cmakeKWadd_executable contained
             \ ALIAS
+            \ ALIAS_GLOBAL
             \ CONFIG
             \ EXCLUDE_FROM_ALL
             \ GLOBAL
@@ -1725,6 +2142,7 @@
 
 syn keyword cmakeKWadd_library contained
             \ ALIAS
+            \ ALIAS_GLOBAL
             \ ARCHIVE_OUTPUT_DIRECTORY
             \ CLI
             \ CONFIG
@@ -1735,11 +2153,15 @@
             \ HEADER_FILE_ONLY
             \ IMPORTED
             \ IMPORTED_
+            \ IMPORTED_IMPLIB
+            \ IMPORTED_IMPLIB_
             \ IMPORTED_LOCATION
             \ IMPORTED_LOCATION_
             \ IMPORTED_OBJECTS
             \ IMPORTED_OBJECTS_
+            \ INTERFACE
             \ INTERFACE_
+            \ INTERFACE_SOURCES
             \ LIBRARY_OUTPUT_DIRECTORY
             \ MODULE
             \ OBJECT
@@ -1749,17 +2171,23 @@
             \ POST_BUILD
             \ PRE_BUILD
             \ PRE_LINK
-            \ PUBLIC_HEADER
+            \ PRIVATE
+            \ PUBLIC
             \ RUNTIME_OUTPUT_DIRECTORY
             \ SHARED
+            \ SOURCES
             \ STATIC
             \ TARGET_OBJECTS
             \ UNKNOWN
 
 syn keyword cmakeKWadd_link_options contained
             \ CMAKE_
+            \ CUDA_RESOLVE_DEVICE_SYMBOLS
+            \ CUDA_SEPARABLE_COMPILATION
+            \ DEVICE_LINK
             \ GCC
             \ GNU
+            \ HOST_LINK
             \ LANG
             \ LINKER
             \ LINK_OPTIONS
@@ -1775,6 +2203,7 @@
 syn keyword cmakeKWadd_test contained
             \ BUILD_TESTING
             \ COMMAND
+            \ COMMAND_EXPAND_LISTS
             \ CONFIGURATIONS
             \ FAIL_REGULAR_EXPRESSION
             \ NAME
@@ -1816,6 +2245,23 @@
             \ TOTAL_PHYSICAL_MEMORY
             \ TOTAL_VIRTUAL_MEMORY
 
+syn keyword cmakeKWcmake_language contained
+            \ AND
+            \ CALL
+            \ CANCEL_CALL
+            \ CODE
+            \ DEFER
+            \ DIRECTORY
+            \ EVAL
+            \ FALSE
+            \ GET_CALL_IDS
+            \ ID
+            \ ID_VAR
+            \ OR
+            \ STATUS
+            \ TRUE
+            \ WRITE
+
 syn keyword cmakeKWcmake_minimum_required contained
             \ FATAL_ERROR
             \ VERSION
@@ -1845,6 +2291,72 @@
             \ _KEYWORDS_MISSING_VALUES
             \ _UNPARSED_ARGUMENTS
 
+syn keyword cmakeKWcmake_path contained
+            \ ABSOLUTE_PATH
+            \ AND
+            \ APPEND
+            \ BASE_DIRECTORY
+            \ CMAKE_PATH
+            \ COMPARE
+            \ CONCAT
+            \ CONVERT
+            \ ELSEIF
+            \ ENDIF
+            \ EXTENSION
+            \ EXTENSION_DEF
+            \ FALSE
+            \ FILENAME_DEF
+            \ GET
+            \ GET_EXTENSION
+            \ GET_FILENAME
+            \ GET_PARENT_PATH
+            \ GET_RELATIVE_PATH
+            \ GET_ROOT_DIRECTORY
+            \ GET_ROOT_NAME
+            \ GET_ROOT_PATH
+            \ GET_STEM
+            \ HASH
+            \ HAS_EXTENSION
+            \ HAS_FILENAME
+            \ HAS_PARENT_PATH
+            \ HAS_RELATIVE_PATH
+            \ HAS_ROOT_DIRECTORY
+            \ HAS_ROOT_NAME
+            \ HAS_ROOT_PATH
+            \ HAS_STEM
+            \ IF
+            \ IS_ABSOLUTE
+            \ IS_PREFIX
+            \ IS_RELATIVE
+            \ LAST_ONLY
+            \ MATCHES
+            \ NATIVE_PATH
+            \ NORMALIZE
+            \ NORMAL_PATH
+            \ NOT
+            \ NOT_EQUAL
+            \ OP
+            \ OS
+            \ OUTPUT_VARIABLE
+            \ PARENT_PATH
+            \ PROXIMATE_PATH
+            \ REAL_PATH
+            \ RELATIVE_PATH
+            \ REMOVE_EXTENSION
+            \ REMOVE_FILENAME
+            \ REPLACE_EXTENSION
+            \ REPLACE_FILENAME
+            \ RETURN
+            \ ROOT_DIRECTORY
+            \ ROOT_NAME
+            \ ROOT_PATH
+            \ STEM
+            \ STREQUAL
+            \ TO_CMAKE_PATH_LIST
+            \ TO_NATIVE_PATH_LIST
+            \ TRUE
+            \ XOR
+
 syn keyword cmakeKWcmake_policy contained
             \ CMAKE_POLICY_DEFAULT_CMP
             \ CMP
@@ -1862,10 +2374,13 @@
             \ CRLF
             \ DOS
             \ ESCAPE_QUOTES
+            \ FILE_PERMISSIONS
             \ FOO_ENABLE
             \ FOO_STRING
             \ LF
             \ NEWLINE_STYLE
+            \ NO_SOURCE_PERMISSIONS
+            \ USE_SOURCE_PERMISSIONS
             \ VAR
 
 syn keyword cmakeKWcreate_test_sourcelist contained
@@ -1935,6 +2450,7 @@
 
 syn keyword cmakeKWctest_start contained
             \ APPEND
+            \ GROUP
             \ QUIET
             \ TAG
             \ TRACK
@@ -1957,6 +2473,7 @@
             \ SUBMIT_URL
 
 syn keyword cmakeKWctest_test contained
+            \ AFTER_TIMEOUT
             \ APPEND
             \ BUILD
             \ CAPTURE_CMAKE_ERROR
@@ -1972,12 +2489,17 @@
             \ ON
             \ PARALLEL_LEVEL
             \ QUIET
+            \ REPEAT
+            \ RESOURCE_SPEC_FILE
             \ RETURN_VALUE
             \ SCHEDULE_RANDOM
             \ START
+            \ STOP_ON_FAILURE
             \ STOP_TIME
             \ STRIDE
             \ TEST_LOAD
+            \ UNTIL_FAIL
+            \ UNTIL_PASS
 
 syn keyword cmakeKWctest_update contained
             \ CAPTURE_CMAKE_ERROR
@@ -2005,9 +2527,18 @@
             \ TEST
             \ VARIABLE
 
+syn keyword cmakeKWdoxygen_add_docs contained
+            \ ALL
+            \ COMMENT
+            \ USE_STAMP_FILE
+            \ WORKING_DIRECTORY
+
 syn keyword cmakeKWenable_language contained
             \ ASM
             \ CUDA
+            \ ISPC
+            \ OBJC
+            \ OBJCXX
             \ OPTIONAL
 
 syn keyword cmakeKWenable_testing contained
@@ -2020,15 +2551,20 @@
 
 syn keyword cmakeKWexecute_process contained
             \ ANSI
+            \ ANY
             \ AUTO
             \ COMMAND
             \ COMMAND_ECHO
+            \ COMMAND_ERROR_IS_FATAL
+            \ ECHO_ERROR_VARIABLE
+            \ ECHO_OUTPUT_VARIABLE
             \ ENCODING
             \ ERROR_FILE
             \ ERROR_QUIET
             \ ERROR_STRIP_TRAILING_WHITESPACE
             \ ERROR_VARIABLE
             \ INPUT_FILE
+            \ LAST
             \ NONE
             \ OEM
             \ OUTPUT_FILE
@@ -2070,63 +2606,107 @@
 syn keyword cmakeKWfile contained
             \ ALGO
             \ APPEND
+            \ ARCHIVE_CREATE
+            \ ARCHIVE_EXTRACT
             \ ASCII
+            \ BASE_DIRECTORY
+            \ BUNDLE_EXECUTABLE
+            \ CHMOD
+            \ CHMOD_RECURSE
+            \ CMAKE_GET_RUNTIME_DEPENDENCIES_COMMAND
+            \ CMAKE_GET_RUNTIME_DEPENDENCIES_PLATFORM
+            \ CMAKE_GET_RUNTIME_DEPENDENCIES_TOOL
+            \ CMAKE_OBJDUMP
             \ CMAKE_TLS_CAINFO
             \ CMAKE_TLS_VERIFY
+            \ CODE
+            \ COMPILE_FEATURES
+            \ COMPRESSION
+            \ COMPRESSION_LEVEL
             \ CONDITION
-            \ CONFIG
+            \ CONFIGURE
             \ CONFIGURE_DEPENDS
+            \ CONFLICTING_DEPENDENCIES_PREFIX
             \ CONTENT
+            \ CONVERT
             \ COPY
             \ COPY_ON_ERROR
             \ CREATE_LINK
+            \ CRLF
             \ DESTINATION
+            \ DIRECTORIES
             \ DIRECTORY_PERMISSIONS
+            \ DLL
+            \ DOS
             \ DOWNLOAD
             \ ENCODING
-            \ EXCLUDE
+            \ ESCAPE_QUOTES
+            \ EXECUTABLES
             \ EXPECTED_HASH
             \ FILES_MATCHING
             \ FILE_PERMISSIONS
             \ FOLLOW_SYMLINKS
             \ FOLLOW_SYMLINK_CHAIN
+            \ FORMAT
             \ FUNCTION
             \ GENERATE
+            \ GET_RUNTIME_DEPENDENCIES
             \ GLOB
             \ GLOB_RECURSE
+            \ GROUP_EXECUTE
+            \ GROUP_READ
+            \ GROUP_WRITE
             \ GUARD
             \ HASH
             \ HEX
             \ HTTPHEADER
             \ IGNORED
             \ INACTIVITY_TIMEOUT
+            \ INPUT
             \ INSTALL
             \ IS_ABSOLUTE
             \ LENGTH_MAXIMUM
             \ LENGTH_MINIMUM
             \ LF
+            \ LIBRARIES
             \ LIMIT
             \ LIMIT_COUNT
             \ LIMIT_INPUT
             \ LIMIT_OUTPUT
             \ LIST_DIRECTORIES
+            \ LIST_ONLY
             \ LOCK
             \ LOG
             \ MAKE_DIRECTORY
+            \ MODULES
+            \ MTIME
+            \ MYLIBRARY
             \ NETRC
             \ NETRC_FILE
             \ NEWLINE_CONSUME
+            \ NEWLINE_STYLE
             \ NOT
             \ NO_HEX_CONVERSION
             \ NO_SOURCE_PERMISSIONS
             \ OFFSET
-            \ OLD
+            \ ONLY
             \ OPTIONAL
             \ OUTPUT
+            \ OWNER_EXECUTE
+            \ OWNER_READ
+            \ OWNER_WRITE
+            \ PATHS
             \ PATTERN
+            \ PATTERNS
+            \ PERMISSIONS
+            \ POST_EXCLUDE_REGEXES
+            \ POST_INCLUDE_REGEXES
+            \ PRE_EXCLUDE_REGEXES
+            \ PRE_INCLUDE_REGEXES
             \ PROCESS
             \ READ
             \ READ_SYMLINK
+            \ REAL_PATH
             \ REGEX
             \ RELATIVE_PATH
             \ RELEASE
@@ -2134,33 +2714,51 @@
             \ REMOVE_RECURSE
             \ RENAME
             \ REQUIRED
+            \ RESOLVED_DEPENDENCIES_VAR
             \ RESULT
             \ RESULT_VARIABLE
+            \ RPATH
+            \ RUNPATH
+            \ SCRIPT
+            \ SHARED
             \ SHOW_PROGRESS
             \ SIZE
             \ SSL
+            \ STATIC
             \ STATUS
             \ STRINGS
             \ SYMBOLIC
+            \ TARGET
+            \ TARGET_PROPERTY
             \ TIMESTAMP
             \ TLS_CAINFO
             \ TLS_VERIFY
             \ TOUCH
             \ TOUCH_NOCREATE
             \ TO_CMAKE_PATH
+            \ TO_CMAKE_PATH_LIST
             \ TO_NATIVE_PATH
+            \ TO_NATIVE_PATH_LIST
+            \ UNRESOLVED_DEPENDENCIES_VAR
             \ UPLOAD
             \ URL
             \ USERPWD
             \ USE_SOURCE_PERMISSIONS
             \ UTC
             \ UTF
+            \ VERBOSE
+            \ WORLD_EXECUTE
+            \ WORLD_READ
+            \ WORLD_WRITE
             \ WRITE
+            \ XZ
+            \ _FILENAMES
 
 syn keyword cmakeKWfind_file contained
             \ CMAKE_FIND_ROOT_PATH_BOTH
             \ DOC
             \ DVAR
+            \ FALSE
             \ HINTS
             \ INCLUDE
             \ NAMES
@@ -2174,14 +2772,16 @@
             \ ONLY_CMAKE_FIND_ROOT_PATH
             \ PATHS
             \ PATH_SUFFIXES
+            \ REQUIRED
             \ VAR
 
 syn keyword cmakeKWfind_library contained
             \ CMAKE_FIND_ROOT_PATH_BOTH
             \ DOC
             \ DVAR
+            \ FALSE
             \ HINTS
-            \ LIB
+            \ INCLUDE
             \ NAMES
             \ NAMES_PER_DIR
             \ NO_CMAKE_ENVIRONMENT_PATH
@@ -2194,6 +2794,7 @@
             \ ONLY_CMAKE_FIND_ROOT_PATH
             \ PATHS
             \ PATH_SUFFIXES
+            \ REQUIRED
             \ VAR
 
 syn keyword cmakeKWfind_package contained
@@ -2207,8 +2808,12 @@
             \ DEC
             \ DVAR
             \ EXACT
+            \ EXCLUDE
+            \ FALSE
+            \ FIND_PACKAGE_VERSION_FORMAT
             \ FRAMEWORK
             \ HINTS
+            \ INCLUDE
             \ MODULE
             \ NAMES
             \ NATURAL
@@ -2228,12 +2833,26 @@
             \ OPTIONAL_COMPONENTS
             \ PACKAGE_FIND_NAME
             \ PACKAGE_FIND_VERSION
+            \ PACKAGE_FIND_VERSION_COMPLETE
             \ PACKAGE_FIND_VERSION_COUNT
             \ PACKAGE_FIND_VERSION_MAJOR
+            \ PACKAGE_FIND_VERSION_MAX
+            \ PACKAGE_FIND_VERSION_MAX_COUNT
+            \ PACKAGE_FIND_VERSION_MAX_MAJOR
+            \ PACKAGE_FIND_VERSION_MAX_MINOR
+            \ PACKAGE_FIND_VERSION_MAX_PATCH
+            \ PACKAGE_FIND_VERSION_MAX_TWEAK
             \ PACKAGE_FIND_VERSION_MINOR
+            \ PACKAGE_FIND_VERSION_MIN_COUNT
+            \ PACKAGE_FIND_VERSION_MIN_MAJOR
+            \ PACKAGE_FIND_VERSION_MIN_MINOR
+            \ PACKAGE_FIND_VERSION_MIN_PATCH
+            \ PACKAGE_FIND_VERSION_MIN_TWEAK
             \ PACKAGE_FIND_VERSION_PATCH
+            \ PACKAGE_FIND_VERSION_RANGE
+            \ PACKAGE_FIND_VERSION_RANGE_MAX
+            \ PACKAGE_FIND_VERSION_RANGE_MIN
             \ PACKAGE_FIND_VERSION_TWEAK
-            \ PACKAGE_VERSION
             \ PACKAGE_VERSION_COMPATIBLE
             \ PACKAGE_VERSION_EXACT
             \ PACKAGE_VERSION_UNSUITABLE
@@ -2258,6 +2877,7 @@
             \ CMAKE_FIND_ROOT_PATH_BOTH
             \ DOC
             \ DVAR
+            \ FALSE
             \ HINTS
             \ INCLUDE
             \ NAMES
@@ -2271,12 +2891,14 @@
             \ ONLY_CMAKE_FIND_ROOT_PATH
             \ PATHS
             \ PATH_SUFFIXES
+            \ REQUIRED
             \ VAR
 
 syn keyword cmakeKWfind_program contained
             \ CMAKE_FIND_ROOT_PATH_BOTH
             \ DOC
             \ DVAR
+            \ FALSE
             \ HINTS
             \ NAMES
             \ NAMES_PER_DIR
@@ -2290,22 +2912,26 @@
             \ ONLY_CMAKE_FIND_ROOT_PATH
             \ PATHS
             \ PATH_SUFFIXES
+            \ REQUIRED
             \ VAR
 
 syn keyword cmakeKWfltk_wrap_ui contained
             \ FLTK
 
 syn keyword cmakeKWforeach contained
+            \ APPEND
             \ IN
             \ ITEMS
             \ LISTS
             \ RANGE
             \ STATUS
+            \ ZIP_LISTS
 
 syn keyword cmakeKWfunction contained
             \ ARGC
             \ ARGN
             \ ARGV
+            \ CALL
             \ FOO
             \ PARENT_SCOPE
 
@@ -2333,6 +2959,7 @@
             \ PROGRAM
             \ PROGRAM_ARGS
             \ REALPATH
+            \ REAL_PATH
 
 syn keyword cmakeKWget_property contained
             \ BRIEF_DOCS
@@ -2345,13 +2972,15 @@
             \ SET
             \ SOURCE
             \ TARGET
+            \ TARGET_DIRECTORY
             \ TEST
             \ VARIABLE
 
 syn keyword cmakeKWget_source_file_property contained
+            \ DIRECTORY
             \ INHERITED
             \ LOCATION
-            \ VAR
+            \ TARGET_DIRECTORY
 
 syn keyword cmakeKWget_target_property contained
             \ INHERITED
@@ -2427,6 +3056,7 @@
 
 syn keyword cmakeKWinstall contained
             \ AFTER
+            \ AIX
             \ APT
             \ ARCHIVE
             \ BEFORE
@@ -2460,6 +3090,7 @@
             \ DIRECTORY_PERMISSIONS
             \ DLL
             \ DOC
+            \ ENABLE_EXPORTS
             \ EXCLUDE_FROM_ALL
             \ EXPORT
             \ EXPORT_ANDROID_MK
@@ -2565,6 +3196,7 @@
             \ INTERNAL
             \ JOIN
             \ LENGTH
+            \ NATURAL
             \ ORDER
             \ OUTPUT_VARIABLE
             \ PARENT_SCOPE
@@ -2600,6 +3232,7 @@
             \ ARGC
             \ ARGN
             \ ARGV
+            \ CALL
             \ DEFINED
             \ FOO
             \ GREATER
@@ -2616,12 +3249,18 @@
             \ OUTPUT_FORMAT
 
 syn keyword cmakeKWmessage contained
+            \ APPEND
             \ AUTHOR_WARNING
+            \ CHECK_
+            \ CHECK_FAIL
+            \ CHECK_PASS
+            \ CHECK_START
             \ DEBUG
             \ DEPRECATION
             \ FATAL_ERROR
             \ GUI
             \ NOTICE
+            \ POP_BACK
             \ SEND_ERROR
             \ STATUS
             \ TRACE
@@ -2638,15 +3277,18 @@
             \ CUDA
             \ DESCRIPTION
             \ HOMEPAGE_URL
+            \ ISPC
             \ LANGUAGES
             \ NAME
             \ NONE
+            \ OBJC
+            \ OBJCXX
             \ PROJECT
             \ VERSION
             \ _BINARY_DIR
             \ _DESCRIPTION
             \ _HOMEPAGE_URL
-            \ _INCLUDE
+            \ _INCLUDE_BEFORE
             \ _SOURCE_DIR
             \ _VERSION
             \ _VERSION_MAJOR
@@ -2664,9 +3306,14 @@
             \ VALUE
             \ VAR
 
+syn keyword cmakeKWreturn contained
+            \ DEFER
+
 syn keyword cmakeKWseparate_arguments contained
             \ MSDN
             \ NATIVE_COMMAND
+            \ PROGRAM
+            \ SEPARATE_ARGS
             \ UNIX_COMMAND
             \ WINDOWS_COMMAND
 
@@ -2695,12 +3342,15 @@
             \ PROPERTY
             \ SOURCE
             \ TARGET
+            \ TARGET_DIRECTORY
             \ TEST
             \ WIX
 
 syn keyword cmakeKWset_source_files_properties contained
+            \ DIRECTORY
             \ PROPERTIES
             \ SOURCE
+            \ TARGET_DIRECTORY
 
 syn keyword cmakeKWset_target_properties contained
             \ PROPERTIES
@@ -2710,6 +3360,9 @@
             \ PROPERTIES
             \ TEST
 
+syn keyword cmakeKWsite_name contained
+            \ HOSTNAME
+
 syn keyword cmakeKWsource_group contained
             \ FILES
             \ PREFIX
@@ -2719,20 +3372,27 @@
 syn keyword cmakeKWstring contained
             \ ALPHABET
             \ APPEND
+            \ ARRAY
             \ ASCII
+            \ BOOLEAN
             \ CMAKE_MATCH_
             \ COMPARE
             \ CONCAT
             \ CONFIGURE
             \ EQUAL
+            \ ERROR_VARIABLE
             \ ESCAPE_QUOTES
             \ FIND
             \ GENEX_STRIP
+            \ GET
             \ GREATER
             \ GREATER_EQUAL
             \ GUID
             \ HASH
+            \ HEX
             \ JOIN
+            \ JSON
+            \ JSONLENGTH
             \ LENGTH
             \ LESS
             \ LESS_EQUAL
@@ -2740,17 +3400,24 @@
             \ MATCH
             \ MATCHALL
             \ MATCHES
+            \ MEMBER
             \ NAMESPACE
             \ NOTEQUAL
+            \ NULL
+            \ NUMBER
+            \ OBJECT
+            \ OFF
             \ ONLY
             \ PREPEND
             \ RANDOM
             \ RANDOM_SEED
             \ REGEX
+            \ REMOVE
             \ REPEAT
             \ REPLACE
             \ REVERSE
             \ RFC
+            \ SET
             \ SHA
             \ SOURCE_DATE_EPOCH
             \ STRIP
@@ -2853,8 +3520,12 @@
             \ ALIAS
             \ BEFORE
             \ CMAKE_
+            \ CUDA_RESOLVE_DEVICE_SYMBOLS
+            \ CUDA_SEPARABLE_COMPILATION
+            \ DEVICE_LINK
             \ GCC
             \ GNU
+            \ HOST_LINK
             \ IMPORTED
             \ INTERFACE
             \ INTERFACE_LINK_OPTIONS
@@ -2870,9 +3541,23 @@
             \ _LINKER_WRAPPER_FLAG_SEP
 
 syn keyword cmakeKWtarget_precompile_headers contained
+            \ ALIAS
+            \ ANGLE
+            \ BUILD_INTERFACE
+            \ COMPILE_LANGUAGE
+            \ DISABLE_PRECOMPILE_HEADERS
+            \ EXPORT
+            \ FI
+            \ GCC
+            \ IMPORTED
             \ INTERFACE
+            \ INTERFACE_PRECOMPILE_HEADERS
+            \ PRECOMPILE_HEADERS
+            \ PRECOMPILE_HEADERS_REUSE_FROM
             \ PRIVATE
             \ PUBLIC
+            \ REUSE_FROM
+            \ SKIP_PRECOMPILE_HEADERS
 
 syn keyword cmakeKWtarget_sources contained
             \ ALIAS
@@ -2911,6 +3596,12 @@
             \ LINK_OPTIONS
             \ MULTI
             \ NOT
+            \ OBJCXX_EXTENSIONS
+            \ OBJCXX_STANDARD
+            \ OBJCXX_STANDARD_REQUIRED
+            \ OBJC_EXTENSIONS
+            \ OBJC_STANDARD
+            \ OBJC_STANDARD_REQUIRED
             \ OUTPUT_VARIABLE
             \ PRIVATE
             \ SOURCES
@@ -2956,7 +3647,14 @@
             \ TEST_VARIABLE
 
 syn keyword cmakeKWvariable_watch contained
+            \ APPEND
             \ COMMAND
+            \ DEFINED
+            \ MODIFIED_ACCESS
+            \ READ_ACCESS
+            \ REMOVED_ACCESS
+            \ UNKNOWN_MODIFIED_ACCESS
+            \ UNKNOWN_READ_ACCESS
 
 syn keyword cmakeKWwrite_file contained
             \ APPEND
@@ -2988,39 +3686,49 @@
             \ CONFIGURATION
             \ CUDA_COMPILER_ID
             \ CUDA_COMPILER_VERSION
+            \ CUDA_RESOLVE_DEVICE_SYMBOLS
+            \ CUDA_SEPARABLE_COMPILATION
             \ CUSTOM_KEYS
             \ CXX_COMPILER_ID
             \ CXX_COMPILER_VERSION
+            \ CXX_CONFIG
             \ CXX_STANDARD
             \ C_COMPILER_ID
             \ C_COMPILER_VERSION
             \ C_STANDARD
             \ DEBUG_MODE
             \ DEBUG_POSTFIX
+            \ DEVICE_LINK
+            \ DLL
             \ EXCLUDE
             \ EXPORT
             \ FALSE
             \ FILTER
             \ FOO_EXTRA_THINGS
-            \ Fortran_COMPILER_ID
-            \ Fortran_COMPILER_VERSION
             \ GENERATE
             \ GENEX_EVAL
             \ GNU
+            \ HOST_LINK
             \ IF
             \ IGNORE
             \ IMPORT_PREFIX
             \ IMPORT_SUFFIX
             \ INCLUDE_DIRECTORIES
             \ INSTALL_INTERFACE
+            \ INSTALL_NAME_DIR
             \ INSTALL_PREFIX
+            \ INTERFACE
             \ INTERFACE_LINK_LIBRARIES
             \ IN_LIST
+            \ ISPC_COMPILER_ID
+            \ ISPC_COMPILER_VERSION
             \ JOIN
             \ LANG
             \ LANG_COMPILER_ID
             \ LIBRARY_OUTPUT_NAME
             \ LIBRARY_OUTPUT_NAME_
+            \ LINK_LANGUAGE
+            \ LINK_LANG_AND_ID
             \ LINK_LIBRARIES
             \ LINK_ONLY
             \ LOWER_CASE
@@ -3028,6 +3736,10 @@
             \ MAP_IMPORTED_CONFIG_
             \ NO
             \ NOT
+            \ OBJCXX_COMPILER_ID
+            \ OBJCXX_COMPILER_VERSION
+            \ OBJC_COMPILER_ID
+            \ OBJC_COMPILER_VERSION
             \ OFF
             \ OLD_COMPILER
             \ OUTPUT_NAME
@@ -3046,6 +3758,7 @@
             \ SDK
             \ SEMICOLON
             \ SHELL_PATH
+            \ STATIC
             \ STREQUAL
             \ TARGET_BUNDLE_CONTENT_DIR
             \ TARGET_BUNDLE_DIR
@@ -3100,8 +3813,10 @@
             \ break
             \ build_command
             \ cmake_host_system_information
+            \ cmake_language
             \ cmake_minimum_required
             \ cmake_parse_arguments
+            \ cmake_path
             \ cmake_policy
             \ configure_file
             \ continue
@@ -3258,8 +3973,10 @@
 hi def link cmakeKWadd_test ModeMsg
 hi def link cmakeKWbuild_command ModeMsg
 hi def link cmakeKWcmake_host_system_information 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_policy ModeMsg
 hi def link cmakeKWconfigure_file ModeMsg
 hi def link cmakeKWcreate_test_sourcelist ModeMsg
@@ -3274,6 +3991,7 @@
 hi def link cmakeKWctest_update ModeMsg
 hi def link cmakeKWctest_upload ModeMsg
 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
@@ -3318,6 +4036,7 @@
 hi def link cmakeKWqt_wrap_cpp ModeMsg
 hi def link cmakeKWqt_wrap_ui ModeMsg
 hi def link cmakeKWremove ModeMsg
+hi def link cmakeKWreturn ModeMsg
 hi def link cmakeKWseparate_arguments ModeMsg
 hi def link cmakeKWset ModeMsg
 hi def link cmakeKWset_directory_properties ModeMsg
@@ -3325,6 +4044,7 @@
 hi def link cmakeKWset_source_files_properties ModeMsg
 hi def link cmakeKWset_target_properties ModeMsg
 hi def link cmakeKWset_tests_properties ModeMsg
+hi def link cmakeKWsite_name ModeMsg
 hi def link cmakeKWsource_group ModeMsg
 hi def link cmakeKWstring ModeMsg
 hi def link cmakeKWsubdirs ModeMsg
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2d860d4..a2fcf2e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,7 +1,7 @@
 # Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
 # file Copyright.txt or https://cmake.org/licensing for details.
 
-cmake_minimum_required(VERSION 3.1...3.15 FATAL_ERROR)
+cmake_minimum_required(VERSION 3.1...3.18 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)
 project(CMake)
diff --git a/Help/command/DEVICE_LINK_OPTIONS.txt b/Help/command/DEVICE_LINK_OPTIONS.txt
index 3f0226f..1297cd0 100644
--- a/Help/command/DEVICE_LINK_OPTIONS.txt
+++ b/Help/command/DEVICE_LINK_OPTIONS.txt
@@ -1,11 +1,12 @@
 
-When a device link step is involved, which is controlled by
-:prop_tgt:`CUDA_SEPARABLE_COMPILATION` and
-:prop_tgt:`CUDA_RESOLVE_DEVICE_SYMBOLS` properties and policy :policy:`CMP0105`,
-the raw options will be delivered to the host and device link steps (wrapped in
-``-Xcompiler`` or equivalent for device link). Options wrapped with
-``$<DEVICE_LINK:...>``
-:manual:`generator expression <cmake-generator-expressions(7)>` will be used
-only for the device link step. Options wrapped with ``$<HOST_LINK:...>``
-:manual:`generator expression <cmake-generator-expressions(7)>` will be used
-only for the host link step.
+.. versionadded:: 3.18
+  When a device link step is involved, which is controlled by
+  :prop_tgt:`CUDA_SEPARABLE_COMPILATION` and
+  :prop_tgt:`CUDA_RESOLVE_DEVICE_SYMBOLS` properties and policy :policy:`CMP0105`,
+  the raw options will be delivered to the host and device link steps (wrapped in
+  ``-Xcompiler`` or equivalent for device link). Options wrapped with
+  ``$<DEVICE_LINK:...>``
+  :manual:`generator expression <cmake-generator-expressions(7)>` will be used
+  only for the device link step. Options wrapped with ``$<HOST_LINK:...>``
+  :manual:`generator expression <cmake-generator-expressions(7)>` will be used
+  only for the host link step.
diff --git a/Help/command/FIND_XXX.txt b/Help/command/FIND_XXX.txt
index 4a62c5b..97eecfc 100644
--- a/Help/command/FIND_XXX.txt
+++ b/Help/command/FIND_XXX.txt
@@ -33,9 +33,6 @@
 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``.
-The ``REQUIRED`` option stops processing with an error message if nothing
-is found, otherwise the search will be attempted again the
-next time |FIND_XXX| is invoked with the same variable.
 
 Options include:
 
@@ -60,7 +57,11 @@
   Specify the documentation string for the ``<VAR>`` cache entry.
 
 ``REQUIRED``
-  Stop processing with an error message if nothing is found.
+  .. versionadded:: 3.18
+
+  Stop processing with an error message if nothing is found, otherwise
+  the search will be attempted again the next time |FIND_XXX| is invoked
+  with the same variable.
 
 If ``NO_DEFAULT_PATH`` is specified, then no additional paths are
 added to the search.
@@ -84,20 +85,21 @@
    |prefix_XXX_SUBDIR| for each ``<prefix>`` in
    :variable:`CMAKE_SYSTEM_PREFIX_PATH`
 
-1. If called from within a find module or any other script loaded by a call to
-   :command:`find_package(<PackageName>)`, search prefixes unique to the
-   current package being found.  Specifically, look in the
-   :variable:`<PackageName>_ROOT` CMake variable and the
-   :envvar:`<PackageName>_ROOT` environment variable.
-   The package root variables are maintained as a stack, so if called from
-   nested find modules or config packages, root paths from the parent's find
-   module or config package will be searched after paths from the current
-   module or package.  In other words, the search order would be
-   ``<CurrentPackage>_ROOT``, ``ENV{<CurrentPackage>_ROOT}``,
-   ``<ParentPackage>_ROOT``, ``ENV{<ParentPackage>_ROOT}``, etc.
-   This can be skipped if ``NO_PACKAGE_ROOT_PATH`` is passed or by setting
-   the :variable:`CMAKE_FIND_USE_PACKAGE_ROOT_PATH` to ``FALSE``.
-   See policy :policy:`CMP0074`.
+1. .. versionadded:: 3.12
+    If called from within a find module or any other script loaded by a call to
+    :command:`find_package(<PackageName>)`, search prefixes unique to the
+    current package being found.  Specifically, look in the
+    :variable:`<PackageName>_ROOT` CMake variable and the
+    :envvar:`<PackageName>_ROOT` environment variable.
+    The package root variables are maintained as a stack, so if called from
+    nested find modules or config packages, root paths from the parent's find
+    module or config package will be searched after paths from the current
+    module or package.  In other words, the search order would be
+    ``<CurrentPackage>_ROOT``, ``ENV{<CurrentPackage>_ROOT}``,
+    ``<ParentPackage>_ROOT``, ``ENV{<ParentPackage>_ROOT}``, etc.
+    This can be skipped if ``NO_PACKAGE_ROOT_PATH`` is passed or by setting
+    the :variable:`CMAKE_FIND_USE_PACKAGE_ROOT_PATH` to ``FALSE``.
+    See policy :policy:`CMP0074`.
 
    * |FIND_PACKAGE_ROOT_PREFIX_PATH_XXX|
 
@@ -151,6 +153,10 @@
    or in the short-hand version of the command.
    These are typically hard-coded guesses.
 
+.. versionadded:: 3.16
+  Added ``CMAKE_FIND_USE_<CATEGORY>_PATH`` variables to globally disable
+  various search locations.
+
 .. |FIND_ARGS_XXX| replace:: <VAR> NAMES name
 
 On macOS the :variable:`CMAKE_FIND_FRAMEWORK` and
diff --git a/Help/command/OPTIONS_SHELL.txt b/Help/command/OPTIONS_SHELL.txt
index 0f8ec32..4051ffe 100644
--- a/Help/command/OPTIONS_SHELL.txt
+++ b/Help/command/OPTIONS_SHELL.txt
@@ -1,9 +1,11 @@
 The final set of compile or link options used for a target is constructed by
 accumulating options from the current target and the usage requirements of
 its dependencies.  The set of options is de-duplicated to avoid repetition.
-While beneficial for individual options, the de-duplication step can break
-up option groups.  For example, ``-D A -D B`` becomes ``-D A B``.  One may
-specify a group of options using shell-like quoting along with a ``SHELL:``
-prefix.  The ``SHELL:`` prefix is dropped, and the rest of the option string
-is parsed using the :command:`separate_arguments` ``UNIX_COMMAND`` mode.
-For example, ``"SHELL:-D A" "SHELL:-D B"`` becomes ``-D A -D B``.
+
+.. versionadded:: 3.12
+  While beneficial for individual options, the de-duplication step can break
+  up option groups.  For example, ``-D A -D B`` becomes ``-D A B``.  One may
+  specify a group of options using shell-like quoting along with a ``SHELL:``
+  prefix.  The ``SHELL:`` prefix is dropped, and the rest of the option string
+  is parsed using the :command:`separate_arguments` ``UNIX_COMMAND`` mode.
+  For example, ``"SHELL:-D A" "SHELL:-D B"`` becomes ``-D A -D B``.
diff --git a/Help/command/add_custom_command.rst b/Help/command/add_custom_command.rst
index 231f9da..45e4e3e 100644
--- a/Help/command/add_custom_command.rst
+++ b/Help/command/add_custom_command.rst
@@ -51,6 +51,8 @@
   used in the future.
 
 ``BYPRODUCTS``
+  .. versionadded:: 3.2
+
   Specify the files the command is expected to produce but whose
   modification time may or may not be newer than the dependencies.
   If a byproduct name is a relative path it will be interpreted
@@ -88,10 +90,11 @@
 
   * The target is not being cross-compiled (i.e. the
     :variable:`CMAKE_CROSSCOMPILING` variable is not set to true).
-  * The target is being cross-compiled and an emulator is provided (i.e.
-    its :prop_tgt:`CROSSCOMPILING_EMULATOR` target property is set).
-    In this case, the contents of :prop_tgt:`CROSSCOMPILING_EMULATOR` will be
-    prepended to the command before the location of the target executable.
+  * .. versionadded:: 3.6
+      The target is being cross-compiled and an emulator is provided (i.e.
+      its :prop_tgt:`CROSSCOMPILING_EMULATOR` target property is set).
+      In this case, the contents of :prop_tgt:`CROSSCOMPILING_EMULATOR` will be
+      prepended to the command before the location of the target executable.
 
   If neither of the above conditions are met, it is assumed that the
   command name is a program to be found on the ``PATH`` at build time.
@@ -153,18 +156,23 @@
   If any dependency is an ``OUTPUT`` of another custom command in the same
   directory (``CMakeLists.txt`` file), CMake automatically brings the other
   custom command into the target in which this command is built.
-  A target-level dependency is added if any dependency is listed as
-  ``BYPRODUCTS`` of a target or any of its build events in the same
-  directory to ensure the byproducts will be available.
+
+  .. versionadded:: 3.16
+    A target-level dependency is added if any dependency is listed as
+    ``BYPRODUCTS`` of a target or any of its build events in the same
+    directory to ensure the byproducts will be available.
 
   If ``DEPENDS`` is not specified, the command will run whenever
   the ``OUTPUT`` is missing; if the command does not actually
   create the ``OUTPUT``, the rule will always run.
 
-  Arguments to ``DEPENDS`` may use
-  :manual:`generator expressions <cmake-generator-expressions(7)>`.
+  .. versionadded:: 3.1
+    Arguments to ``DEPENDS`` may use
+    :manual:`generator expressions <cmake-generator-expressions(7)>`.
 
 ``COMMAND_EXPAND_LISTS``
+  .. versionadded:: 3.8
+
   Lists in ``COMMAND`` arguments will be expanded, including those
   created with
   :manual:`generator expressions <cmake-generator-expressions(7)>`,
@@ -184,6 +192,8 @@
   only for Makefile generators and will be ignored by other generators.
 
 ``JOB_POOL``
+  .. versionadded:: 3.15
+
   Specify a :prop_gbl:`pool <JOB_POOLS>` for the :generator:`Ninja`
   generator. Incompatible with ``USES_TERMINAL``, which implies
   the ``console`` pool.
@@ -211,6 +221,8 @@
   source file property.
 
 ``USES_TERMINAL``
+  .. versionadded:: 3.2
+
   The command will be given direct access to the terminal if possible.
   With the :generator:`Ninja` generator, this places the command in
   the ``console`` :prop_gbl:`pool <JOB_POOLS>`.
@@ -230,15 +242,23 @@
   If it is a relative path it will be interpreted relative to the
   build tree directory corresponding to the current source directory.
 
-  Arguments to ``WORKING_DIRECTORY`` may use
-  :manual:`generator expressions <cmake-generator-expressions(7)>`.
+  .. versionadded:: 3.13
+    Arguments to ``WORKING_DIRECTORY`` may use
+    :manual:`generator expressions <cmake-generator-expressions(7)>`.
 
 ``DEPFILE``
+  .. versionadded:: 3.7
+
   Specify a ``.d`` depfile for the :generator:`Ninja` generator.
   A ``.d`` file holds dependencies usually emitted by the custom
   command itself.
   Using ``DEPFILE`` with other generators than Ninja is an error.
 
+  If the ``DEPFILE`` argument is relative, it should be relative to
+  :variable:`CMAKE_CURRENT_BINARY_DIR`, and any relative paths inside the
+  ``DEPFILE`` should also be relative to :variable:`CMAKE_CURRENT_BINARY_DIR`
+  (see policy :policy:`CMP0116`.)
+
 Build Events
 ^^^^^^^^^^^^
 
diff --git a/Help/command/add_custom_target.rst b/Help/command/add_custom_target.rst
index 2eb0c88..7c29dda 100644
--- a/Help/command/add_custom_target.rst
+++ b/Help/command/add_custom_target.rst
@@ -32,6 +32,8 @@
   called ``ALL``).
 
 ``BYPRODUCTS``
+  .. versionadded:: 3.2
+
   Specify the files the command is expected to produce but whose
   modification time may or may not be updated on subsequent builds.
   If a byproduct name is a relative path it will be interpreted
@@ -67,10 +69,11 @@
 
   * The target is not being cross-compiled (i.e. the
     :variable:`CMAKE_CROSSCOMPILING` variable is not set to true).
-  * The target is being cross-compiled and an emulator is provided (i.e.
-    its :prop_tgt:`CROSSCOMPILING_EMULATOR` target property is set).
-    In this case, the contents of :prop_tgt:`CROSSCOMPILING_EMULATOR` will be
-    prepended to the command before the location of the target executable.
+  * .. versionadded:: 3.6
+      The target is being cross-compiled and an emulator is provided (i.e.
+      its :prop_tgt:`CROSSCOMPILING_EMULATOR` target property is set).
+      In this case, the contents of :prop_tgt:`CROSSCOMPILING_EMULATOR` will be
+      prepended to the command before the location of the target executable.
 
   If neither of the above conditions are met, it is assumed that the
   command name is a program to be found on the ``PATH`` at build time.
@@ -103,14 +106,18 @@
   :command:`add_custom_command` command calls in the same directory
   (``CMakeLists.txt`` file).  They will be brought up to date when
   the target is built.
-  A target-level dependency is added if any dependency is a byproduct
-  of a target or any of its build events in the same directory to ensure
-  the byproducts will be available before this target is built.
+
+  .. versionchanged:: 3.16
+    A target-level dependency is added if any dependency is a byproduct
+    of a target or any of its build events in the same directory to ensure
+    the byproducts will be available before this target is built.
 
   Use the :command:`add_dependencies` command to add dependencies
   on other targets.
 
 ``COMMAND_EXPAND_LISTS``
+  .. versionadded:: 3.8
+
   Lists in ``COMMAND`` arguments will be expanded, including those
   created with
   :manual:`generator expressions <cmake-generator-expressions(7)>`,
@@ -119,6 +126,8 @@
   to be properly expanded.
 
 ``JOB_POOL``
+  .. versionadded:: 3.15
+
   Specify a :prop_gbl:`pool <JOB_POOLS>` for the :generator:`Ninja`
   generator. Incompatible with ``USES_TERMINAL``, which implies
   the ``console`` pool.
@@ -141,6 +150,8 @@
   tool-specific special characters.
 
 ``USES_TERMINAL``
+  .. versionadded:: 3.2
+
   The command will be given direct access to the terminal if possible.
   With the :generator:`Ninja` generator, this places the command in
   the ``console`` :prop_gbl:`pool <JOB_POOLS>`.
@@ -150,5 +161,6 @@
   If it is a relative path it will be interpreted relative to the
   build tree directory corresponding to the current source directory.
 
-  Arguments to ``WORKING_DIRECTORY`` may use
-  :manual:`generator expressions <cmake-generator-expressions(7)>`.
+  .. versionadded:: 3.13
+    Arguments to ``WORKING_DIRECTORY`` may use
+    :manual:`generator expressions <cmake-generator-expressions(7)>`.
diff --git a/Help/command/add_dependencies.rst b/Help/command/add_dependencies.rst
index de219a5..14c0183 100644
--- a/Help/command/add_dependencies.rst
+++ b/Help/command/add_dependencies.rst
@@ -17,6 +17,9 @@
 or an :ref:`interface library <Interface Libraries>` are followed
 transitively in its place since the target itself does not build.
 
+.. versionadded:: 3.3
+  Allow adding dependencies to interface libraries.
+
 See the ``DEPENDS`` option of :command:`add_custom_target` and
 :command:`add_custom_command` commands for adding file-level
 dependencies in custom rules.  See the :prop_sf:`OBJECT_DEPENDS`
diff --git a/Help/command/add_executable.rst b/Help/command/add_executable.rst
index e073228..dde9429 100644
--- a/Help/command/add_executable.rst
+++ b/Help/command/add_executable.rst
@@ -17,13 +17,21 @@
                  [source1] [source2 ...])
 
 Adds an executable target called ``<name>`` to be built from the source
-files listed in the command invocation.  (The source files can be omitted
-here if they are added later using :command:`target_sources`.)  The
+files listed in the command invocation.  The
 ``<name>`` corresponds to the logical target name and must be globally
 unique within a project.  The actual file name of the executable built is
 constructed based on conventions of the native platform (such as
 ``<name>.exe`` or just ``<name>``).
 
+.. versionadded:: 3.1
+  Source arguments to ``add_executable`` may use "generator expressions" with
+  the syntax ``$<...>``.  See the :manual:`cmake-generator-expressions(7)`
+  manual for available expressions.
+
+.. versionadded:: 3.11
+  The source files can be omitted if they are added later using
+  :command:`target_sources`.
+
 By default the executable file will be created in the build tree
 directory corresponding to the source tree directory in which the
 command was invoked.  See documentation of the
@@ -43,10 +51,8 @@
 the created target.  See documentation of the :prop_tgt:`EXCLUDE_FROM_ALL`
 target property for details.
 
-Source arguments to ``add_executable`` may use "generator expressions" with
-the syntax ``$<...>``.  See the :manual:`cmake-generator-expressions(7)`
-manual for available expressions.  See the :manual:`cmake-buildsystem(7)`
-manual for more on defining buildsystem properties.
+See the :manual:`cmake-buildsystem(7)` manual for more on defining
+buildsystem properties.
 
 See also :prop_sf:`HEADER_FILE_ONLY` on what to do if some sources are
 pre-processed, and you want to have the original sources reachable from
@@ -85,10 +91,14 @@
 does not appear in the generated buildsystem as a make target.  The
 ``<target>`` may not be an ``ALIAS``.
 
-An ``ALIAS`` to a non-``GLOBAL`` :ref:`Imported Target <Imported Targets>`
-has scope in the directory in which the alias is created and below.
-The :prop_tgt:`ALIAS_GLOBAL` target property can be used to check if the
-alias is global or not.
+.. versionadded:: 3.11
+  An ``ALIAS`` can target a ``GLOBAL`` :ref:`Imported Target <Imported Targets>`
+
+.. versionadded:: 3.18
+  An ``ALIAS`` can target a non-``GLOBAL`` Imported Target. Such alias is
+  scoped to the directory in which it is created and subdirectories.
+  The :prop_tgt:`ALIAS_GLOBAL` target property can be used to check if the
+  alias is global or not.
 
 ``ALIAS`` targets can be used as targets to read properties
 from, executables for custom commands and custom targets.  They can also be
diff --git a/Help/command/add_library.rst b/Help/command/add_library.rst
index b7dfabc..d3fbdcf 100644
--- a/Help/command/add_library.rst
+++ b/Help/command/add_library.rst
@@ -17,13 +17,21 @@
               [<source>...])
 
 Adds a library target called ``<name>`` to be built from the source files
-listed in the command invocation.  (The source files can be omitted here
-if they are added later using :command:`target_sources`.)  The ``<name>``
+listed in the command invocation.  The ``<name>``
 corresponds to the logical target name and must be globally unique within
 a project.  The actual file name of the library built is constructed based
 on conventions of the native platform (such as ``lib<name>.a`` or
 ``<name>.lib``).
 
+.. versionadded:: 3.1
+  Source arguments to ``add_library`` may use "generator expressions" with
+  the syntax ``$<...>``.  See the :manual:`cmake-generator-expressions(7)`
+  manual for available expressions.
+
+.. versionadded:: 3.11
+  The source files can be omitted if they are added later using
+  :command:`target_sources`.
+
 ``STATIC``, ``SHARED``, or ``MODULE`` may be given to specify the type of
 library to be created.  ``STATIC`` libraries are archives of object files
 for use when linking other targets.  ``SHARED`` libraries are linked
@@ -34,9 +42,13 @@
 variable :variable:`BUILD_SHARED_LIBS` is ``ON``.  For ``SHARED`` and
 ``MODULE`` libraries the :prop_tgt:`POSITION_INDEPENDENT_CODE` target
 property is set to ``ON`` automatically.
-A ``SHARED`` or ``STATIC`` library may be marked with the :prop_tgt:`FRAMEWORK`
+A ``SHARED`` library may be marked with the :prop_tgt:`FRAMEWORK`
 target property to create an macOS Framework.
 
+.. versionadded:: 3.8
+  A ``STATIC`` library may be marked with the :prop_tgt:`FRAMEWORK`
+  target property to create a static Framework.
+
 If a library does not export any symbols, it must not be declared as a
 ``SHARED`` library.  For example, a Windows resource DLL or a managed C++/CLI
 DLL that exports no unmanaged symbols would need to be a ``MODULE`` library.
@@ -55,10 +67,8 @@
 the created target.  See documentation of the :prop_tgt:`EXCLUDE_FROM_ALL`
 target property for details.
 
-Source arguments to ``add_library`` may use "generator expressions" with
-the syntax ``$<...>``.  See the :manual:`cmake-generator-expressions(7)`
-manual for available expressions.  See the :manual:`cmake-buildsystem(7)`
-manual for more on defining buildsystem properties.
+See the :manual:`cmake-buildsystem(7)` manual for more on defining
+buildsystem properties.
 
 See also :prop_sf:`HEADER_FILE_ONLY` on what to do if some sources are
 pre-processed, and you want to have the original sources reachable from
@@ -93,6 +103,9 @@
 consider adding at least one real source file to any target that references
 ``$<TARGET_OBJECTS:objlib>``.
 
+.. versionadded:: 3.12
+  Object libraries can be linked to with :command:`target_link_libraries`.
+
 Interface Libraries
 ^^^^^^^^^^^^^^^^^^^
 
@@ -121,23 +134,28 @@
 An interface library created with the above signature has no source files
 itself and is not included as a target in the generated buildsystem.
 
-Since CMake 3.19, an interface library target may be created with
-source files:
+.. versionadded:: 3.15
+  An interface library can have :prop_tgt:`PUBLIC_HEADER` and
+  :prop_tgt:`PRIVATE_HEADER` properties.  The headers specified by those
+  properties can be installed using the :command:`install(TARGETS)` command.
 
-.. code-block:: cmake
+.. versionadded:: 3.19
+  An interface library target may be created with source files:
 
-  add_library(<name> INTERFACE [<source>...] [EXCLUDE_FROM_ALL])
+  .. code-block:: cmake
 
-Source files may be listed directly in the ``add_library`` call or added
-later by calls to :command:`target_sources` with the ``PRIVATE`` or
-``PUBLIC`` keywords.
+    add_library(<name> INTERFACE [<source>...] [EXCLUDE_FROM_ALL])
 
-If an interface library has source files (i.e. the :prop_tgt:`SOURCES`
-target property is set), it will appear in the generated buildsystem
-as a build target much like a target defined by the
-:command:`add_custom_target` command.  It does not compile any sources,
-but does contain build rules for custom commands created by the
-:command:`add_custom_command` command.
+  Source files may be listed directly in the ``add_library`` call or added
+  later by calls to :command:`target_sources` with the ``PRIVATE`` or
+  ``PUBLIC`` keywords.
+
+  If an interface library has source files (i.e. the :prop_tgt:`SOURCES`
+  target property is set), it will appear in the generated buildsystem
+  as a build target much like a target defined by the
+  :command:`add_custom_target` command.  It does not compile any sources,
+  but does contain build rules for custom commands created by the
+  :command:`add_custom_command` command.
 
 .. note::
   In most command signatures where the ``INTERFACE`` keyword appears,
@@ -211,10 +229,14 @@
 not appear in the generated buildsystem as a make target.  The ``<target>``
 may not be an ``ALIAS``.
 
-An ``ALIAS`` to a non-``GLOBAL`` :ref:`Imported Target <Imported Targets>`
-has scope in the directory in which the alias is created and below.
-The :prop_tgt:`ALIAS_GLOBAL` target property can be used to check if the
-alias is global or not.
+.. versionadded:: 3.11
+  An ``ALIAS`` can target a ``GLOBAL`` :ref:`Imported Target <Imported Targets>`
+
+.. versionadded:: 3.18
+  An ``ALIAS`` can target a non-``GLOBAL`` Imported Target. Such alias is
+  scoped to the directory in which it is created and below.
+  The :prop_tgt:`ALIAS_GLOBAL` target property can be used to check if the
+  alias is global or not.
 
 ``ALIAS`` targets can be used as linkable targets and as targets to
 read properties from.  They can also be tested for existence with the
diff --git a/Help/command/add_test.rst b/Help/command/add_test.rst
index 2b4d082..832d8db 100644
--- a/Help/command/add_test.rst
+++ b/Help/command/add_test.rst
@@ -31,6 +31,8 @@
   current source directory.
 
 ``COMMAND_EXPAND_LISTS``
+  .. versionadded:: 3.16
+
   Lists in ``COMMAND`` arguments will be expanded, including those
   created with
   :manual:`generator expressions <cmake-generator-expressions(7)>`.
@@ -43,6 +45,9 @@
 :prop_test:`FAIL_REGULAR_EXPRESSION` or
 :prop_test:`SKIP_REGULAR_EXPRESSION` test property is used.
 
+.. versionadded:: 3.16
+  Added :prop_test:`SKIP_REGULAR_EXPRESSION` property.
+
 The ``COMMAND`` and ``WORKING_DIRECTORY`` options may use "generator
 expressions" with the syntax ``$<...>``.  See the
 :manual:`cmake-generator-expressions(7)` manual for available expressions.
diff --git a/Help/command/cmake_host_system_information.rst b/Help/command/cmake_host_system_information.rst
index 2e9563a..2b902a9 100644
--- a/Help/command/cmake_host_system_information.rst
+++ b/Help/command/cmake_host_system_information.rst
@@ -24,6 +24,14 @@
 ``AVAILABLE_VIRTUAL_MEMORY``  Available virtual memory in MiB [#mebibytes]_
 ``TOTAL_PHYSICAL_MEMORY``     Total physical memory in MiB [#mebibytes]_
 ``AVAILABLE_PHYSICAL_MEMORY`` Available physical memory in MiB [#mebibytes]_
+============================= ================================================
+
+.. versionadded:: 3.10
+  Additional ``<key>`` values are available:
+
+============================= ================================================
+Key                           Description
+============================= ================================================
 ``IS_64BIT``                  One if processor is 64Bit
 ``HAS_FPU``                   One if processor has floating point unit
 ``HAS_MMX``                   One if processor supports MMX instructions
diff --git a/Help/command/cmake_minimum_required.rst b/Help/command/cmake_minimum_required.rst
index e6ebcf0..fe0e424 100644
--- a/Help/command/cmake_minimum_required.rst
+++ b/Help/command/cmake_minimum_required.rst
@@ -7,6 +7,9 @@
 
   cmake_minimum_required(VERSION <min>[...<max>] [FATAL_ERROR])
 
+.. versionadded:: 3.12
+  The optional ``<max>`` version.
+
 Sets the minimum required version of cmake for a project.
 Also updates the policy settings as explained below.
 
diff --git a/Help/command/cmake_parse_arguments.rst b/Help/command/cmake_parse_arguments.rst
index 8803ec8..8dedc80 100644
--- a/Help/command/cmake_parse_arguments.rst
+++ b/Help/command/cmake_parse_arguments.rst
@@ -21,11 +21,12 @@
 The first signature reads processes arguments passed in the ``<args>...``.
 This may be used in either a :command:`macro` or a :command:`function`.
 
-The ``PARSE_ARGV`` signature is only for use in a :command:`function`
-body.  In this case the arguments that are parsed come from the
-``ARGV#`` variables of the calling function.  The parsing starts with
-the ``<N>``-th argument, where ``<N>`` is an unsigned integer.  This allows for
-the values to have special characters like ``;`` in them.
+.. versionadded:: 3.7
+  The ``PARSE_ARGV`` signature is only for use in a :command:`function`
+  body.  In this case the arguments that are parsed come from the
+  ``ARGV#`` variables of the calling function.  The parsing starts with
+  the ``<N>``-th argument, where ``<N>`` is an unsigned integer.
+  This allows for the values to have special characters like ``;`` in them.
 
 The ``<options>`` argument contains all options for the respective macro,
 i.e.  keywords which can be used when calling the macro without any value
@@ -40,12 +41,11 @@
 macro which can be followed by more than one value, like e.g. the
 ``TARGETS`` or ``FILES`` keywords of the :command:`install` command.
 
-.. note::
-
-   All keywords shall be unique. I.e. every keyword shall only be specified
-   once in either ``<options>``, ``<one_value_keywords>`` or
-   ``<multi_value_keywords>``. A warning will be emitted if uniqueness is
-   violated.
+.. versionchanged:: 3.5
+  All keywords shall be unique. I.e. every keyword shall only be specified
+  once in either ``<options>``, ``<one_value_keywords>`` or
+  ``<multi_value_keywords>``. A warning will be emitted if uniqueness is
+  violated.
 
 When done, ``cmake_parse_arguments`` will consider for each of the
 keywords listed in ``<options>``, ``<one_value_keywords>`` and
@@ -61,10 +61,12 @@
 were recognized. This can be checked afterwards to see
 whether your macro was called with unrecognized parameters.
 
-``<one_value_keywords>`` and ``<multi_value_keywords>`` that were given no
-values at all are collected in a variable ``<prefix>_KEYWORDS_MISSING_VALUES``
-that will be undefined if all keywords received values. This can be checked
-to see if there were keywords without any values given.
+.. versionadded:: 3.15
+   ``<one_value_keywords>`` and ``<multi_value_keywords>`` that were given no
+   values at all are collected in a variable
+   ``<prefix>_KEYWORDS_MISSING_VALUES`` that will be undefined if all keywords
+   received values. This can be checked to see if there were keywords without
+   any values given.
 
 Consider the following example macro, ``my_install()``, which takes similar
 arguments to the real :command:`install` command:
diff --git a/Help/command/cmake_path.rst b/Help/command/cmake_path.rst
new file mode 100644
index 0000000..2d37ae0
--- /dev/null
+++ b/Help/command/cmake_path.rst
@@ -0,0 +1,817 @@
+cmake_path
+----------
+
+.. versionadded:: 3.20
+
+Filesystem path manipulation command.
+
+This command is dedicated to the manipulation of objects of type path which
+represent paths on a filesystem. Only syntactic aspects of paths are handled:
+the pathname may represent a non-existing path or even one that is not allowed
+to exist on the current file system or OS.
+
+For operations involving the filesystem, have a look at the :command:`file`
+command.
+
+The path name has the following syntax:
+
+1. ``root-name`` (optional): identifies the root on a filesystem with multiple
+   roots (such as ``"C:"`` or ``"//myserver"``).
+
+2. ``root-directory`` (optional): a directory separator that, if present, marks
+   this path as absolute. If it is missing (and the first element other than
+   the ``root-name`` is a ``item-name``), then the path is relative.
+
+Zero or more of the following:
+
+3. ``item-name``: sequence of characters that aren't directory separators. This
+   name may identify a file, a hard link, a symbolic link, or a directory. Two
+   special ``item-names`` are recognized:
+
+     * ``dot``: the item name consisting of a single dot character ``.`` is a
+       directory name that refers to the current directory.
+
+     * ``dot-dot``: the item name consisting of two dot characters ``..`` is a
+       directory name that refers to the parent directory.
+
+4. ``directory-separator``: the forward slash character ``/``. If this
+   character is repeated, it is treated as a single directory separator:
+   ``/usr///////lib`` is the same as ``/usr/lib``.
+
+.. _FILENAME_DEF:
+
+A path has a filename if it does not ends with a ``directory-separator``. The
+filename is the last ``item-name`` of the path.
+
+.. _EXTENSION_DEF:
+
+A :ref:`filename <FILENAME_DEF>` can have an extension. By default, the
+extension is defined as the sub-string beginning at the leftmost period
+(including the period) and until the end of the pathname. When the option
+``LAST_ONLY`` is specified, the extension is the sub-string beginning at the
+rightmost period.
+
+The following exceptions apply:
+
+  * If the first character in the :ref:`filename <FILENAME_DEF>` is a period,
+    that period is ignored (a filename like ``".profile"`` is not treated as an
+    extension).
+
+  * If the pathname is either ``.`` or ``..``.
+
+.. note::
+
+  ``cmake_path`` command handles paths in the format of the build system, not
+  the target system. So this is not generally applicable to the target system
+  in cross-compiling environment.
+
+For all commands, ``<path-var>`` placeholder expect a variable name. An error
+will be raised if the variable does not exist, except for `SET`_ and `APPEND`_
+sub-commands. ``<input>`` placeholder expect a string literal.
+``[<input>...]`` placeholder expect zero or more arguments. ``<out-var>``
+placeholder expect a variable name.
+
+.. note::
+
+  ``cmake_path`` command does not support list of paths. The ``<path-var>``
+  placeholder must store only one path name.
+
+To initialize a path variable, three possibilities can be used:
+
+1. :command:`set` command.
+2. :ref:`cmake_path(SET) <SET>` command. Mainly used to build a
+   path variable from a native path.
+3. :ref:`cmake_path(APPEND) <APPEND>` command. Can be used to build a path from
+   already available path fragments.
+
+  .. code-block:: cmake
+
+    # To build the path "${CMAKE_CURRENT_SOURCE_DIR}/data"
+
+    set (path1 "${CMAKE_CURRENT_SOURCE_DIR}/data")
+
+    cmake_path(SET path2 "${CMAKE_CURRENT_SOURCE_DIR}/data")
+
+    cmake_path(APPEND path3 "${CMAKE_CURRENT_SOURCE_DIR}" "data")
+
+`Modification`_ and `Generation`_ sub-commands store the result in-place or in
+the variable specified by  ``OUTPUT_VARIABLE`` option. All other sub-commands
+store the result in the required ``<out-var>`` variable.
+
+Sub-commands supporting ``NORMALIZE`` option will :ref:`normalize <NORMAL_PATH>`
+the path.
+
+Synopsis
+^^^^^^^^
+
+.. parsed-literal::
+
+  `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_PATH <GET_RELATIVE_PATH>` <out-var>)
+    cmake_path(`GET`_ <path-var> :ref:`PARENT_PATH <GET_PARENT_PATH>` <out-var>)
+
+  `Modification`_
+    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>])
+    cmake_path(`REPLACE_FILENAME`_ <path-var> <input> [OUTPUT_VARIABLE <out-var>])
+    cmake_path(`REMOVE_EXTENSION`_ <path-var> [LAST_ONLY]
+                                              [OUTPUT_VARIABLE <out-var>])
+    cmake_path(`REPLACE_EXTENSION`_ <path-var> [LAST_ONLY] <input>
+                                               [OUTPUT_VARIABLE <out-var>])
+
+  `Generation`_
+    cmake_path(`NORMAL_PATH`_ <path-var> [OUTPUT_VARIABLE <out-var>])
+    cmake_path(`RELATIVE_PATH`_ <path-var> [BASE_DIRECTORY <input>]
+                                           [OUTPUT_VARIABLE <out-var>])
+    cmake_path(`ABSOLUTE_PATH`_ <path-var> [BASE_DIRECTORY <input>] [NORMALIZE]
+                                           [OUTPUT_VARIABLE <out-var>])
+
+  `Conversion`_
+    cmake_path(`NATIVE_PATH`_ <path-var> [NORMALIZE] <out-var>)
+    cmake_path(`CONVERT`_ <input> `TO_CMAKE_PATH_LIST`_ <out-var>)
+    cmake_path(`CONVERT`_ <input> `TO_NATIVE_PATH_LIST`_ <out-var>)
+
+  `Comparison`_
+    cmake_path(`COMPARE`_ <input1> <OP> <input2> <out-var>)
+
+  `Query`_
+    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>)
+    cmake_path(`HAS_FILENAME`_ <path-var> <out-var>)
+    cmake_path(`HAS_EXTENSION`_ <path-var> <out-var>)
+    cmake_path(`HAS_STEM`_ <path-var> <out-var>)
+    cmake_path(`HAS_RELATIVE_PATH`_ <path-var> <out-var>)
+    cmake_path(`HAS_PARENT_PATH`_ <path-var> <out-var>)
+    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>)
+
+  `Hashing`_
+    cmake_path(`HASH`_ <path-var> [NORMALIZE] <out-var>)
+
+Decomposition
+^^^^^^^^^^^^^
+
+.. _GET:
+.. _GET_ROOT_NAME:
+
+.. code-block:: cmake
+
+  cmake_path(GET <path-var> ROOT_NAME <out-var>)
+
+Returns the root name of the path. If the path does not include a root name,
+returns an empty path.
+
+.. note::
+
+  Only ``Windows`` system has the concept of ``root-name``, so on all other
+  systems, it is always an empty path.
+
+For example:
+
+  .. code-block:: cmake
+
+    set (path "c:/a")
+    cmake_path (GET path ROOT_NAME output)
+    message ("Root name is \"${output}\"")
+
+  Will display::
+
+    Root name is "c:"
+
+.. _GET_ROOT_DIRECTORY:
+
+.. code-block:: cmake
+
+  cmake_path(GET <path-var> ROOT_DIRECTORY <out-var>)
+
+Returns the root directory of the path. If the path does not include a root
+directory, returns an empty path.
+
+For example:
+
+  .. code-block:: cmake
+
+    set (path "c:/a")
+    cmake_path (GET path ROOT_DIRECTORY output)
+    message ("Root directory is \"${output}\"")
+
+  Will display::
+
+    Root directory is "/"
+
+.. _GET_ROOT_PATH:
+
+.. code-block:: cmake
+
+  cmake_path(GET <path-var> ROOT_PATH <out-var>)
+
+Returns the root path of the path. If the path does not include a root path,
+returns an empty path.
+
+Effectively, returns the following: ``root-name root-directory``.
+
+For example:
+
+  .. code-block:: cmake
+
+    set (path "c:/a")
+    cmake_path (GET path ROOT_PATH output)
+    message ("Root path is \"${output}\"")
+
+  Will display::
+
+    Root path is "c:/"
+
+.. _GET_FILENAME:
+
+.. code-block:: cmake
+
+  cmake_path(GET <path-var> FILENAME <out-var>)
+
+Returns the :ref:`filename <FILENAME_DEF>` component of the path. If the path
+ends with a ``directory-separator``, there is no filename, so returns an empty
+path.
+
+For example:
+
+  .. code-block:: cmake
+
+    set (path "/a")
+    cmake_path (GET path FILENAME output)
+    message ("First filename is \"${output}\"")
+
+    set (path "/a/")
+    cmake_path (GET path FILENAME output)
+    message ("Second filename is \"${output}\"")
+
+  Will display::
+
+    First filename is "a"
+    Second filename is ""
+
+.. _GET_EXTENSION:
+
+.. code-block:: cmake
+
+  cmake_path(GET <path-var> EXTENSION [LAST_ONLY] <out-var>)
+
+Returns the :ref:`extension <EXTENSION_DEF>` of the filename component.
+
+If the :ref:`filename <FILENAME_DEF>` component of the path contains a period
+(``.``), and is not one of the special filesystem elements ``dot`` or
+``dot-dot``, then the :ref:`extension <EXTENSION_DEF>` is returned.
+
+For example:
+
+  .. code-block:: cmake
+
+    set (path "name.ext1.ext2")
+    cmake_path (GET path EXTENSION result)
+    message ("Full extension is \"${result}\"")
+    cmake_path (GET path EXTENSION LAST_ONLY result)
+    message ("Last extension is \"${result}\"")
+
+  Will display::
+
+    Full extension is ".ext1.ext2"
+    Last extension is ".ext2"
+
+The following exceptions apply:
+
+  * If the first character in the filename is a period, that period is ignored
+    (a filename like ``".profile"`` is not treated as an extension).
+
+  * If the pathname is either ``.`` or ``..``, or if
+    :ref:`filename <FILENAME_DEF>` component does not contain the ``.``
+    character, then an empty path is returned.
+
+.. _GET_STEM:
+
+.. code-block:: cmake
+
+  cmake_path(GET <path-var> STEM [LAST_ONLY] <out-var>)
+
+Returns the :ref:`filename <FILENAME_DEF>` component of the path stripped of
+its :ref:`extension <EXTENSION_DEF>`.
+
+For Example:
+
+  .. code-block:: cmake
+
+    set (path "name.ext1.ext2")
+    cmake_path (GET path STEM result)
+    message ("Filename without the extension is \"${result}\"")
+    cmake_path (GET path STEM LAST_ONLY result)
+    message ("Filename whiteout the last extension is \"${result}\"")
+
+  Will display::
+
+    Filename without the extension is "name"
+    Filename without the last extension is "name.ext1"
+
+The following exceptions apply:
+
+  * If the first character in the filename is a period, that period is ignored
+    (a filename like ``".profile"`` is not treated as an extension).
+
+  * If the filename is one of the special filesystem components ``dot`` or
+    ``dot-dot``, or if it has no periods, the function returns the entire
+    :ref:`filename <FILENAME_DEF>` component.
+
+.. _GET_RELATIVE_PATH:
+
+.. code-block:: cmake
+
+  cmake_path(GET <path-var> RELATIVE_PATH <out-var>)
+
+Returns path relative to ``root-path``, that is, a pathname composed of
+every component of ``<path-var>`` after ``root-path``. If ``<path-var>`` is
+an empty path, returns an empty path.
+
+For Example:
+
+  .. code-block:: cmake
+
+    set (path "/a/b")
+    cmake_path (GET path RELATIVE_PATH result)
+    message ("Relative path is \"${result}\"")
+
+    set (path "/")
+    cmake_path (GET path RELATIVE_PATH result)
+    message ("Relative path is \"${result}\"")
+
+  Will display::
+
+    Relative path is "a/b"
+    Relative path is ""
+
+.. _GET_PARENT_PATH:
+
+.. code-block:: cmake
+
+  cmake_path(GET <path-var> PARENT_PATH <out-var>)
+
+Returns the path to the parent directory.
+
+If `HAS_RELATIVE_PATH`_ sub-command returns false, the result is a copy of
+``<path-var>``. Otherwise, the result is ``<path-var>`` with one fewer element.
+
+For Example:
+
+  .. code-block:: cmake
+
+    set (path "c:/a/b")
+    cmake_path (GET path PARENT_PATH result)
+    message ("Parent path is \"${result}\"")
+
+    set (path "c:/")
+    cmake_path (GET path PARENT_PATH result)
+    message ("Parent path is \"${result}\"")
+
+  Will display::
+
+    Parent path is "c:/a"
+    Relative path is "c:/"
+
+Modification
+^^^^^^^^^^^^
+
+.. _cmake_path-SET:
+.. _SET:
+
+.. code-block:: cmake
+
+    cmake_path(SET <path-var> [NORMALIZE] <input>)
+
+Assign the ``<input>`` path to ``<path-var>``. Moreover, if ``<input>`` is a
+native path, it is converted into cmake-style path with forward-slashes
+(``/``). On Windows, the long filename marker is taken into account.
+
+When ``NORMALIZE`` option is specified, the path is :ref:`normalized
+<NORMAL_PATH>` before the conversion.
+
+For Example:
+
+  .. code-block:: cmake
+
+    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}\"")
+
+  Will display::
+
+    CMake path is "c:/a/b/../c"
+    Normalized CMake path is "c:/a/c"
+
+.. _APPEND:
+
+.. code-block:: cmake
+
+    cmake_path(APPEND <path-var> [<input>...] [OUTPUT_VARIABLE <out-var>])
+
+Append all the ``<input>`` arguments to the ``<path-var>`` using ``/`` as
+``directory-separator``.
+
+For each ``<input>`` argument, the following algorithm (pseudo-code) applies:
+
+  .. code-block:: cmake
+
+    # <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()))
+      replaces <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()))
+      appends directory-separator to <path>
+    ENDIF()
+
+    appends <input> omitting any root-name to <path>
+
+.. _APPEND_STRING:
+
+.. code-block:: cmake
+
+    cmake_path(APPEND_STRING <path-var> [<input>...] [OUTPUT_VARIABLE <out-var>])
+
+Append all the ``<input>`` arguments to the ``<path-var>`` without
+``directory-separator``.
+
+.. _REMOVE_FILENAME:
+
+.. code-block:: cmake
+
+    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 this function returns, if change is done in-place, `HAS_FILENAME`_
+returns false for ``<path-var>``.
+
+For Example:
+
+  .. code-block:: cmake
+
+    set (path "/a/b")
+    cmake_path (REMOVE_FILENAME path)
+    message ("First path is \"${path}\"")
+
+    cmake_path (REMOVE_FILENAME path)
+    message ("Second path is \"${result}\"")
+
+  Will display::
+
+    First path is "/a/"
+    Second path is "/a/"
+
+.. _REPLACE_FILENAME:
+
+.. code-block:: cmake
+
+    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 (`HAS_FILENAME`_ returns false),
+the path is unchanged.
+
+Equivalent to the following:
+
+  .. code-block:: cmake
+
+    cmake_path(HAS_FILENAME path has_filename)
+    if (has_filename)
+      cmake_path(REMOVE_FILENAME path)
+      cmake_path(APPEND path "replacement");
+    endif()
+
+.. _REMOVE_EXTENSION:
+
+.. code-block:: cmake
+
+    cmake_path(REMOVE_EXTENSION <path-var> [LAST_ONLY]
+                                           [OUTPUT_VARIABLE <out-var>])
+
+Removes the :ref:`extension <EXTENSION_DEF>`, if any, from ``<path-var>``.
+
+.. _REPLACE_EXTENSION:
+
+.. code-block:: cmake
+
+    cmake_path(REPLACE_EXTENSION <path-var> [LAST_ONLY] <input>
+                                 [OUTPUT_VARIABLE <out-var>])
+
+Replaces the :ref:`extension <EXTENSION_DEF>` with ``<input>``.
+
+  1. If ``<path-var>`` has an :ref:`extension <EXTENSION_DEF>`
+     (`HAS_EXTENSION`_ is true), it is removed.
+  2. A ``dot`` character is appended to ``<path-var>``, if ``<input>`` is not
+     empty or does not begin with a ``dot`` character.
+  3. ``<input>`` is appended as if `APPEND_STRING`_ was used.
+
+
+Equivalent to the following:
+
+  .. code-block:: cmake
+
+    cmake_path(REMOVE_EXTENSION path)
+    if (NOT "input" MATCHES "^\\.")
+      cmake_path(APPEND_STRING path ".")
+    endif()
+    cmake_path(APPEND_STRING path "input");
+
+Generation
+^^^^^^^^^^
+
+.. _NORMAL_PATH:
+
+.. code-block:: cmake
+
+    cmake_path(NORMAL_PATH <path-var> [OUTPUT_VARIABLE <out-var>])
+
+Normalize ``<path-var>``.
+
+A path can be normalized by following this algorithm:
+
+  1. If the path is empty, stop (normal form of an empty path is an empty
+     path).
+  2. Replace each ``directory-separator`` (which may consist of multiple
+     separators) with a single ``/``.
+  3. Replace each ``directory-separator`` character in the ``root-name`` with
+     ``/``.
+  4. Remove each ``dot`` and any immediately following ``directory-separator``.
+  5. Remove each non-dot-dot filename immediately followed by a
+     ``directory-separator`` and a ``dot-dot``, along with any immediately
+     following ``directory-separator``.
+  6. If there is ``root-directory``, remove all ``dot-dots`` and any
+     ``directory-separators`` immediately following them.
+  7. If the last filename is ``dot-dot``, remove any trailing
+     ``directory-separator``.
+  8. If the path is empty, add a ``dot`` (normal form of ``./`` is ``.``).
+
+.. _cmake_path-RELATIVE_PATH:
+.. _RELATIVE_PATH:
+
+.. code-block:: cmake
+
+    cmake_path(RELATIVE_PATH <path-var> [BASE_DIRECTORY <input>]
+                                        [OUTPUT_VARIABLE <out-var>])
+
+Returns ``<path-var>`` made relative to ``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 described
+`here <https://en.cppreference.com/w/cpp/filesystem/path/lexically_normal>`_.
+
+.. _ABSOLUTE_PATH:
+
+.. code-block:: cmake
+
+    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 specifired, the default base directory will be
+:variable:`CMAKE_CURRENT_SOURCE_DIR`.
+
+When ``NORMALIZE`` option is specified, the path is :ref:`normalized
+<NORMAL_PATH>` after the path computation.
+
+Because ``cmake_path`` does not access to the filesystem, symbolic links are
+not resolved. To compute a real path, use :command:`file(REAL_PATH)`
+command.
+
+Conversion
+^^^^^^^^^^
+
+.. _cmake_path-NATIVE_PATH:
+.. _NATIVE_PATH:
+
+.. code-block:: cmake
+
+    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 and ``/`` elsewhere).
+
+When ``NORMALIZE`` option is specified, the path is :ref:`normalized
+<NORMAL_PATH>` before the conversion.
+
+.. _CONVERT:
+.. _cmake_path-TO_CMAKE_PATH_LIST:
+.. _TO_CMAKE_PATH_LIST:
+
+.. code-block:: cmake
+
+   cmake_path(CONVERT <input> TO_CMAKE_PATH_LIST <out-var> [NORMALIZE])
+
+Converts a native ``<input>`` path into cmake-style path with forward-slashes
+(``/``).  On Windows, 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. The
+result of the conversion is stored in the ``<out-var>`` variable.
+
+When ``NORMALIZE`` option is specified, the path is :ref:`normalized
+<NORMAL_PATH>` before the conversion.
+
+.. _cmake_path-TO_NATIVE_PATH_LIST:
+.. _TO_NATIVE_PATH_LIST:
+
+.. code-block:: cmake
+
+  cmake_path(CONVERT <input> TO_NATIVE_PATH_LIST <out-var> [NORMALIZE])
+
+Converts a cmake-style ``<input>`` path into a native path with
+platform-specific slashes (``\`` on Windows and ``/`` elsewhere). The input can
+be a single path or a cmake-style list. A list will be converted into a native
+search path. The result of the conversion is stored in the ``<out-var>``
+variable.
+
+When ``NORMALIZE`` option is specified, the path is :ref:`normalized
+<NORMAL_PATH>` before the conversion.
+
+For Example:
+
+  .. 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}\"")
+
+  Will display, on Windows::
+
+    Native path list is "\a\b\c;\x\y\z"
+
+  And on the all other systems::
+
+    Native path list is "/a/b/c:/x/y/z"
+
+Comparison
+^^^^^^^^^^
+
+.. _COMPARE:
+
+.. code-block:: cmake
+
+    cmake_path(COMPARE <input1> EQUAL <input2> <out-var>)
+    cmake_path(COMPARE <input1> NOT_EQUAL <input2> <out-var>)
+
+Compares the lexical representations of the path and another path.
+
+For testing equality, the following algorithm (pseudo-code) apply:
+
+  .. code-block:: cmake
+
+    IF (NOT <input1>.root_name() STREQUAL <input2>.root_name())
+      returns FALSE
+    ELSEIF (<input1>.has_root_directory() XOR <input2>.has_root_directory())
+      returns FALSE
+    ENDIF()
+
+    returns TRUE or FALSE if the relative portion of <input1> is
+      lexicographically equal or not to the relative portion of <input2>.
+      Comparison is performed path component-wise
+
+Query
+^^^^^
+
+.. _HAS_ROOT_NAME:
+
+.. code-block:: cmake
+
+    cmake_path(HAS_ROOT_NAME <path-var> <out-var>)
+
+Checks if ``<path-var>`` has ``root-name``.
+
+.. _HAS_ROOT_DIRECTORY:
+
+.. code-block:: cmake
+
+    cmake_path(HAS_ROOT_DIRECTORY <path-var> <out-var>)
+
+Checks if ``<path-var>`` has ``root-directory``.
+
+.. _HAS_ROOT_PATH:
+
+.. code-block:: cmake
+
+    cmake_path(HAS_ROOT_PATH <path-var> <out-var>)
+
+Checks if ``<path-var>`` has root path.
+
+Effectively, checks if ``<path-var>`` has ``root-name`` and ``root-directory``.
+
+.. _HAS_FILENAME:
+
+.. code-block:: cmake
+
+    cmake_path(HAS_FILENAME <path-var> <out-var>)
+
+Checks if ``<path-var>`` has a :ref:`filename <FILENAME_DEF>`.
+
+.. _HAS_EXTENSION:
+
+.. code-block:: cmake
+
+    cmake_path(HAS_EXTENSION <path-var> <out-var>)
+
+Checks if ``<path-var>`` has an :ref:`extension <EXTENSION_DEF>`. If the first
+character in the filename is a period, it is not treated as an extension (for
+example ".profile").
+
+.. _HAS_STEM:
+
+.. code-block:: cmake
+
+    cmake_path(HAS_STEM <path-var> <out-var>)
+
+Checks if ``<path-var>`` has stem (:ref:`GET ... STEM <GET_STEM>` returns a non
+empty path).
+
+.. _HAS_RELATIVE_PATH:
+
+.. code-block:: cmake
+
+    cmake_path(HAS_RELATIVE_PATH <path-var> <out-var>)
+
+Checks if ``<path-var>`` has relative path (`GET_RELATIVE_PATH`_ returns a
+non-empty path).
+
+.. _HAS_PARENT_PATH:
+
+.. code-block:: cmake
+
+    cmake_path(HAS_PARENT_PATH <path-var> <out-var>)
+
+Checks if ``<path-var>`` has parent path. The result is true except if the path
+is only composed of a :ref:`filename <FILENAME_DEF>`.
+
+.. _IS_ABSOLUTE:
+
+.. code-block:: cmake
+
+    cmake_path(IS_ABSOLUTE <path-var> <out-var>)
+
+Checks 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.
+
+.. _IS_RELATIVE:
+
+.. code-block:: cmake
+
+    cmake_path(IS_RELATIVE <path-var> <out-var>)
+
+Checks if path is relative (i.e. not :ref:`absolute <IS_ABSOLUTE>`).
+
+.. _IS_PREFIX:
+
+.. code-block:: cmake
+
+    cmake_path(IS_PREFIX <path-var> <input> [NORMALIZE] <out-var>)
+
+Checks if ``<path-var>`` is the prefix of ``<input>``.
+
+When ``NORMALIZE`` option is specified, the paths are :ref:`normalized
+<NORMAL_PATH>` before the check.
+
+Hashing
+^^^^^^^
+
+.. _HASH:
+
+.. code-block:: cmake
+
+    cmake_path(HASH <path-var> [NORMALIZE] <out-var>)
+
+Compute hash value of ``<path-var>`` such that if for two paths (``p1`` and
+``p2``) are equal (:ref:`COMPARE ... EQUAL <COMPARE>`) then hash value of p1 is
+equal to hash value of p2.
+
+When ``NORMALIZE`` option is specified, the paths are :ref:`normalized
+<NORMAL_PATH>` before the check.
diff --git a/Help/command/cmake_policy.rst b/Help/command/cmake_policy.rst
index 4bc7807..94060d9 100644
--- a/Help/command/cmake_policy.rst
+++ b/Help/command/cmake_policy.rst
@@ -28,6 +28,9 @@
 
   cmake_policy(VERSION <min>[...<max>])
 
+.. versionadded:: 3.12
+  The optional ``<max>`` version.
+
 ``<min>`` and the optional ``<max>`` are each CMake versions of the form
 ``major.minor[.patch[.tweak]]``, and the ``...`` is literal.  The ``<min>``
 version must be at least ``2.4`` and at most the running version of CMake.
diff --git a/Help/command/configure_file.rst b/Help/command/configure_file.rst
index c59995a..63ea84d 100644
--- a/Help/command/configure_file.rst
+++ b/Help/command/configure_file.rst
@@ -6,8 +6,9 @@
 .. code-block:: cmake
 
   configure_file(<input> <output>
+                 [FILE_PERMISSIONS <permissions>...]
                  [COPYONLY] [ESCAPE_QUOTES] [@ONLY]
-                 [NO_SOURCE_PERMISSIONS]
+                 [NO_SOURCE_PERMISSIONS] [USE_SOURCE_PERMISSIONS]
                  [NEWLINE_STYLE [UNIX|DOS|WIN32|LF|CRLF] ])
 
 Copies an ``<input>`` file to an ``<output>`` file and substitutes
@@ -37,22 +38,24 @@
 line after the variable name, if any, is processed as above.
 Input file lines of the form ``#cmakedefine01 VAR`` will be replaced with
 either ``#define VAR 1`` or ``#define VAR 0`` similarly.
-The result lines (with the exception of the ``#undef`` comments) can be
-indented using spaces and/or tabs between the ``#`` character
-and the ``cmakedefine`` or ``cmakedefine01`` words. This whitespace
-indentation will be preserved in the output lines:
 
-.. code-block:: c
+.. versionadded:: 3.10
+  The result lines (with the exception of the ``#undef`` comments) can be
+  indented using spaces and/or tabs between the ``#`` character
+  and the ``cmakedefine`` or ``cmakedefine01`` words. This whitespace
+  indentation will be preserved in the output lines:
 
-  #  cmakedefine VAR
-  #  cmakedefine01 VAR
+  .. code-block:: c
 
-will be replaced, if ``VAR`` is defined, with
+    #  cmakedefine VAR
+    #  cmakedefine01 VAR
 
-.. code-block:: c
+  will be replaced, if ``VAR`` is defined, with
 
-  #  define VAR
-  #  define VAR 1
+  .. code-block:: c
+
+    #  define VAR
+    #  define VAR 1
 
 If the input file is modified the build system will re-run CMake to
 re-configure the file and generate the build system again.
@@ -72,6 +75,9 @@
   If the path names an existing directory the output file is placed
   in that directory with the same file name as the input file.
 
+``FILE_PERMISSIONS <permissions>...``
+  Use user provided permissions for the output file.
+
 ``COPYONLY``
   Copy the file without replacing any variable references or other
   content.  This option may not be used with ``NEWLINE_STYLE``.
@@ -84,10 +90,17 @@
   This is useful for configuring scripts that use ``${VAR}`` syntax.
 
 ``NO_SOURCE_PERMISSIONS``
+  .. versionadded:: 3.19
+
   Does not transfer the file permissions of the original file to the copy.
   The copied file permissions default to the standard 644 value
   (-rw-r--r--).
 
+``USE_SOURCE_PERMISSIONS``
+  .. versionadded:: 3.20
+
+  Transfer the file permissions of the original file to the output file.
+
 ``NEWLINE_STYLE <style>``
   Specify the newline style for the output file.  Specify
   ``UNIX`` or ``LF`` for ``\n`` newlines, or specify
diff --git a/Help/command/ctest_build.rst b/Help/command/ctest_build.rst
index 66e1844..4d6dc5a 100644
--- a/Help/command/ctest_build.rst
+++ b/Help/command/ctest_build.rst
@@ -50,7 +50,10 @@
   for an example.
 
 ``PROJECT_NAME <project-name>``
-  Ignored.  This was once used but is no longer needed.
+  Ignored since CMake 3.0.
+
+  .. versionchanged:: 3.14
+    This value is no longer required.
 
 ``TARGET <target-name>``
   Specify the name of a target to build.  If not specified the
@@ -68,10 +71,14 @@
   Store the return value of the native build tool in the given variable.
 
 ``CAPTURE_CMAKE_ERROR <result-var>``
+  .. versionadded:: 3.7
+
   Store in the ``<result-var>`` variable -1 if there are any errors running
   the command and prevent ctest from returning non-zero if an error occurs.
 
 ``QUIET``
+  .. versionadded:: 3.3
+
   Suppress any CTest-specific non-error output that would have been
   printed to the console otherwise.  The summary of warnings / errors,
   as well as the output from the native build tool is unaffected by
diff --git a/Help/command/ctest_configure.rst b/Help/command/ctest_configure.rst
index 2dea07b..95712aa 100644
--- a/Help/command/ctest_configure.rst
+++ b/Help/command/ctest_configure.rst
@@ -37,10 +37,14 @@
   configuration tool.
 
 ``CAPTURE_CMAKE_ERROR <result-var>``
+  .. versionadded:: 3.7
+
   Store in the ``<result-var>`` variable -1 if there are any errors running
   the command and prevent ctest from returning non-zero if an error occurs.
 
 ``QUIET``
+  .. versionadded:: 3.3
+
   Suppress any CTest-specific non-error messages that would have
   otherwise been printed to the console.  Output from the underlying
   configure command is not affected.
diff --git a/Help/command/ctest_coverage.rst b/Help/command/ctest_coverage.rst
index d50f634..a6c643b 100644
--- a/Help/command/ctest_coverage.rst
+++ b/Help/command/ctest_coverage.rst
@@ -37,10 +37,14 @@
   ran without error and non-zero otherwise.
 
 ``CAPTURE_CMAKE_ERROR <result-var>``
+  .. versionadded:: 3.7
+
   Store in the ``<result-var>`` variable -1 if there are any errors running
   the command and prevent ctest from returning non-zero if an error occurs.
 
 ``QUIET``
+  .. versionadded:: 3.3
+
   Suppress any CTest-specific non-error output that would have been
   printed to the console otherwise.  The summary indicating how many
   lines of code were covered is unaffected by this option.
diff --git a/Help/command/ctest_memcheck.rst b/Help/command/ctest_memcheck.rst
index 288b65a..f655c2e 100644
--- a/Help/command/ctest_memcheck.rst
+++ b/Help/command/ctest_memcheck.rst
@@ -35,4 +35,6 @@
 The options unique to this command are:
 
 ``DEFECT_COUNT <defect-count-var>``
+  .. versionadded:: 3.8
+
   Store in the ``<defect-count-var>`` the number of defects found.
diff --git a/Help/command/ctest_start.rst b/Help/command/ctest_start.rst
index f0704ac..c0f3c6d 100644
--- a/Help/command/ctest_start.rst
+++ b/Help/command/ctest_start.rst
@@ -29,8 +29,11 @@
 ``GROUP <group>``
   If ``GROUP`` is used, the submissions will go to the specified group on the
   CDash server. If no ``GROUP`` is specified, the name of the model is used by
-  default. This replaces the deprecated option ``TRACK``. Despite the name
-  change its behavior is unchanged.
+  default.
+
+  .. versionchanged:: 3.16
+    This replaces the deprecated option ``TRACK``. Despite the name
+    change its behavior is unchanged.
 
 ``APPEND``
   If ``APPEND`` is used, the existing ``TAG`` is used rather than creating a new
@@ -56,6 +59,8 @@
   new model and group will be used.
 
 ``QUIET``
+  .. versionadded:: 3.3
+
   If ``QUIET`` is used, CTest will suppress any non-error messages that it
   otherwise would have printed to the console.
 
diff --git a/Help/command/ctest_submit.rst b/Help/command/ctest_submit.rst
index 983fc20..9c10318 100644
--- a/Help/command/ctest_submit.rst
+++ b/Help/command/ctest_submit.rst
@@ -42,14 +42,20 @@
   Each individual file must exist at the time of the call.
 
 ``SUBMIT_URL <url>``
+  .. versionadded:: 3.14
+
   The ``http`` or ``https`` URL of the dashboard server to send the submission
   to.  If not given, the :variable:`CTEST_SUBMIT_URL` variable is used.
 
 ``BUILD_ID <result-var>``
+  .. versionadded:: 3.15
+
   Store in the ``<result-var>`` variable the ID assigned to this build by
   CDash.
 
 ``HTTPHEADER <HTTP-header>``
+  .. versionadded:: 3.9
+
   Specify HTTP header to be included in the request to CDash during submission.
   For example, CDash can be configured to only accept submissions from
   authenticated clients. In this case, you should provide a bearer token in your
@@ -73,20 +79,27 @@
   non-zero on failure.
 
 ``CAPTURE_CMAKE_ERROR <result-var>``
+  .. versionadded:: 3.13
+
   Store in the ``<result-var>`` variable -1 if there are any errors running
   the command and prevent ctest from returning non-zero if an error occurs.
 
 ``QUIET``
+  .. versionadded:: 3.3
+
   Suppress all non-error messages that would have otherwise been
   printed to the console.
 
 Submit to CDash Upload API
 ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
+.. versionadded:: 3.2
+
 ::
 
   ctest_submit(CDASH_UPLOAD <file> [CDASH_UPLOAD_TYPE <type>]
                [SUBMIT_URL <url>]
+               [BUILD_ID <result-var>]
                [HTTPHEADER <header>]
                [RETRY_COUNT <count>]
                [RETRY_DELAY <delay>]
@@ -99,6 +112,19 @@
 then it is uploaded. Along with the file, a CDash type string is specified
 to tell CDash which handler to use to process the data.
 
-This signature accepts the ``SUBMIT_URL``, ``BUILD_ID``, ``HTTPHEADER``,
-``RETRY_COUNT``, ``RETRY_DELAY``, ``RETURN_VALUE`` and ``QUIET`` options
-as described above.
+This signature interprets options in the same way as the first one.
+
+.. versionadded:: 3.8
+  Added ``RETRY_COUNT``, ``RETRY_DELAY``, ``QUIET`` options.
+
+.. versionadded:: 3.9
+  Added ``HTTPHEADER`` option.
+
+.. versionadded:: 3.13
+  Added ``RETURN_VALUE`` option.
+
+.. versionadded:: 3.14
+  Added ``SUBMIT_URL`` option.
+
+.. versionadded:: 3.15
+  Added ``BUILD_ID`` option.
diff --git a/Help/command/ctest_test.rst b/Help/command/ctest_test.rst
index 3589296..b4493a0 100644
--- a/Help/command/ctest_test.rst
+++ b/Help/command/ctest_test.rst
@@ -68,6 +68,8 @@
   Tests not matching this expression are excluded.
 
 ``EXCLUDE_FIXTURE <regex>``
+  .. versionadded:: 3.7
+
   If a test in the set of tests to be executed requires a particular fixture,
   that fixture's setup and cleanup tests would normally be added to the test
   set automatically. This option prevents adding setup or cleanup tests for
@@ -76,9 +78,13 @@
   setup tests that fail.
 
 ``EXCLUDE_FIXTURE_SETUP <regex>``
+  .. versionadded:: 3.7
+
   Same as ``EXCLUDE_FIXTURE`` except only matching setup tests are excluded.
 
 ``EXCLUDE_FIXTURE_CLEANUP <regex>``
+  .. versionadded:: 3.7
+
   Same as ``EXCLUDE_FIXTURE`` except only matching cleanup tests are excluded.
 
 ``PARALLEL_LEVEL <level>``
@@ -86,11 +92,15 @@
   be run in parallel.
 
 ``RESOURCE_SPEC_FILE <file>``
+  .. versionadded:: 3.16
+
   Specify a
   :ref:`resource specification file <ctest-resource-specification-file>`. See
   :ref:`ctest-resource-allocation` for more information.
 
 ``TEST_LOAD <threshold>``
+  .. versionadded:: 3.4
+
   While running tests in parallel, try not to start tests when they
   may cause the CPU load to pass above a given threshold.  If not
   specified the :variable:`CTEST_TEST_LOAD` variable will be checked,
@@ -98,6 +108,8 @@
   See also the ``TestLoad`` setting in the :ref:`CTest Test Step`.
 
 ``REPEAT <mode>:<n>``
+  .. versionadded:: 3.17
+
   Run tests repeatedly based on the given ``<mode>`` up to ``<n>`` times.
   The modes are:
 
@@ -121,6 +133,8 @@
   implicit test dependencies.
 
 ``STOP_ON_FAILURE``
+  .. versionadded:: 3.18
+
   Stop the execution of the tests once one has failed.
 
 ``STOP_TIME <time-of-day>``
@@ -131,10 +145,14 @@
   Store non-zero if anything went wrong.
 
 ``CAPTURE_CMAKE_ERROR <result-var>``
+  .. versionadded:: 3.7
+
   Store in the ``<result-var>`` variable -1 if there are any errors running
   the command and prevent ctest from returning non-zero if an error occurs.
 
 ``QUIET``
+  .. versionadded:: 3.3
+
   Suppress any CTest-specific non-error messages that would have otherwise
   been printed to the console.  Output from the underlying test command is not
   affected.  Summary info detailing the percentage of passing tests is also
diff --git a/Help/command/ctest_update.rst b/Help/command/ctest_update.rst
index 96a11c9..63f991b 100644
--- a/Help/command/ctest_update.rst
+++ b/Help/command/ctest_update.rst
@@ -24,10 +24,14 @@
   updated or ``-1`` on error.
 
 ``CAPTURE_CMAKE_ERROR <result-var>``
+  .. versionadded:: 3.13
+
   Store in the ``<result-var>`` variable -1 if there are any errors running
   the command and prevent ctest from returning non-zero if an error occurs.
 
 ``QUIET``
+  .. versionadded:: 3.3
+
   Tell CTest to suppress most non-error messages that it would
   have otherwise printed to the console.  CTest will still report
   the new revision of the repository and any conflicting files
diff --git a/Help/command/ctest_upload.rst b/Help/command/ctest_upload.rst
index 39d9de1..ffddd0a 100644
--- a/Help/command/ctest_upload.rst
+++ b/Help/command/ctest_upload.rst
@@ -14,9 +14,13 @@
   dashboard server.
 
 ``QUIET``
+  .. versionadded:: 3.3
+
   Suppress any CTest-specific non-error output that would have been
   printed to the console otherwise.
 
 ``CAPTURE_CMAKE_ERROR <result-var>``
+  .. versionadded:: 3.7
+
   Store in the ``<result-var>`` variable -1 if there are any errors running
   the command and prevent ctest from returning non-zero if an error occurs.
diff --git a/Help/command/enable_language.rst b/Help/command/enable_language.rst
index e8640ea..ce765de 100644
--- a/Help/command/enable_language.rst
+++ b/Help/command/enable_language.rst
@@ -12,6 +12,15 @@
 are ``CXX``, ``C``, ``CUDA``, ``OBJC``, ``OBJCXX``, ``Fortran``,
 ``ISPC``, and ``ASM``.
 
+.. versionadded:: 3.8
+  Added ``CUDA`` support.
+
+.. versionadded:: 3.16
+  Added ``OBJC`` and ``OBJCXX`` support.
+
+.. versionadded:: 3.18
+  Added ``ISPC`` support.
+
 If enabling ``ASM``, enable it last so that CMake can check whether
 compilers for other languages like ``C`` work for assembly too.
 
diff --git a/Help/command/execute_process.rst b/Help/command/execute_process.rst
index 268c307..82fcd46 100644
--- a/Help/command/execute_process.rst
+++ b/Help/command/execute_process.rst
@@ -62,6 +62,8 @@
  describing an error condition.
 
 ``RESULTS_VARIABLE <variable>``
+ .. versionadded:: 3.10
+
  The variable will be set to contain the result of all processes as a
  :ref:`semicolon-separated list <CMake Language Lists>`, in order of the
  given ``COMMAND`` arguments.  Each entry will be an integer return code
@@ -75,19 +77,26 @@
 ``INPUT_FILE, OUTPUT_FILE``, ``ERROR_FILE``
  The file named will be attached to the standard input of the first
  process, standard output of the last process, or standard error of
- all processes, respectively.  If the same file is named for both
- output and error then it will be used for both.
+ all processes, respectively.
+
+ .. versionadded:: 3.3
+  If the same file is named for both output and error then it will be used
+  for both.
 
 ``OUTPUT_QUIET``, ``ERROR_QUIET``
  The standard output or standard error results will be quietly ignored.
 
 ``COMMAND_ECHO <where>``
+ .. versionadded:: 3.15
+
  The command being run will be echo'ed to ``<where>`` with ``<where>``
  being set to one of ``STDERR``, ``STDOUT`` or ``NONE``.
  See the :variable:`CMAKE_EXECUTE_PROCESS_COMMAND_ECHO` variable for a way
  to control the default behavior when this option is not present.
 
 ``ENCODING <name>``
+ .. versionadded:: 3.8
+
  On Windows, the encoding that is used to decode output from the process.
  Ignored on other platforms.
  Valid encoding names are:
@@ -104,11 +113,15 @@
  ``OEM``
    Use the original equipment manufacturer (OEM) code page.
  ``UTF8`` or ``UTF-8``
-   Use the UTF-8 codepage. Prior to CMake 3.11.0, only ``UTF8`` was accepted
-   for this encoding. In CMake 3.11.0, ``UTF-8`` was added for consistency with
-   the `UTF-8 RFC <https://www.ietf.org/rfc/rfc3629>`_ naming convention.
+   Use the UTF-8 codepage.
+
+   .. versionadded:: 3.11
+     Accept ``UTF-8`` spelling for consistency with the
+     `UTF-8 RFC <https://www.ietf.org/rfc/rfc3629>`_ naming convention.
 
 ``ECHO_OUTPUT_VARIABLE``, ``ECHO_ERROR_VARIABLE``
+  .. versionadded:: 3.18
+
   The standard output or standard error will not be exclusively redirected to
   the configured variables.
 
@@ -118,6 +131,8 @@
   This is analogous to the ``tee`` Unix command.
 
 ``COMMAND_ERROR_IS_FATAL <ANY|LAST>``
+  .. versionadded:: 3.19
+
   The option following ``COMMAND_ERROR_IS_FATAL`` determines the behavior when
   an error is encountered:
 
diff --git a/Help/command/export.rst b/Help/command/export.rst
index 2ca7056..e8a1fa7 100644
--- a/Help/command/export.rst
+++ b/Help/command/export.rst
@@ -64,16 +64,23 @@
 wide installations, it is not desirable to write the user package
 registry.
 
-By default the ``export(PACKAGE)`` command does nothing (see policy
-:policy:`CMP0090`) because populating the user package registry has effects
-outside the source and build trees.  Set the
-:variable:`CMAKE_EXPORT_PACKAGE_REGISTRY` variable to add build directories to
-the CMake user package registry.
+.. versionchanged:: 3.1
+  If the :variable:`CMAKE_EXPORT_NO_PACKAGE_REGISTRY` variable
+  is enabled, the ``export(PACKAGE)`` command will do nothing.
+
+.. versionchanged:: 3.15
+  By default the ``export(PACKAGE)`` command does nothing (see policy
+  :policy:`CMP0090`) because populating the user package registry has effects
+  outside the source and build trees.  Set the
+  :variable:`CMAKE_EXPORT_PACKAGE_REGISTRY` variable to add build directories
+  to the CMake user package registry.
 
 .. code-block:: cmake
 
   export(TARGETS [target1 [target2 [...]]]  [ANDROID_MK <filename>])
 
+.. versionadded:: 3.7
+
 This signature exports cmake built targets to the android ndk build system
 by creating an Android.mk file that references the prebuilt targets. The
 Android NDK supports the use of prebuilt libraries, both static and shared.
diff --git a/Help/command/file.rst b/Help/command/file.rst
index e963be0..9580c9c 100644
--- a/Help/command/file.rst
+++ b/Help/command/file.rst
@@ -3,6 +3,21 @@
 
 File manipulation command.
 
+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
+: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.
+
 Synopsis
 ^^^^^^^^
 
@@ -103,10 +118,15 @@
  Consider only strings that match the given regular expression.
 
 ``ENCODING <encoding-type>``
+ .. versionadded:: 3.1
+
  Consider strings of a given encoding.  Currently supported encodings are:
- UTF-8, UTF-16LE, UTF-16BE, UTF-32LE, UTF-32BE.  If the ENCODING option
- is not provided and the file has a Byte Order Mark, the ENCODING option
- will be defaulted to respect the Byte Order Mark.
+ ``UTF-8``, ``UTF-16LE``, ``UTF-16BE``, ``UTF-32LE``, ``UTF-32BE``.
+ If the ``ENCODING`` option is not provided and the file has a Byte Order Mark,
+ the ``ENCODING`` option will be defaulted to respect the Byte Order Mark.
+
+ .. versionadded:: 3.2
+   Added ``UTF-16LE``, ``UTF-16BE``, ``UTF-32LE``, ``UTF-32BE`` encodings.
 
 For example, the code
 
@@ -160,6 +180,8 @@
     [POST_EXCLUDE_REGEXES [<regexes>...]]
     )
 
+.. versionadded:: 3.16
+
 Recursively get the list of libraries depended on by the given files.
 
 Please note that this sub-command is not intended to be used in project mode.
@@ -408,6 +430,9 @@
   If this variable is not specified, it is determined by the value of
   ``CMAKE_OBJDUMP`` if set, else by system introspection.
 
+  .. versionadded:: 3.18
+    Use ``CMAKE_OBJDUMP`` if set.
+
 Writing
 ^^^^^^^
 
@@ -436,6 +461,8 @@
   file(TOUCH [<files>...])
   file(TOUCH_NOCREATE [<files>...])
 
+.. versionadded:: 3.12
+
 Create a file with no content if it does not yet exist. If the file already
 exists, its access and/or modification will be updated to the time when the
 function call is executed.
@@ -469,8 +496,10 @@
 
 ``INPUT <input-file>``
   Use the content from a given file as input.
-  A relative path is treated with respect to the value of
-  :variable:`CMAKE_CURRENT_SOURCE_DIR`.  See policy :policy:`CMP0070`.
+
+  .. versionchanged:: 3.10
+    A relative path is treated with respect to the value of
+    :variable:`CMAKE_CURRENT_SOURCE_DIR`.  See policy :policy:`CMP0070`.
 
 ``OUTPUT <output-file>``
   Specify the output file name to generate.  Use generator expressions
@@ -478,11 +507,15 @@
   name.  Multiple configurations may generate the same output file only
   if the generated content is identical.  Otherwise, the ``<output-file>``
   must evaluate to an unique name for each configuration.
-  A relative path (after evaluating generator expressions) is treated
-  with respect to the value of :variable:`CMAKE_CURRENT_BINARY_DIR`.
-  See policy :policy:`CMP0070`.
+
+  .. versionchanged:: 3.10
+    A relative path (after evaluating generator expressions) is treated
+    with respect to the value of :variable:`CMAKE_CURRENT_BINARY_DIR`.
+    See policy :policy:`CMP0070`.
 
 ``TARGET <target>``
+  .. versionadded:: 3.19
+
   Specify which target to use when evaluating generator expressions that
   require a target for evaluation (e.g. ``$<COMPILE_FEATURES:...>``,
   ``$<TARGET_PROPERTY:prop>``).
@@ -506,6 +539,8 @@
        [ESCAPE_QUOTES] [@ONLY]
        [NEWLINE_STYLE [UNIX|DOS|WIN32|LF|CRLF] ])
 
+.. versionadded:: 3.18
+
 Generate an output file using the input given by ``CONTENT`` and substitute
 variable values referenced as ``@VAR@`` or ``${VAR}`` contained therein. The
 substitution rules behave the same as the :command:`configure_file` command.
@@ -554,20 +589,25 @@
 store it into the ``<variable>``.  Globbing expressions are similar to
 regular expressions, but much simpler.  If ``RELATIVE`` flag is
 specified, the results will be returned as relative paths to the given
-path.  The results will be ordered lexicographically.
+path.
+
+.. versionchanged:: 3.6
+  The results will be ordered lexicographically.
 
 On Windows and macOS, globbing is case-insensitive even if the underlying
 filesystem is case-sensitive (both filenames and globbing expressions are
 converted to lowercase before matching).  On other platforms, globbing is
 case-sensitive.
 
-If the ``CONFIGURE_DEPENDS`` flag is specified, CMake will add logic
-to the main build system check target to rerun the flagged ``GLOB`` commands
-at build time. If any of the outputs change, CMake will regenerate the build
-system.
+.. versionadded:: 3.3
+  By default ``GLOB`` lists directories - directories are omitted in result if
+  ``LIST_DIRECTORIES`` is set to false.
 
-By default ``GLOB`` lists directories - directories are omitted in result if
-``LIST_DIRECTORIES`` is set to false.
+.. versionadded:: 3.12
+  If the ``CONFIGURE_DEPENDS`` flag is specified, CMake will add logic
+  to the main build system check target to rerun the flagged ``GLOB`` commands
+  at build time. If any of the outputs change, CMake will regenerate the build
+  system.
 
 .. note::
   We do not recommend using GLOB to collect a list of source files from
@@ -590,10 +630,11 @@
 are only traversed if ``FOLLOW_SYMLINKS`` is given or policy
 :policy:`CMP0009` is not set to ``NEW``.
 
-By default ``GLOB_RECURSE`` omits directories from result list - setting
-``LIST_DIRECTORIES`` to true adds directories to result list.
-If ``FOLLOW_SYMLINKS`` is given or policy :policy:`CMP0009` is not set to
-``NEW`` then ``LIST_DIRECTORIES`` treats symlinks as directories.
+.. versionadded:: 3.3
+  By default ``GLOB_RECURSE`` omits directories from result list - setting
+  ``LIST_DIRECTORIES`` to true adds directories to result list.
+  If ``FOLLOW_SYMLINKS`` is given or policy :policy:`CMP0009` is not set to
+  ``NEW`` then ``LIST_DIRECTORIES`` treats symlinks as directories.
 
 Examples of recursive globbing include::
 
@@ -619,7 +660,12 @@
 Remove the given files.  The ``REMOVE_RECURSE`` mode will remove the given
 files and directories, also non-empty directories. No error is emitted if a
 given file does not exist.  Relative input paths are evaluated with respect
-to the current source directory.  Empty input paths are ignored with a warning.
+to the current source directory.
+
+.. versionchanged:: 3.15
+  Empty input paths are ignored with a warning.  Previous versions of CMake
+  interpreted empty string as a relative path with respect to the current
+  directory and removed its contents.
 
 .. _MAKE_DIRECTORY:
 
@@ -652,17 +698,18 @@
 permissions unless explicit permissions or ``NO_SOURCE_PERMISSIONS``
 are given (default is ``USE_SOURCE_PERMISSIONS``).
 
-If ``FOLLOW_SYMLINK_CHAIN`` is specified, ``COPY`` will recursively resolve
-the symlinks at the paths given until a real file is found, and install
-a corresponding symlink in the destination for each symlink encountered. For
-each symlink that is installed, the resolution is stripped of the directory,
-leaving only the filename, meaning that the new symlink points to a file in
-the same directory as the symlink. This feature is useful on some Unix systems,
-where libraries are installed as a chain of symlinks with version numbers, with
-less specific versions pointing to more specific versions.
-``FOLLOW_SYMLINK_CHAIN`` will install all of these symlinks and the library
-itself into the destination directory. For example, if you have the following
-directory structure:
+.. versionadded:: 3.15
+  If ``FOLLOW_SYMLINK_CHAIN`` is specified, ``COPY`` will recursively resolve
+  the symlinks at the paths given until a real file is found, and install
+  a corresponding symlink in the destination for each symlink encountered. For
+  each symlink that is installed, the resolution is stripped of the directory,
+  leaving only the filename, meaning that the new symlink points to a file in
+  the same directory as the symlink. This feature is useful on some Unix systems,
+  where libraries are installed as a chain of symlinks with version numbers, with
+  less specific versions pointing to more specific versions.
+  ``FOLLOW_SYMLINK_CHAIN`` will install all of these symlinks and the library
+  itself into the destination directory. For example, if you have the following
+  directory structure:
 
 * ``/opt/foo/lib/libfoo.so.1.2.3``
 * ``/opt/foo/lib/libfoo.so.1.2 -> libfoo.so.1.2.3``
@@ -696,6 +743,8 @@
 
   file(SIZE <filename> <variable>)
 
+.. versionadded:: 3.14
+
 Determine the file size of the ``<filename>`` and put the result in
 ``<variable>`` variable. Requires that ``<filename>`` is a valid path
 pointing to a file and is readable.
@@ -706,6 +755,8 @@
 
   file(READ_SYMLINK <linkname> <variable>)
 
+.. versionadded:: 3.14
+
 This subcommand queries the symlink ``<linkname>`` and stores the path it
 points to in the result ``<variable>``.  If ``<linkname>`` does not exist or
 is not a symlink, CMake issues a fatal error.
@@ -730,6 +781,8 @@
   file(CREATE_LINK <original> <linkname>
        [RESULT <result>] [COPY_ON_ERROR] [SYMBOLIC])
 
+.. versionadded:: 3.14
+
 Create a link ``<linkname>`` that points to ``<original>``.
 It will be a hard link by default, but providing the ``SYMBOLIC`` option
 results in a symbolic link instead.  Hard links require that ``original``
@@ -754,6 +807,8 @@
       [FILE_PERMISSIONS <permissions>...]
       [DIRECTORY_PERMISSIONS <permissions>...])
 
+.. versionadded:: 3.19
+
 Set the permissions for the ``<files>...`` and ``<directories>...`` specified.
 Valid permissions are  ``OWNER_READ``, ``OWNER_WRITE``, ``OWNER_EXECUTE``,
 ``GROUP_READ``, ``GROUP_WRITE``, ``GROUP_EXECUTE``, ``WORLD_READ``,
@@ -790,6 +845,8 @@
        [FILE_PERMISSIONS <permissions>...]
        [DIRECTORY_PERMISSIONS <permissions>...])
 
+.. versionadded:: 3.19
+
 Same as `CHMOD`_, but change the permissions of files and directories present in
 the ``<directories>...`` recursively.
 
@@ -802,6 +859,8 @@
 
   file(REAL_PATH <path> <out-var> [BASE_DIRECTORY <dir>])
 
+.. versionadded:: 3.19
+
 Compute the absolute path to an existing file or directory with symlinks
 resolved.
 
@@ -849,10 +908,12 @@
   file(UPLOAD   <file> <url> [<options>...])
 
 The ``DOWNLOAD`` subcommand downloads the given ``<url>`` to a local ``<file>``.
-If ``<file>`` is not specified for ``file(DOWNLOAD)``, the file is not saved.
-This can be useful if you want to know if a file can be downloaded (for example,
-to check that it exists) without actually saving it anywhere. The ``UPLOAD``
-mode uploads a local ``<file>`` to a given ``<url>``.
+The ``UPLOAD`` mode uploads a local ``<file>`` to a given ``<url>``.
+
+.. versionadded:: 3.19
+  If ``<file>`` is not specified for ``file(DOWNLOAD)``, the file is not saved.
+  This can be useful if you want to know if a file can be downloaded (for example,
+  to check that it exists) without actually saving it anywhere.
 
 Options to both ``DOWNLOAD`` and ``UPLOAD`` are:
 
@@ -877,12 +938,18 @@
   Terminate the operation after a given total time has elapsed.
 
 ``USERPWD <username>:<password>``
+  .. versionadded:: 3.7
+
   Set username and password for operation.
 
 ``HTTPHEADER <HTTP-header>``
+  .. versionadded:: 3.7
+
   HTTP header for operation. Suboption can be repeated several times.
 
 ``NETRC <level>``
+  .. versionadded:: 3.11
+
   Specify whether the .netrc file is to be used for operation.  If this
   option is not specified, the value of the ``CMAKE_NETRC`` variable
   will be used instead.
@@ -899,6 +966,8 @@
     The .netrc file is required, and information in the URL is ignored.
 
 ``NETRC_FILE <file>``
+  .. versionadded:: 3.11
+
   Specify an alternative .netrc file to the one in your home directory,
   if the ``NETRC`` level is ``OPTIONAL`` or ``REQUIRED``. If this option
   is not specified, the value of the ``CMAKE_NETRC_FILE`` variable will
@@ -911,9 +980,15 @@
   Specify whether to verify the server certificate for ``https://`` URLs.
   The default is to *not* verify.
 
+  .. versionadded:: 3.18
+    Added support to ``file(UPLOAD)``.
+
 ``TLS_CAINFO <file>``
   Specify a custom Certificate Authority file for ``https://`` URLs.
 
+  .. versionadded:: 3.18
+    Added support to ``file(UPLOAD)``.
+
 For ``https://`` URLs CMake must be built with OpenSSL support.  ``TLS/SSL``
 certificates are not checked by default.  Set ``TLS_VERIFY`` to ``ON`` to
 check certificates. If neither ``TLS`` option is given CMake will check
@@ -944,6 +1019,8 @@
        [RESULT_VARIABLE <variable>]
        [TIMEOUT <seconds>])
 
+.. versionadded:: 3.2
+
 Lock a file specified by ``<path>`` if no ``DIRECTORY`` option present and file
 ``<path>/cmake.lock`` otherwise. File will be locked for scope defined by
 ``GUARD`` option (default value is ``PROCESS``). ``RELEASE`` option can be used
@@ -979,6 +1056,8 @@
     [MTIME <mtime>]
     [VERBOSE])
 
+.. versionadded:: 3.18
+
 Creates the specified ``<archive>`` file with the files and directories
 listed in ``<paths>``.  Note that ``<paths>`` must list actual files or
 directories, wildcards are not supported.
@@ -993,9 +1072,10 @@
 directed to do so with the ``COMPRESSION`` option.  Valid values for
 ``<compression>`` are ``None``, ``BZip2``, ``GZip``, ``XZ``, and ``Zstd``.
 
-The compression level can be specified with the ``COMPRESSION_LEVEL`` option.
-The ``<compression-level>`` should be between 0-9, with the default being 0.
-The ``COMPRESSION`` option must be present when ``COMPRESSION_LEVEL`` is given.
+.. versionadded:: 3.19
+  The compression level can be specified with the ``COMPRESSION_LEVEL`` option.
+  The ``<compression-level>`` should be between 0-9, with the default being 0.
+  The ``COMPRESSION`` option must be present when ``COMPRESSION_LEVEL`` is given.
 
 .. note::
   With ``FORMAT`` set to ``raw`` only one file will be compressed with the
@@ -1016,6 +1096,8 @@
     [LIST_ONLY]
     [VERBOSE])
 
+.. versionadded:: 3.18
+
 Extracts or lists the content of the specified ``<archive>``.
 
 The directory where the content of the archive will be extracted to can
diff --git a/Help/command/find_package.rst b/Help/command/find_package.rst
index 1be2e09..2ef3e97 100644
--- a/Help/command/find_package.rst
+++ b/Help/command/find_package.rst
@@ -351,15 +351,16 @@
 steps.  If ``NO_DEFAULT_PATH`` is specified all ``NO_*`` options are
 enabled.
 
-1. Search paths specified in the :variable:`<PackageName>_ROOT` CMake
-   variable and the :envvar:`<PackageName>_ROOT` environment variable,
-   where ``<PackageName>`` is the package to be found.
-   The package root variables are maintained as a stack so if
-   called from within a find module, root paths from the parent's find
-   module will also be searched after paths for the current package.
-   This can be skipped if ``NO_PACKAGE_ROOT_PATH`` is passed or by setting
-   the :variable:`CMAKE_FIND_USE_PACKAGE_ROOT_PATH` to ``FALSE``.
-   See policy :policy:`CMP0074`.
+1. .. versionadded:: 3.12
+    Search paths specified in the :variable:`<PackageName>_ROOT` CMake
+    variable and the :envvar:`<PackageName>_ROOT` environment variable,
+    where ``<PackageName>`` is the package to be found.
+    The package root variables are maintained as a stack so if
+    called from within a find module, root paths from the parent's find
+    module will also be searched after paths for the current package.
+    This can be skipped if ``NO_PACKAGE_ROOT_PATH`` is passed or by setting
+    the :variable:`CMAKE_FIND_USE_PACKAGE_ROOT_PATH` to ``FALSE``.
+    See policy :policy:`CMP0074`.
 
 2. Search paths specified in cmake-specific cache variables.  These
    are intended to be used on the command line with a ``-DVAR=value``.
@@ -430,6 +431,10 @@
 9. Search paths specified by the ``PATHS`` option.  These are typically
    hard-coded guesses.
 
+.. versionadded:: 3.16
+   Added ``CMAKE_FIND_USE_<CATEGORY>_PATH`` variables to globally disable
+   various search locations.
+
 .. |FIND_XXX| replace:: find_package
 .. |FIND_ARGS_XXX| replace:: <PackageName>
 .. |CMAKE_FIND_ROOT_PATH_MODE_XXX| replace::
diff --git a/Help/command/foreach.rst b/Help/command/foreach.rst
index a01a104..8de6deb 100644
--- a/Help/command/foreach.rst
+++ b/Help/command/foreach.rst
@@ -88,6 +88,8 @@
 
   foreach(<loop_var>... IN ZIP_LISTS <lists>)
 
+.. versionadded:: 3.17
+
 In this variant, ``<lists>`` is a whitespace or semicolon
 separated list of list-valued variables. The ``foreach``
 command iterates over each list simultaneously setting the
diff --git a/Help/command/function.rst b/Help/command/function.rst
index 7a9b907..3d25aa4 100644
--- a/Help/command/function.rst
+++ b/Help/command/function.rst
@@ -50,8 +50,9 @@
 case chosen in the function definition. Typically functions use
 all-lowercase names.
 
-The :command:`cmake_language(CALL ...)` command can also be used to
-invoke the function.
+.. versionadded:: 3.18
+  The :command:`cmake_language(CALL ...)` command can also be used to
+  invoke the function.
 
 Arguments
 ^^^^^^^^^
diff --git a/Help/command/get_directory_property.rst b/Help/command/get_directory_property.rst
index 39015cc..0ccbfb0 100644
--- a/Help/command/get_directory_property.rst
+++ b/Help/command/get_directory_property.rst
@@ -11,12 +11,14 @@
 
 The ``DIRECTORY`` argument specifies another directory from which
 to retrieve the property value instead of the current directory.
-It may reference either a source directory, or since CMake 3.19,
-a binary directory.  Relative paths are treated as relative to the
+Relative paths are treated as relative to the
 current source directory.  CMake must already know about the directory,
 either by having added it through a call to :command:`add_subdirectory`
 or being the top level directory.
 
+.. versionadded:: 3.19
+  ``<dir>`` may reference a binary directory.
+
 If the property is not defined for the nominated directory scope,
 an empty string is returned.  In the case of ``INHERITED`` properties,
 if the property is not found for the nominated directory scope,
diff --git a/Help/command/get_filename_component.rst b/Help/command/get_filename_component.rst
index ea2dedb..e073a28 100644
--- a/Help/command/get_filename_component.rst
+++ b/Help/command/get_filename_component.rst
@@ -3,6 +3,11 @@
 
 Get a specific component of a full filename.
 
+.. versionchanged:: 3.19
+  This command been superseded by :command:`cmake_path` command, except
+  ``REALPATH`` now offered by :ref:`file(REAL_PATH) <REAL_PATH>` command and
+  ``PROGRAM`` now available in :command:`separate_arguments(PROGRAM)` command.
+
 .. code-block:: cmake
 
   get_filename_component(<var> <FileName> <mode> [CACHE])
@@ -19,6 +24,9 @@
  NAME_WLE  = File name with neither the directory nor the last extension
  PATH      = Legacy alias for DIRECTORY (use for CMake <= 2.8.11)
 
+.. versionadded:: 3.14
+  Added ``LAST_EXT`` and ``NAME_WLE`` modes.
+
 Paths are returned with forward slashes and have no trailing slashes.
 If the optional ``CACHE`` argument is specified, the result variable is
 added to the cache.
@@ -27,6 +35,8 @@
 
   get_filename_component(<var> <FileName> <mode> [BASE_DIR <dir>] [CACHE])
 
+.. versionadded:: 3.4
+
 Sets ``<var>`` to the absolute path of ``<FileName>``, where ``<mode>`` is one
 of:
 
@@ -53,9 +63,3 @@
 any command-line arguments present in the ``<FileName>`` string are split
 from the program name and stored in ``<arg_var>``.  This is used to
 separate a program name from its arguments in a command line string.
-
-.. note::
-
-  The ``REALPATH`` and ``PROGRAM`` subcommands had been superseded,
-  respectively, by :ref:`file(REAL_PATH) <REAL_PATH>` and
-  :command:`separate_arguments(PROGRAM)` commands.
diff --git a/Help/command/get_property.rst b/Help/command/get_property.rst
index 870c934..9ee7a4b 100644
--- a/Help/command/get_property.rst
+++ b/Help/command/get_property.rst
@@ -30,35 +30,43 @@
 ``DIRECTORY``
   Scope defaults to the current directory but another
   directory (already processed by CMake) may be named by the
-  full or relative path ``<dir>``.  The ``<dir>`` may reference either a
-  source directory, or since CMake 3.19, a binary directory.
+  full or relative path ``<dir>``.
   Relative paths are treated as relative to the current source directory.
   See also the :command:`get_directory_property` command.
 
+  .. versionadded:: 3.19
+    ``<dir>`` may reference a binary directory.
+
 ``TARGET``
   Scope must name one existing target.
   See also the :command:`get_target_property` command.
 
 ``SOURCE``
   Scope must name one source file.  By default, the source file's property
-  will be read from the current source directory's scope, but this can be
-  overridden with one of the following sub-options:
+  will be read from the current source directory's scope.
 
-  ``DIRECTORY <dir>``
-    The source file property will be read from the ``<dir>`` directory's
-    scope.  The ``<dir>`` may reference either a source directory, or
-    since CMake 3.19, a binary directory.  CMake must already know about
-    the directory, either by having added it through a call
-    to :command:`add_subdirectory` or ``<dir>`` being the top level directory.
-    Relative paths are treated as relative to the current source directory.
+  .. versionadded:: 3.18
+    Directory scope can be overridden with one of the following sub-options:
 
-  ``TARGET_DIRECTORY <target>``
-    The source file property will be read from the directory scope in which
-    ``<target>`` was created (``<target>`` must therefore already exist).
+    ``DIRECTORY <dir>``
+      The source file property will be read from the ``<dir>`` directory's
+      scope.  CMake must already know about
+      the directory, either by having added it through a call
+      to :command:`add_subdirectory` or ``<dir>`` being the top level directory.
+      Relative paths are treated as relative to the current source directory.
+
+      .. versionadded:: 3.19
+        ``<dir>`` may reference a binary directory.
+
+    ``TARGET_DIRECTORY <target>``
+      The source file property will be read from the directory scope in which
+      ``<target>`` was created (``<target>`` must therefore already exist).
 
   See also the :command:`get_source_file_property` command.
 
 ``INSTALL``
+  .. versionadded:: 3.1
+
   Scope must name one installed file path.
 
 ``TEST``
diff --git a/Help/command/get_source_file_property.rst b/Help/command/get_source_file_property.rst
index 76ed776..1e0ea9f 100644
--- a/Help/command/get_source_file_property.rst
+++ b/Help/command/get_source_file_property.rst
@@ -19,19 +19,21 @@
 an empty string.
 
 By default, the source file's property will be read from the current source
-directory's scope, but this can be overridden with one of the following
-sub-options:
+directory's scope.
 
-``DIRECTORY <dir>``
-  The source file property will be read from the ``<dir>`` directory's
-  scope.  CMake must already know about that source directory, either by
-  having added it through a call to :command:`add_subdirectory` or ``<dir>``
-  being the top level source directory.  Relative paths are treated as
-  relative to the current source directory.
+.. versionadded:: 3.18
+  Directory scope can be overridden with one of the following sub-options:
 
-``TARGET_DIRECTORY <target>``
-  The source file property will be read from the directory scope in which
-  ``<target>`` was created (``<target>`` must therefore already exist).
+  ``DIRECTORY <dir>``
+    The source file property will be read from the ``<dir>`` directory's
+    scope.  CMake must already know about that source directory, either by
+    having added it through a call to :command:`add_subdirectory` or ``<dir>``
+    being the top level source directory.  Relative paths are treated as
+    relative to the current source directory.
+
+  ``TARGET_DIRECTORY <target>``
+    The source file property will be read from the directory scope in which
+    ``<target>`` was created (``<target>`` must therefore already exist).
 
 Use :command:`set_source_files_properties` to set property values.  Source
 file properties usually control how the file is built. One property that is
diff --git a/Help/command/if.rst b/Help/command/if.rst
index be992df..72d328d 100644
--- a/Help/command/if.rst
+++ b/Help/command/if.rst
@@ -85,8 +85,9 @@
  (in any directory).
 
 ``if(TEST test-name)``
- True if the given name is an existing test name created by the
- :command:`add_test` command.
+ .. versionadded:: 3.3
+  True if the given name is an existing test name created by the
+  :command:`add_test` command.
 
 ``if(EXISTS path-to-file-or-directory)``
  True if the named file or directory exists.  Behavior is well-defined
@@ -116,7 +117,9 @@
 ``if(<variable|string> MATCHES regex)``
  True if the given string or variable's value matches the given regular
  condition.  See :ref:`Regex Specification` for regex format.
- ``()`` groups are captured in :variable:`CMAKE_MATCH_<n>` variables.
+
+ .. versionadded:: 3.9
+  ``()`` groups are captured in :variable:`CMAKE_MATCH_<n>` variables.
 
 ``if(<variable|string> LESS <variable|string>)``
  True if the given string or variable's value is a valid number and less
@@ -131,12 +134,14 @@
  to that on the right.
 
 ``if(<variable|string> LESS_EQUAL <variable|string>)``
- True if the given string or variable's value is a valid number and less
- than or equal to that on the right.
+ .. versionadded:: 3.7
+  True if the given string or variable's value is a valid number and less
+  than or equal to that on the right.
 
 ``if(<variable|string> GREATER_EQUAL <variable|string>)``
- True if the given string or variable's value is a valid number and greater
- than or equal to that on the right.
+ .. versionadded:: 3.7
+  True if the given string or variable's value is a valid number and greater
+  than or equal to that on the right.
 
 ``if(<variable|string> STRLESS <variable|string>)``
  True if the given string or variable's value is lexicographically less
@@ -151,12 +156,14 @@
  to the string or variable on the right.
 
 ``if(<variable|string> STRLESS_EQUAL <variable|string>)``
- True if the given string or variable's value is lexicographically less
- than or equal to the string or variable on the right.
+ .. versionadded:: 3.7
+  True if the given string or variable's value is lexicographically less
+  than or equal to the string or variable on the right.
 
 ``if(<variable|string> STRGREATER_EQUAL <variable|string>)``
- True if the given string or variable's value is lexicographically greater
- than or equal to the string or variable on the right.
+ .. versionadded:: 3.7
+  True if the given string or variable's value is lexicographically greater
+  than or equal to the string or variable on the right.
 
 ``if(<variable|string> VERSION_LESS <variable|string>)``
  Component-wise integer version number comparison (version format is
@@ -177,25 +184,31 @@
  component effectively truncates the string at that point.
 
 ``if(<variable|string> VERSION_LESS_EQUAL <variable|string>)``
- Component-wise integer version number comparison (version format is
- ``major[.minor[.patch[.tweak]]]``, omitted components are treated as zero).
- Any non-integer version component or non-integer trailing part of a version
- component effectively truncates the string at that point.
+ .. versionadded:: 3.7
+  Component-wise integer version number comparison (version format is
+  ``major[.minor[.patch[.tweak]]]``, omitted components are treated as zero).
+  Any non-integer version component or non-integer trailing part of a version
+  component effectively truncates the string at that point.
 
 ``if(<variable|string> VERSION_GREATER_EQUAL <variable|string>)``
- Component-wise integer version number comparison (version format is
- ``major[.minor[.patch[.tweak]]]``, omitted components are treated as zero).
- Any non-integer version component or non-integer trailing part of a version
- component effectively truncates the string at that point.
+ .. versionadded:: 3.7
+  Component-wise integer version number comparison (version format is
+  ``major[.minor[.patch[.tweak]]]``, omitted components are treated as zero).
+  Any non-integer version component or non-integer trailing part of a version
+  component effectively truncates the string at that point.
 
 ``if(<variable|string> IN_LIST <variable>)``
- True if the given element is contained in the named list variable.
+ .. versionadded:: 3.3
+  True if the given element is contained in the named list variable.
 
 ``if(DEFINED <name>|CACHE{<name>}|ENV{<name>})``
  True if a variable, cache variable or environment variable
  with given ``<name>`` is defined. The value of the variable
  does not matter. Note that macro arguments are not variables.
 
+ .. versionadded:: 3.14
+  Added support for ``CACHE{<name>}`` variables.
+
 ``if((condition) AND (condition OR (condition)))``
  The conditions inside the parenthesis are evaluated first and then
  the remaining condition is evaluated as in the previous examples.
@@ -268,11 +281,12 @@
   tested to see if they are boolean constants, if so they are used as
   such, otherwise they are assumed to be variables and are dereferenced.
 
-To prevent ambiguity, potential variable or keyword names can be
-specified in a :ref:`Quoted Argument` or a :ref:`Bracket Argument`.
-A quoted or bracketed variable or keyword will be interpreted as a
-string and not dereferenced or interpreted.
-See policy :policy:`CMP0054`.
+.. versionchanged:: 3.1
+  To prevent ambiguity, potential variable or keyword names can be
+  specified in a :ref:`Quoted Argument` or a :ref:`Bracket Argument`.
+  A quoted or bracketed variable or keyword will be interpreted as a
+  string and not dereferenced or interpreted.
+  See policy :policy:`CMP0054`.
 
 There is no automatic evaluation for environment or cache
 :ref:`Variable References`.  Their values must be referenced as
diff --git a/Help/command/include_external_msproject.rst b/Help/command/include_external_msproject.rst
index 540a13a..4354654 100644
--- a/Help/command/include_external_msproject.rst
+++ b/Help/command/include_external_msproject.rst
@@ -21,6 +21,7 @@
 the target platform.  This is useful for projects requiring values
 other than the default (e.g.  WIX projects).
 
-If the imported project has different configuration names than the
-current project, set the :prop_tgt:`MAP_IMPORTED_CONFIG_<CONFIG>`
-target property to specify the mapping.
+.. versionadded:: 3.9
+  If the imported project has different configuration names than the
+  current project, set the :prop_tgt:`MAP_IMPORTED_CONFIG_<CONFIG>`
+  target property to specify the mapping.
diff --git a/Help/command/install.rst b/Help/command/install.rst
index c11eaf4..bd8da39 100644
--- a/Help/command/install.rst
+++ b/Help/command/install.rst
@@ -20,10 +20,13 @@
 
 This command generates installation rules for a project.  Install rules
 specified by calls to the ``install()`` command within a source directory
-are executed in order during installation.  Install rules in subdirectories
-added by calls to the :command:`add_subdirectory` command are interleaved
-with those in the parent directory to run in the order declared (see
-policy :policy:`CMP0082`).
+are executed in order during installation.
+
+.. versionchanged:: 3.14
+  Install rules in subdirectories
+  added by calls to the :command:`add_subdirectory` command are interleaved
+  with those in the parent directory to run in the order declared (see
+  policy :policy:`CMP0082`).
 
 There are multiple signatures for this command.  Some of them define
 installation options for files and targets.  Options common to
@@ -85,6 +88,8 @@
   :variable:`CMAKE_INSTALL_DEFAULT_COMPONENT_NAME` variable.
 
 ``EXCLUDE_FROM_ALL``
+  .. versionadded:: 3.6
+
   Specify that the file is excluded from a full installation and only
   installed as part of a component-specific installation
 
@@ -97,16 +102,18 @@
   Specify that it is not an error if the file to be installed does
   not exist.
 
-Command signatures that install files may print messages during
-installation.  Use the :variable:`CMAKE_INSTALL_MESSAGE` variable
-to control which messages are printed.
+.. versionadded:: 3.1
+  Command signatures that install files may print messages during
+  installation.  Use the :variable:`CMAKE_INSTALL_MESSAGE` variable
+  to control which messages are printed.
 
-Many of the ``install()`` variants implicitly create the directories
-containing the installed files. If
-:variable:`CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS` is set, these
-directories will be created with the permissions specified. Otherwise,
-they will be created according to the uname rules on Unix-like platforms.
-Windows platforms are unaffected.
+.. versionadded:: 3.11
+  Many of the ``install()`` variants implicitly create the directories
+  containing the installed files. If
+  :variable:`CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS` is set, these
+  directories will be created with the permissions specified. Otherwise,
+  they will be created according to the uname rules on Unix-like platforms.
+  Windows platforms are unaffected.
 
 Installing Targets
 ^^^^^^^^^^^^^^^^^^
@@ -162,6 +169,8 @@
     accompanying import libraries are of kind ``ARCHIVE``).
 
 ``OBJECTS``
+  .. versionadded:: 3.9
+
   Object files associated with *object libraries*.
 
 ``FRAMEWORK``
@@ -246,6 +255,8 @@
 the following additional arguments:
 
 ``NAMELINK_COMPONENT``
+  .. versionadded:: 3.12
+
   On some platforms a versioned shared library has a symbolic link such
   as::
 
@@ -357,17 +368,19 @@
 Installing a target with the :prop_tgt:`EXCLUDE_FROM_ALL` target property
 set to ``TRUE`` has undefined behavior.
 
-`install(TARGETS)`_ can install targets that were created in
-other directories.  When using such cross-directory install rules, running
-``make install`` (or similar) from a subdirectory will not guarantee that
-targets from other directories are up-to-date.  You can use
-:command:`target_link_libraries` or :command:`add_dependencies`
-to ensure that such out-of-directory targets are built before the
-subdirectory-specific install rules are run.
+.. versionadded:: 3.3
+  An install destination given as a ``DESTINATION`` argument may
+  use "generator expressions" with the syntax ``$<...>``.  See the
+  :manual:`cmake-generator-expressions(7)` manual for available expressions.
 
-An install destination given as a ``DESTINATION`` argument may
-use "generator expressions" with the syntax ``$<...>``.  See the
-:manual:`cmake-generator-expressions(7)` manual for available expressions.
+.. versionadded:: 3.13
+  `install(TARGETS)`_ can install targets that were created in
+  other directories.  When using such cross-directory install rules, running
+  ``make install`` (or similar) from a subdirectory will not guarantee that
+  targets from other directories are up-to-date.  You can use
+  :command:`target_link_libraries` or :command:`add_dependencies`
+  to ensure that such out-of-directory targets are built before the
+  subdirectory-specific install rules are run.
 
 Installing Files
 ^^^^^^^^^^^^^^^^
@@ -455,9 +468,10 @@
           DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/myproj
   )
 
-An install destination given as a ``DESTINATION`` argument may
-use "generator expressions" with the syntax ``$<...>``.  See the
-:manual:`cmake-generator-expressions(7)` manual for available expressions.
+.. versionadded:: 3.4
+  An install destination given as a ``DESTINATION`` argument may
+  use "generator expressions" with the syntax ``$<...>``.  See the
+  :manual:`cmake-generator-expressions(7)` manual for available expressions.
 
 Installing Directories
 ^^^^^^^^^^^^^^^^^^^^^^
@@ -495,7 +509,8 @@
 directories will be given the default permissions specified in the
 ``PROGRAMS`` form of the command.
 
-The ``MESSAGE_NEVER`` option disables file installation status output.
+.. versionadded:: 3.1
+  The ``MESSAGE_NEVER`` option disables file installation status output.
 
 Installation of directories may be controlled with fine granularity
 using the ``PATTERN`` or ``REGEX`` options.  These "match" options specify a
@@ -579,10 +594,14 @@
 This allows package maintainers to control the install destination by setting
 the appropriate cache variables.
 
-The list of ``dirs...`` given to ``DIRECTORY`` and an install destination
-given as a ``DESTINATION`` argument may use "generator expressions"
-with the syntax ``$<...>``.  See the :manual:`cmake-generator-expressions(7)`
-manual for available expressions.
+.. versionadded:: 3.4
+  An install destination given as a ``DESTINATION`` argument may
+  use "generator expressions" with the syntax ``$<...>``.  See the
+  :manual:`cmake-generator-expressions(7)` manual for available expressions.
+
+.. versionadded:: 3.5
+  The list of ``dirs...`` given to ``DIRECTORY`` may use
+  "generator expressions" too.
 
 Custom Installation Logic
 ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -610,10 +629,11 @@
 
 will print a message during installation.
 
-``<file>`` or ``<code>`` may use "generator expressions" with the syntax
-``$<...>`` (in the case of ``<file>``, this refers to their use in the file
-name, not the file's contents).  See the
-:manual:`cmake-generator-expressions(7)` manual for available expressions.
+.. versionadded:: 3.14
+  ``<file>`` or ``<code>`` may use "generator expressions" with the syntax
+  ``$<...>`` (in the case of ``<file>``, this refers to their use in the file
+  name, not the file's contents).  See the
+  :manual:`cmake-generator-expressions(7)` manual for available expressions.
 
 Installing Exports
 ^^^^^^^^^^^^^^^^^^
@@ -673,13 +693,14 @@
 of the ``Development`` component in the package metadata, ensuring that the
 library is always installed if the headers and CMake export file are present.
 
-In addition to cmake language files, the ``EXPORT_ANDROID_MK`` mode maybe
-used to specify an export to the android ndk build system.  This mode
-accepts the same options as the normal export mode.  The Android
-NDK supports the use of prebuilt libraries, both static and shared. This
-allows cmake to build the libraries of a project and make them available
-to an ndk build system complete with transitive dependencies, include flags
-and defines required to use the libraries.
+.. versionadded:: 3.7
+  In addition to cmake language files, the ``EXPORT_ANDROID_MK`` mode maybe
+  used to specify an export to the android ndk build system.  This mode
+  accepts the same options as the normal export mode.  The Android
+  NDK supports the use of prebuilt libraries, both static and shared. This
+  allows cmake to build the libraries of a project and make them available
+  to an ndk build system complete with transitive dependencies, include flags
+  and defines required to use the libraries.
 
 The ``EXPORT`` form is useful to help outside projects use targets built
 and installed by the current project.  For example, the code
diff --git a/Help/command/link_directories.rst b/Help/command/link_directories.rst
index 9cb8faa..6732402 100644
--- a/Help/command/link_directories.rst
+++ b/Help/command/link_directories.rst
@@ -11,21 +11,25 @@
 Relative paths given to this command are interpreted as relative to
 the current source directory, see :policy:`CMP0015`.
 
-The directories are added to the :prop_dir:`LINK_DIRECTORIES` directory
-property for the current ``CMakeLists.txt`` file, converting relative
-paths to absolute as needed.
 The command will apply only to targets created after it is called.
 
-By default the directories specified are appended onto the current list of
-directories.  This default behavior can be changed by setting
-:variable:`CMAKE_LINK_DIRECTORIES_BEFORE` to ``ON``.  By using
-``AFTER`` or ``BEFORE`` explicitly, you can select between appending and
-prepending, independent of the default.
+.. versionadded:: 3.13
+  The directories are added to the :prop_dir:`LINK_DIRECTORIES` directory
+  property for the current ``CMakeLists.txt`` file, converting relative
+  paths to absolute as needed.  See the :manual:`cmake-buildsystem(7)`
+  manual for more on defining buildsystem properties.
 
-Arguments to ``link_directories`` may use "generator expressions" with
-the syntax "$<...>".  See the :manual:`cmake-generator-expressions(7)`
-manual for available expressions.  See the :manual:`cmake-buildsystem(7)`
-manual for more on defining buildsystem properties.
+.. versionadded:: 3.13
+  By default the directories specified are appended onto the current list of
+  directories.  This default behavior can be changed by setting
+  :variable:`CMAKE_LINK_DIRECTORIES_BEFORE` to ``ON``.  By using
+  ``AFTER`` or ``BEFORE`` explicitly, you can select between appending and
+  prepending, independent of the default.
+
+.. versionadded:: 3.13
+  Arguments to ``link_directories`` may use "generator expressions" with
+  the syntax "$<...>".  See the :manual:`cmake-generator-expressions(7)`
+  manual for available expressions.
 
 .. note::
 
diff --git a/Help/command/list.rst b/Help/command/list.rst
index 4d339a0..ee3530c 100644
--- a/Help/command/list.rst
+++ b/Help/command/list.rst
@@ -88,6 +88,8 @@
 
   list(JOIN <list> <glue> <output variable>)
 
+.. versionadded:: 3.12
+
 Returns a string joining all list's elements using the glue string.
 To join multiple strings, which are not part of a list, use ``JOIN`` operator
 from :command:`string` command.
@@ -98,6 +100,8 @@
 
   list(SUBLIST <list> <begin> <length> <output variable>)
 
+.. versionadded:: 3.12
+
 Returns a sublist of the given list.
 If ``<length>`` is 0, an empty list will be returned.
 If ``<length>`` is -1 or the list is smaller than ``<begin>+<length>`` then
@@ -132,6 +136,8 @@
 
   list(FILTER <list> <INCLUDE|EXCLUDE> REGEX <regular_expression>)
 
+.. versionadded:: 3.6
+
 Includes or removes items from the list that match the mode's pattern.
 In ``REGEX`` mode, items will be matched against the given regular expression.
 
@@ -152,6 +158,8 @@
 
   list(POP_BACK <list> [<out-var>...])
 
+.. versionadded:: 3.15
+
 If no variable name is given, removes exactly one element. Otherwise,
 assign the last element's value to the given variable and removes it,
 up to the last variable name given.
@@ -162,6 +170,8 @@
 
   list(POP_FRONT <list> [<out-var>...])
 
+.. versionadded:: 3.15
+
 If no variable name is given, removes exactly one element. Otherwise,
 assign the first element's value to the given variable and removes it,
 up to the last variable name given.
@@ -172,6 +182,8 @@
 
   list(PREPEND <list> [<element> ...])
 
+.. versionadded:: 3.15
+
 Insert elements to the 0th position in the list.
 
 .. _REMOVE_ITEM:
@@ -206,6 +218,8 @@
   list(TRANSFORM <list> <ACTION> [<SELECTOR>]
                         [OUTPUT_VARIABLE <output variable>])
 
+.. versionadded:: 3.12
+
 Transforms the list by applying an action to all or, by specifying a
 ``<SELECTOR>``, to the selected elements of the list, storing the result
 in-place or in the specified output variable.
@@ -302,6 +316,13 @@
   list(SORT <list> [COMPARE <compare>] [CASE <case>] [ORDER <order>])
 
 Sorts the list in-place alphabetically.
+
+.. versionadded:: 3.13
+  Added ``COMPARE``, ``CASE``, and ``ORDER`` options.
+
+.. versionadded:: 3.18
+  Added ``COMPARE NATURAL`` option.
+
 Use the ``COMPARE`` keyword to select the comparison method for sorting.
 The ``<compare>`` option should be one of:
 
diff --git a/Help/command/macro.rst b/Help/command/macro.rst
index 797a90d..5fe4c00 100644
--- a/Help/command/macro.rst
+++ b/Help/command/macro.rst
@@ -48,8 +48,9 @@
 case chosen in the macro definition.  Typically macros use
 all-lowercase names.
 
-The :command:`cmake_language(CALL ...)` command can also be used to
-invoke the macro.
+.. versionadded:: 3.18
+  The :command:`cmake_language(CALL ...)` command can also be used to
+  invoke the macro.
 
 Arguments
 ^^^^^^^^^
diff --git a/Help/command/mark_as_advanced.rst b/Help/command/mark_as_advanced.rst
index e52e623..201363f 100644
--- a/Help/command/mark_as_advanced.rst
+++ b/Help/command/mark_as_advanced.rst
@@ -23,8 +23,6 @@
 variable already has an advanced/non-advanced state,
 it will not be changed.
 
-.. note::
-
-  Policy :policy:`CMP0102` affects the behavior of the ``mark_as_advanced``
-  call. When set to ``NEW``, variables passed to this command which are not
-  already in the cache are ignored. See policy :policy:`CMP0102`.
+.. versionchanged:: 3.17
+  Variables passed to this command which are not already in the cache
+  are ignored. See policy :policy:`CMP0102`.
diff --git a/Help/command/math.rst b/Help/command/math.rst
index ddb1ec6..8386aab 100644
--- a/Help/command/math.rst
+++ b/Help/command/math.rst
@@ -17,17 +17,18 @@
 ``^``, ``~``, ``<<``, ``>>``, and ``(...)``; they have the same meaning
 as in C code.
 
-Hexadecimal numbers are recognized when prefixed with ``0x``, as in C code.
+.. versionadded:: 3.13
+  Hexadecimal numbers are recognized when prefixed with ``0x``, as in C code.
 
-The result is formatted according to the option ``OUTPUT_FORMAT``,
-where ``<format>`` is one of
+.. versionadded:: 3.13
+  The result is formatted according to the option ``OUTPUT_FORMAT``,
+  where ``<format>`` is one of
 
-``HEXADECIMAL``
-  Hexadecimal notation as in C code, i. e. starting with "0x".
-``DECIMAL``
-  Decimal notation. Which is also used if no ``OUTPUT_FORMAT`` option
-  is specified.
-
+  ``HEXADECIMAL``
+    Hexadecimal notation as in C code, i. e. starting with "0x".
+  ``DECIMAL``
+    Decimal notation. Which is also used if no ``OUTPUT_FORMAT`` option
+    is specified.
 
 For example
 
diff --git a/Help/command/message.rst b/Help/command/message.rst
index 6bc0e4c..3ea82a6 100644
--- a/Help/command/message.rst
+++ b/Help/command/message.rst
@@ -71,6 +71,9 @@
   using this log level would normally only be temporary and would expect to be
   removed before releasing the project, packaging up the files, etc.
 
+.. versionadded:: 3.15
+  Added ``NOTICE``, ``VERBOSE``, ``DEBUG``, and ``TRACE`` levels.
+
 The CMake command-line tool displays ``STATUS`` to ``TRACE`` messages on stdout
 with the message preceded by two hyphens and a space.  All other message types
 are sent to stderr and are not prefixed with hyphens.  The
@@ -79,25 +82,29 @@
 messages one at a time on a status line and other messages in an
 interactive pop-up box.  The ``--log-level`` command-line option to each of
 these tools can be used to control which messages will be shown.
-To make a log level persist between CMake runs, the
-:variable:`CMAKE_MESSAGE_LOG_LEVEL` variable can be set instead.
-Note that the command line option takes precedence over the cache variable.
 
-Messages of log levels ``NOTICE`` and below will have each line preceded
-by the content of the :variable:`CMAKE_MESSAGE_INDENT` variable (converted to
-a single string by concatenating its list items).  For ``STATUS`` to ``TRACE``
-messages, this indenting content will be inserted after the hyphens.
+.. versionadded:: 3.17
+  To make a log level persist between CMake runs, the
+  :variable:`CMAKE_MESSAGE_LOG_LEVEL` variable can be set instead.
+  Note that the command line option takes precedence over the cache variable.
 
-Messages of log levels ``NOTICE`` and below can also have each line preceded
-with context of the form ``[some.context.example]``.  The content between the
-square brackets is obtained by converting the :variable:`CMAKE_MESSAGE_CONTEXT`
-list variable to a dot-separated string.  The message context will always
-appear before any indenting content but after any automatically added leading
-hyphens. By default, message context is not shown, it has to be explicitly
-enabled by giving the :manual:`cmake <cmake(1)>` ``--log-context``
-command-line option or by setting the :variable:`CMAKE_MESSAGE_CONTEXT_SHOW`
-variable to true.  See the :variable:`CMAKE_MESSAGE_CONTEXT` documentation for
-usage examples.
+.. versionadded:: 3.16
+  Messages of log levels ``NOTICE`` and below will have each line preceded
+  by the content of the :variable:`CMAKE_MESSAGE_INDENT` variable (converted to
+  a single string by concatenating its list items).  For ``STATUS`` to ``TRACE``
+  messages, this indenting content will be inserted after the hyphens.
+
+.. versionadded:: 3.17
+  Messages of log levels ``NOTICE`` and below can also have each line preceded
+  with context of the form ``[some.context.example]``.  The content between the
+  square brackets is obtained by converting the :variable:`CMAKE_MESSAGE_CONTEXT`
+  list variable to a dot-separated string.  The message context will always
+  appear before any indenting content but after any automatically added leading
+  hyphens. By default, message context is not shown, it has to be explicitly
+  enabled by giving the :manual:`cmake <cmake(1)>` ``--log-context``
+  command-line option or by setting the :variable:`CMAKE_MESSAGE_CONTEXT_SHOW`
+  variable to true.  See the :variable:`CMAKE_MESSAGE_CONTEXT` documentation for
+  usage examples.
 
 CMake Warning and Error message text displays using a simple markup
 language.  Non-indented text is formatted in line-wrapped paragraphs
@@ -107,6 +114,8 @@
 Reporting checks
 ^^^^^^^^^^^^^^^^
 
+.. versionadded:: 3.17
+
 A common pattern in CMake output is a message indicating the start of some
 sort of check, followed by another message reporting the result of that check.
 For example:
diff --git a/Help/command/project.rst b/Help/command/project.rst
index c325050..d3454cc 100644
--- a/Help/command/project.rst
+++ b/Help/command/project.rst
@@ -55,10 +55,14 @@
   * :variable:`PROJECT_VERSION_TWEAK`,
     :variable:`<PROJECT-NAME>_VERSION_TWEAK`.
 
-  When the ``project()`` command is called from the top-level ``CMakeLists.txt``,
-  then the version is also stored in the variable :variable:`CMAKE_PROJECT_VERSION`.
+  .. versionadded:: 3.12
+    When the ``project()`` command is called from the top-level
+    ``CMakeLists.txt``, then the version is also stored in the variable
+    :variable:`CMAKE_PROJECT_VERSION`.
 
 ``DESCRIPTION <project-description-string>``
+  .. versionadded:: 3.9
+
   Optional.
   Sets the variables
 
@@ -71,7 +75,12 @@
   When the ``project()`` command is called from the top-level ``CMakeLists.txt``,
   then the description is also stored in the variable :variable:`CMAKE_PROJECT_DESCRIPTION`.
 
+  .. versionadded:: 3.12
+    Added ``<PROJECT-NAME>_DESCRIPTION`` variable.
+
 ``HOMEPAGE_URL <url-string>``
+  .. versionadded:: 3.12
+
   Optional.
   Sets the variables
 
@@ -93,6 +102,15 @@
   Specify language ``NONE``, or use the ``LANGUAGES`` keyword and list no languages,
   to skip enabling any languages.
 
+  .. versionadded:: 3.8
+    Added ``CUDA`` support.
+
+  .. versionadded:: 3.16
+    Added ``OBJC`` and ``OBJCXX`` support.
+
+  .. versionadded:: 3.18
+    Added ``ISPC`` support.
+
   If enabling ``ASM``, list it last so that CMake can check whether
   compilers for other languages like ``C`` work for assembly too.
 
@@ -102,6 +120,8 @@
 Code Injection
 ^^^^^^^^^^^^^^
 
+.. versionadded:: 3.15
+
 If the :variable:`CMAKE_PROJECT_INCLUDE_BEFORE` or
 :variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE_BEFORE` variables are set,
 the files they point to will be included as the first step of the
@@ -115,6 +135,9 @@
 If both are set, then :variable:`CMAKE_PROJECT_INCLUDE` will be included before
 :variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE`.
 
+.. versionadded:: 3.17
+  Added ``CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE_BEFORE`` variable.
+
 Usage
 ^^^^^
 
diff --git a/Help/command/separate_arguments.rst b/Help/command/separate_arguments.rst
index 69fb726..f66af35 100644
--- a/Help/command/separate_arguments.rst
+++ b/Help/command/separate_arguments.rst
@@ -32,10 +32,14 @@
   MSDN article `Parsing C Command-Line Arguments`_ for details.
 
 ``NATIVE_COMMAND``
+  .. versionadded:: 3.9
+
   Proceeds as in ``WINDOWS_COMMAND`` mode if the host system is Windows.
   Otherwise proceeds as in ``UNIX_COMMAND`` mode.
 
 ``PROGRAM``
+  .. versionadded:: 3.19
+
   The first item in ``<args>`` is assumed to be an executable and will be
   searched in the system search path or left as a full path. If not found,
   ``<variable>`` will be empty. Otherwise, ``<variable>`` is a list of 2
diff --git a/Help/command/set_property.rst b/Help/command/set_property.rst
index b5c1613..22e0301 100644
--- a/Help/command/set_property.rst
+++ b/Help/command/set_property.rst
@@ -28,11 +28,12 @@
 ``DIRECTORY``
   Scope defaults to the current directory but other directories
   (already processed by CMake) may be named by full or relative path.
-  Each path may reference either a source directory, or since CMake 3.19,
-  a binary directory.
   Relative paths are treated as relative to the current source directory.
   See also the :command:`set_directory_properties` command.
 
+  .. versionadded:: 3.19
+    ``<dir>`` may reference a binary directory.
+
 ``TARGET``
   Scope may name zero or more existing targets.
   See also the :command:`set_target_properties` command.
@@ -40,25 +41,31 @@
 ``SOURCE``
   Scope may name zero or more source files.  By default, source file properties
   are only visible to targets added in the same directory (``CMakeLists.txt``).
-  Visibility can be set in other directory scopes using one or both of the
-  following sub-options:
 
-  ``DIRECTORY <dirs>...``
-    The source file property will be set in each of the ``<dirs>``
-    directories' scopes.  Each path may reference either a source directory,
-    or since CMake 3.19, a binary directory.  CMake must already know about
-    each of these directories, either by having added them through a call to
-    :command:`add_subdirectory` or it being the top level source directory.
-    Relative paths are treated as relative to the current source directory.
+  .. versionadded:: 3.18
+    Visibility can be set in other directory scopes using one or both of the
+    following sub-options:
 
-  ``TARGET_DIRECTORY <targets>...``
-    The source file property will be set in each of the directory scopes
-    where any of the specified ``<targets>`` were created (the ``<targets>``
-    must therefore already exist).
+    ``DIRECTORY <dirs>...``
+      The source file property will be set in each of the ``<dirs>``
+      directories' scopes.  CMake must already know about
+      each of these directories, either by having added them through a call to
+      :command:`add_subdirectory` or it being the top level source directory.
+      Relative paths are treated as relative to the current source directory.
+
+      .. versionadded:: 3.19
+        ``<dirs>`` may reference a binary directory.
+
+    ``TARGET_DIRECTORY <targets>...``
+      The source file property will be set in each of the directory scopes
+      where any of the specified ``<targets>`` were created (the ``<targets>``
+      must therefore already exist).
 
   See also the :command:`set_source_files_properties` command.
 
 ``INSTALL``
+  .. versionadded:: 3.1
+
   Scope may name zero or more installed file paths.
   These are made available to CPack to influence deployment.
 
diff --git a/Help/command/set_source_files_properties.rst b/Help/command/set_source_files_properties.rst
index 9558b40..f8b05ac 100644
--- a/Help/command/set_source_files_properties.rst
+++ b/Help/command/set_source_files_properties.rst
@@ -14,9 +14,10 @@
 Sets properties associated with source files using a key/value paired
 list.
 
-By default, source file properties are only visible to targets added in the
-same directory (``CMakeLists.txt``).  Visibility can be set in other directory
-scopes using one or both of the following options:
+.. versionadded:: 3.18
+  By default, source file properties are only visible to targets added in the
+  same directory (``CMakeLists.txt``).  Visibility can be set in other directory
+  scopes using one or both of the following options:
 
 ``DIRECTORY <dirs>...``
   The source file properties will be set in each of the ``<dirs>``
diff --git a/Help/command/site_name.rst b/Help/command/site_name.rst
index 1bcaead..09b5a9f 100644
--- a/Help/command/site_name.rst
+++ b/Help/command/site_name.rst
@@ -6,3 +6,7 @@
 .. code-block:: cmake
 
   site_name(variable)
+
+On UNIX-like platforms, if the variable ``HOSTNAME`` is set, its value
+will be executed as a command expected to print out the host name,
+much like the ``hostname`` command-line tool.
diff --git a/Help/command/source_group.rst b/Help/command/source_group.rst
index 5ae9e51..5db1ec8 100644
--- a/Help/command/source_group.rst
+++ b/Help/command/source_group.rst
@@ -14,12 +14,16 @@
 The options are:
 
 ``TREE``
+ .. versionadded:: 3.8
+
  CMake will automatically detect, from ``<src>`` files paths, source groups
  it needs to create, to keep structure of source groups analogically to the
  actual files and directories structure in the project. Paths of ``<src>``
  files will be cut to be relative to ``<root>``.
 
 ``PREFIX``
+ .. versionadded:: 3.8
+
  Source group and files located directly in ``<root>`` path, will be placed
  in ``<prefix>`` source groups.
 
@@ -47,6 +51,9 @@
   source_group(outer\\inner ...)
   source_group(TREE <root> PREFIX sources\\inc ...)
 
+.. versionadded:: 3.18
+  Allow using forward slashes (``/``) to specify subgroups.
+
 For backwards compatibility, the short-hand signature
 
 .. code-block:: cmake
diff --git a/Help/command/string.rst b/Help/command/string.rst
index 51f8d82..178d9d3 100644
--- a/Help/command/string.rst
+++ b/Help/command/string.rst
@@ -170,10 +170,12 @@
   Matches a pattern on either side of the ``|``
 ``()``
   Saves a matched subexpression, which can be referenced
-  in the ``REGEX REPLACE`` operation. Additionally it is saved
-  by all regular expression-related commands, including
-  e.g. :command:`if(MATCHES)`, in the variables
-  :variable:`CMAKE_MATCH_<n>` for ``<n>`` 0..9.
+  in the ``REGEX REPLACE`` operation.
+
+  .. versionadded:: 3.9
+    All regular expression-related commands, including e.g.
+    :command:`if(MATCHES)`, save subgroup matches in the variables
+    :variable:`CMAKE_MATCH_<n>` for ``<n>`` 0..9.
 
 ``*``, ``+`` and ``?`` have higher precedence than concatenation.  ``|``
 has lower precedence than concatenation.  This means that the regular
@@ -205,6 +207,8 @@
 
   string(APPEND <string_variable> [<input>...])
 
+.. versionadded:: 3.4
+
 Append all the ``<input>`` arguments to the string.
 
 .. _PREPEND:
@@ -213,6 +217,8 @@
 
   string(PREPEND <string_variable> [<input>...])
 
+.. versionadded:: 3.10
+
 Prepend all the ``<input>`` arguments to the string.
 
 .. _CONCAT:
@@ -230,6 +236,8 @@
 
   string(JOIN <glue> <output_variable> [<input>...])
 
+.. versionadded:: 3.12
+
 Join all the ``<input>`` arguments together using the ``<glue>``
 string and store the result in the named ``<output_variable>``.
 
@@ -271,16 +279,15 @@
 
 Store in an ``<output_variable>`` a substring of a given ``<string>``.  If
 ``<length>`` is ``-1`` the remainder of the string starting at ``<begin>``
-will be returned.  If ``<string>`` is shorter than ``<length>`` then the
-end of the string is used instead.
+will be returned.
+
+.. versionchanged:: 3.2
+  If ``<string>`` is shorter than ``<length>`` then the end of the string
+  is used instead.  Previous versions of CMake reported an error in this case.
 
 Both ``<begin>`` and ``<length>`` are counted in bytes, so care must
 be exercised if ``<string>`` could contain multi-byte characters.
 
-.. note::
-  CMake 3.1 and below reported an error if ``<length>`` pointed past
-  the end of ``<string>``.
-
 .. _STRIP:
 
 .. code-block:: cmake
@@ -296,6 +303,8 @@
 
   string(GENEX_STRIP <string> <output_variable>)
 
+.. versionadded:: 3.1
+
 Strip any :manual:`generator expressions <cmake-generator-expressions(7)>`
 from the input ``<string>`` and store the result in the ``<output_variable>``.
 
@@ -305,6 +314,8 @@
 
   string(REPEAT <string> <count> <output_variable>)
 
+.. versionadded:: 3.15
+
 Produce the output string as the input ``<string>`` repeated ``<count>`` times.
 
 Comparison
@@ -323,6 +334,9 @@
 
 Compare the strings and store true or false in the ``<output_variable>``.
 
+.. versionadded:: 3.7
+  Added ``LESS_EQUAL`` and ``GREATER_EQUAL`` options.
+
 .. _`Supported Hash Algorithms`:
 
 Hashing
@@ -358,6 +372,9 @@
 ``SHA3_512``
   Keccak SHA-3.
 
+.. versionadded:: 3.8
+  Added ``SHA3`` hash algorithms.
+
 Generation
 ^^^^^^^^^^
 
@@ -375,6 +392,8 @@
 
   string(HEX <string> <output_variable>)
 
+.. versionadded:: 3.18
+
 Convert each byte in the input ``<string>`` to its hexadecimal representation
 and store the concatenated hex digits in the ``<output_variable>``. Letters in
 the output (``a`` through ``f``) are in lowercase.
@@ -451,6 +470,18 @@
    %y        The last two digits of the current year (00-99)
    %Y        The current year.
 
+.. versionadded:: 3.6
+  ``%s`` format specifier (UNIX time).
+
+.. versionadded:: 3.7
+  ``%a`` and ``%b`` format specifiers (abbreviated month and weekday names).
+
+.. versionadded:: 3.8
+  ``%%`` specifier (literal ``%``).
+
+.. versionadded:: 3.7
+  ``%A`` and ``%B`` format specifiers (full month and weekday names).
+
 Unknown format specifiers will be ignored and copied to the output
 as-is.
 
@@ -461,8 +492,7 @@
    %Y-%m-%dT%H:%M:%S    for local time.
    %Y-%m-%dT%H:%M:%SZ   for UTC.
 
-.. note::
-
+.. versionadded:: 3.8
   If the ``SOURCE_DATE_EPOCH`` environment variable is set,
   its value will be used instead of the current time.
   See https://reproducible-builds.org/specs/source-date-epoch/ for details.
@@ -474,6 +504,8 @@
   string(UUID <output_variable> NAMESPACE <namespace> NAME <name>
          TYPE <MD5|SHA1> [UPPER])
 
+.. versionadded:: 3.1
+
 Create a universally unique identifier (aka GUID) as per RFC4122
 based on the hash of the combined values of ``<namespace>``
 (which itself has to be a valid UUID) and ``<name>``.
@@ -489,6 +521,8 @@
 JSON
 ^^^^
 
+.. versionadded:: 3.19
+
 Functionality for querying a JSON string.
 
 .. note::
diff --git a/Help/command/target_compile_definitions.rst b/Help/command/target_compile_definitions.rst
index 9e9c690..09e2ded 100644
--- a/Help/command/target_compile_definitions.rst
+++ b/Help/command/target_compile_definitions.rst
@@ -19,10 +19,12 @@
 items will populate the :prop_tgt:`COMPILE_DEFINITIONS` property of
 ``<target>``. ``PUBLIC`` and ``INTERFACE`` items will populate the
 :prop_tgt:`INTERFACE_COMPILE_DEFINITIONS` property of ``<target>``.
-(:ref:`IMPORTED targets <Imported Targets>` only support ``INTERFACE`` items.)
 The following arguments specify compile definitions.  Repeated calls for the
 same ``<target>`` append items in the order called.
 
+.. versionadded:: 3.11
+  Allow setting ``INTERFACE`` items on :ref:`IMPORTED targets <Imported Targets>`.
+
 Arguments to ``target_compile_definitions`` may use "generator expressions"
 with the syntax ``$<...>``.  See the :manual:`cmake-generator-expressions(7)`
 manual for available expressions.  See the :manual:`cmake-buildsystem(7)`
diff --git a/Help/command/target_compile_features.rst b/Help/command/target_compile_features.rst
index b50be34..58502bf 100644
--- a/Help/command/target_compile_features.rst
+++ b/Help/command/target_compile_features.rst
@@ -21,9 +21,11 @@
 populate the :prop_tgt:`COMPILE_FEATURES` property of ``<target>``.
 ``PUBLIC`` and ``INTERFACE`` items will populate the
 :prop_tgt:`INTERFACE_COMPILE_FEATURES` property of ``<target>``.
-(:ref:`IMPORTED targets <Imported Targets>` only support ``INTERFACE`` items.)
 Repeated calls for the same ``<target>`` append items.
 
+.. versionadded:: 3.11
+  Allow setting ``INTERFACE`` items on :ref:`IMPORTED targets <Imported Targets>`.
+
 The named ``<target>`` must have been created by a command such as
 :command:`add_executable` or :command:`add_library` and must not be an
 :ref:`ALIAS target <Alias Targets>`.
diff --git a/Help/command/target_compile_options.rst b/Help/command/target_compile_options.rst
index 3c733c5..e45b209 100644
--- a/Help/command/target_compile_options.rst
+++ b/Help/command/target_compile_options.rst
@@ -26,10 +26,12 @@
 items will populate the :prop_tgt:`COMPILE_OPTIONS` property of
 ``<target>``.  ``PUBLIC`` and ``INTERFACE`` items will populate the
 :prop_tgt:`INTERFACE_COMPILE_OPTIONS` property of ``<target>``.
-(:ref:`IMPORTED targets <Imported Targets>` only support ``INTERFACE`` items.)
 The following arguments specify compile options.  Repeated calls for the same
 ``<target>`` append items in the order called.
 
+.. versionadded:: 3.11
+  Allow setting ``INTERFACE`` items on :ref:`IMPORTED targets <Imported Targets>`.
+
 Arguments to ``target_compile_options`` may use "generator expressions"
 with the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)`
 manual for available expressions.  See the :manual:`cmake-buildsystem(7)`
diff --git a/Help/command/target_include_directories.rst b/Help/command/target_include_directories.rst
index 660e15c..a8a5c83 100644
--- a/Help/command/target_include_directories.rst
+++ b/Help/command/target_include_directories.rst
@@ -22,9 +22,11 @@
 populate the :prop_tgt:`INCLUDE_DIRECTORIES` property of ``<target>``.
 ``PUBLIC`` and ``INTERFACE`` items will populate the
 :prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` property of ``<target>``.
-(:ref:`IMPORTED targets <Imported Targets>` only support ``INTERFACE`` items.)
 The following arguments specify include directories.
 
+.. versionadded:: 3.11
+  Allow setting ``INTERFACE`` items on :ref:`IMPORTED targets <Imported Targets>`.
+
 Specified include directories may be absolute paths or relative paths.
 Repeated calls for the same <target> append items in the order called.  If
 ``SYSTEM`` is specified, the compiler will be told the
diff --git a/Help/command/target_link_libraries.rst b/Help/command/target_link_libraries.rst
index c2e7e8a..872e264 100644
--- a/Help/command/target_link_libraries.rst
+++ b/Help/command/target_link_libraries.rst
@@ -27,6 +27,10 @@
 directory.  Repeated calls for the same ``<target>`` append items in
 the order called.
 
+.. versionadded:: 3.13
+  The ``<target>`` doesn't have to be defined in the same directory as the
+  ``target_link_libraries`` call.
+
 Each ``<item>`` may be:
 
 * **A library target name**: The generated link line will have the
@@ -62,10 +66,11 @@
   :ref:`usage requirement <Target Usage Requirements>`.  This has the same
   effect as passing the framework directory as an include directory.
 
-  On :ref:`Visual Studio Generators` for VS 2010 and above, library files
-  ending in ``.targets`` will be treated as MSBuild targets files and
-  imported into generated project files.  This is not supported by other
-  generators.
+  .. versionadded:: 3.8
+    On :ref:`Visual Studio Generators` for VS 2010 and above, library files
+    ending in ``.targets`` will be treated as MSBuild targets files and
+    imported into generated project files.  This is not supported by other
+    generators.
 
   The full path to the library file will be quoted/escaped for
   the shell automatically.
@@ -89,6 +94,11 @@
   flags explicitly. The flags will then be placed at the toolchain-defined
   flag position in the link command.
 
+  .. versionadded:: 3.13
+    :prop_tgt:`LINK_OPTIONS` target property and :command:`target_link_options`
+    command.  For earlier versions of CMake, use :prop_tgt:`LINK_FLAGS`
+    property instead.
+
   The link flag is treated as a command-line string fragment and
   will be used with no extra quoting or escaping.
 
@@ -216,6 +226,8 @@
 Linking Object Libraries
 ^^^^^^^^^^^^^^^^^^^^^^^^
 
+.. versionadded:: 3.12
+
 :ref:`Object Libraries` may be used as the ``<target>`` (first) argument
 of ``target_link_libraries`` to specify dependencies of their sources
 on other libraries.  For example, the code
diff --git a/Help/command/target_link_options.rst b/Help/command/target_link_options.rst
index e59e0e1..87dff39 100644
--- a/Help/command/target_link_options.rst
+++ b/Help/command/target_link_options.rst
@@ -36,10 +36,12 @@
 items will populate the :prop_tgt:`LINK_OPTIONS` property of
 ``<target>``.  ``PUBLIC`` and ``INTERFACE`` items will populate the
 :prop_tgt:`INTERFACE_LINK_OPTIONS` property of ``<target>``.
-(:ref:`IMPORTED targets <Imported Targets>` only support ``INTERFACE`` items.)
 The following arguments specify link options.  Repeated calls for the same
 ``<target>`` append items in the order called.
 
+.. note::
+  :ref:`IMPORTED targets <Imported Targets>` only support ``INTERFACE`` items.
+
 Arguments to ``target_link_options`` may use "generator expressions"
 with the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)`
 manual for available expressions.  See the :manual:`cmake-buildsystem(7)`
diff --git a/Help/command/target_sources.rst b/Help/command/target_sources.rst
index 653b8d7..520614a 100644
--- a/Help/command/target_sources.rst
+++ b/Help/command/target_sources.rst
@@ -12,27 +12,37 @@
     [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
 
 Specifies sources to use when building a target and/or its dependents.
-Relative source file paths are interpreted as being relative to the current
-source directory (i.e. :variable:`CMAKE_CURRENT_SOURCE_DIR`).  The
-named ``<target>`` must have been created by a command such as
-:command:`add_executable` or :command:`add_library` and must not be an
+The named ``<target>`` must have been created by a command such as
+:command:`add_executable` or :command:`add_library` or
+:command:`add_custom_target` and must not be an
 :ref:`ALIAS target <Alias Targets>`.
 
+.. versionchanged:: 3.13
+  Relative source file paths are interpreted as being relative to the current
+  source directory (i.e. :variable:`CMAKE_CURRENT_SOURCE_DIR`).
+  See policy :policy:`CMP0076`.
+
+.. versionadded:: 3.20
+  ``<target>`` can be a custom target.
+
 The ``INTERFACE``, ``PUBLIC`` and ``PRIVATE`` keywords are required to
 specify the scope of the items following them.  ``PRIVATE`` and ``PUBLIC``
 items will populate the :prop_tgt:`SOURCES` property of
 ``<target>``, which are used when building the target itself.
 ``PUBLIC`` and ``INTERFACE`` items will populate the
 :prop_tgt:`INTERFACE_SOURCES` property of ``<target>``, which are used
-when building dependents.  (:ref:`IMPORTED targets <Imported Targets>`
-only support ``INTERFACE`` items because they are not build targets.)
+when building dependents.
 The following arguments specify sources.  Repeated calls for the same
-``<target>`` append items in the order called.
+``<target>`` append items in the order called. The targets created by
+:command:`add_custom_target` can only have ``PRIVATE`` scope.
+
+.. versionadded:: 3.3
+  Allow exporting targets with :prop_tgt:`INTERFACE_SOURCES`.
+
+.. versionadded:: 3.11
+  Allow setting ``INTERFACE`` items on :ref:`IMPORTED targets <Imported Targets>`.
 
 Arguments to ``target_sources`` may use "generator expressions"
 with the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)`
 manual for available expressions.  See the :manual:`cmake-buildsystem(7)`
 manual for more on defining buildsystem properties.
-
-See also the :policy:`CMP0076` policy for older behavior related to the
-handling of relative source file paths.
diff --git a/Help/command/try_compile.rst b/Help/command/try_compile.rst
index 323077a..06da910 100644
--- a/Help/command/try_compile.rst
+++ b/Help/command/try_compile.rst
@@ -19,6 +19,10 @@
 Try building a project.  The success or failure of the ``try_compile``,
 i.e. ``TRUE`` or ``FALSE`` respectively, is returned in ``<resultVar>``.
 
+.. versionadded:: 3.14
+  The name of the ``<resultVar>`` is defined by the user.  Previously, it had
+  a fixed name ``RESULT_VAR``.
+
 In this form, ``<srcdir>`` should contain a complete CMake project with a
 ``CMakeLists.txt`` file and all sources.  The ``<bindir>`` and ``<srcdir>``
 will not be deleted after this command is run.  Specify ``<targetName>`` to
@@ -47,6 +51,10 @@
 variable).  The success or failure of the ``try_compile``, i.e. ``TRUE`` or
 ``FALSE`` respectively, is returned in ``<resultVar>``.
 
+.. versionadded:: 3.14
+  The name of the ``<resultVar>`` is defined by the user.  Previously, it had
+  a fixed name ``RESULT_VAR``.
+
 In this form, one or more source files must be provided.  If
 :variable:`CMAKE_TRY_COMPILE_TARGET_TYPE` is unset or is set to ``EXECUTABLE``,
 the sources must include a definition for ``main`` and CMake will create a
@@ -94,6 +102,8 @@
   given to the ``CMAKE_FLAGS`` option will be ignored.
 
 ``LINK_OPTIONS <options>...``
+  .. versionadded:: 3.14
+
   Specify link step options to pass to :command:`target_link_options` or to
   set the :prop_tgt:`STATIC_LIBRARY_OPTIONS` target property in the generated
   project, depending on the :variable:`CMAKE_TRY_COMPILE_TARGET_TYPE` variable.
@@ -102,17 +112,23 @@
   Store the output from the build process in the given variable.
 
 ``<LANG>_STANDARD <std>``
+  .. versionadded:: 3.8
+
   Specify the :prop_tgt:`C_STANDARD`, :prop_tgt:`CXX_STANDARD`,
   :prop_tgt:`OBJC_STANDARD`, :prop_tgt:`OBJCXX_STANDARD`,
   or :prop_tgt:`CUDA_STANDARD` target property of the generated project.
 
 ``<LANG>_STANDARD_REQUIRED <bool>``
+  .. versionadded:: 3.8
+
   Specify the :prop_tgt:`C_STANDARD_REQUIRED`,
   :prop_tgt:`CXX_STANDARD_REQUIRED`, :prop_tgt:`OBJC_STANDARD_REQUIRED`,
   :prop_tgt:`OBJCXX_STANDARD_REQUIRED`,or :prop_tgt:`CUDA_STANDARD_REQUIRED`
   target property of the generated project.
 
 ``<LANG>_EXTENSIONS <bool>``
+  .. versionadded:: 3.8
+
   Specify the :prop_tgt:`C_EXTENSIONS`, :prop_tgt:`CXX_EXTENSIONS`,
   :prop_tgt:`OBJC_EXTENSIONS`, :prop_tgt:`OBJCXX_EXTENSIONS`,
   or :prop_tgt:`CUDA_EXTENSIONS` target property of the generated project.
@@ -131,24 +147,26 @@
 Other Behavior Settings
 ^^^^^^^^^^^^^^^^^^^^^^^
 
-If set, the following variables are passed in to the generated
-try_compile CMakeLists.txt to initialize compile target properties with
-default values:
+.. versionadded:: 3.4
+  If set, the following variables are passed in to the generated
+  try_compile CMakeLists.txt to initialize compile target properties with
+  default values:
 
-* :variable:`CMAKE_CUDA_RUNTIME_LIBRARY`
-* :variable:`CMAKE_ENABLE_EXPORTS`
-* :variable:`CMAKE_LINK_SEARCH_START_STATIC`
-* :variable:`CMAKE_LINK_SEARCH_END_STATIC`
-* :variable:`CMAKE_MSVC_RUNTIME_LIBRARY`
-* :variable:`CMAKE_POSITION_INDEPENDENT_CODE`
+  * :variable:`CMAKE_CUDA_RUNTIME_LIBRARY`
+  * :variable:`CMAKE_ENABLE_EXPORTS`
+  * :variable:`CMAKE_LINK_SEARCH_START_STATIC`
+  * :variable:`CMAKE_LINK_SEARCH_END_STATIC`
+  * :variable:`CMAKE_MSVC_RUNTIME_LIBRARY`
+  * :variable:`CMAKE_POSITION_INDEPENDENT_CODE`
 
-If :policy:`CMP0056` is set to ``NEW``, then
-:variable:`CMAKE_EXE_LINKER_FLAGS` is passed in as well.
+  If :policy:`CMP0056` is set to ``NEW``, then
+  :variable:`CMAKE_EXE_LINKER_FLAGS` is passed in as well.
 
-If :policy:`CMP0083` is set to ``NEW``, then in order to obtain correct
-behavior at link time, the ``check_pie_supported()`` command from the
-:module:`CheckPIESupported` module must be called before using the
-:command:`try_compile` command.
+.. versionchanged:: 3.14
+  If :policy:`CMP0083` is set to ``NEW``, then in order to obtain correct
+  behavior at link time, the ``check_pie_supported()`` command from the
+  :module:`CheckPIESupported` module must be called before using the
+  :command:`try_compile` command.
 
 The current settings of :policy:`CMP0065` and :policy:`CMP0083` are propagated
 through to the generated test project.
@@ -156,37 +174,41 @@
 Set the :variable:`CMAKE_TRY_COMPILE_CONFIGURATION` variable to choose
 a build configuration.
 
-Set the :variable:`CMAKE_TRY_COMPILE_TARGET_TYPE` variable to specify
-the type of target used for the source file signature.
+.. versionadded:: 3.6
+  Set the :variable:`CMAKE_TRY_COMPILE_TARGET_TYPE` variable to specify
+  the type of target used for the source file signature.
 
-Set the :variable:`CMAKE_TRY_COMPILE_PLATFORM_VARIABLES` variable to specify
-variables that must be propagated into the test project.  This variable is
-meant for use only in toolchain files and is only honored by the
-``try_compile()`` command for the source files form, not when given a whole
-project.
+.. versionadded:: 3.6
+  Set the :variable:`CMAKE_TRY_COMPILE_PLATFORM_VARIABLES` variable to specify
+  variables that must be propagated into the test project.  This variable is
+  meant for use only in toolchain files and is only honored by the
+  ``try_compile()`` command for the source files form, not when given a whole
+  project.
 
-If :policy:`CMP0067` is set to ``NEW``, or any of the ``<LANG>_STANDARD``,
-``<LANG>_STANDARD_REQUIRED``, or ``<LANG>_EXTENSIONS`` options are used,
-then the language standard variables are honored:
+.. versionchanged:: 3.8
+  If :policy:`CMP0067` is set to ``NEW``, or any of the ``<LANG>_STANDARD``,
+  ``<LANG>_STANDARD_REQUIRED``, or ``<LANG>_EXTENSIONS`` options are used,
+  then the language standard variables are honored:
 
-* :variable:`CMAKE_C_STANDARD`
-* :variable:`CMAKE_C_STANDARD_REQUIRED`
-* :variable:`CMAKE_C_EXTENSIONS`
-* :variable:`CMAKE_CXX_STANDARD`
-* :variable:`CMAKE_CXX_STANDARD_REQUIRED`
-* :variable:`CMAKE_CXX_EXTENSIONS`
-* :variable:`CMAKE_OBJC_STANDARD`
-* :variable:`CMAKE_OBJC_STANDARD_REQUIRED`
-* :variable:`CMAKE_OBJC_EXTENSIONS`
-* :variable:`CMAKE_OBJCXX_STANDARD`
-* :variable:`CMAKE_OBJCXX_STANDARD_REQUIRED`
-* :variable:`CMAKE_OBJCXX_EXTENSIONS`
-* :variable:`CMAKE_CUDA_STANDARD`
-* :variable:`CMAKE_CUDA_STANDARD_REQUIRED`
-* :variable:`CMAKE_CUDA_EXTENSIONS`
+  * :variable:`CMAKE_C_STANDARD`
+  * :variable:`CMAKE_C_STANDARD_REQUIRED`
+  * :variable:`CMAKE_C_EXTENSIONS`
+  * :variable:`CMAKE_CXX_STANDARD`
+  * :variable:`CMAKE_CXX_STANDARD_REQUIRED`
+  * :variable:`CMAKE_CXX_EXTENSIONS`
+  * :variable:`CMAKE_OBJC_STANDARD`
+  * :variable:`CMAKE_OBJC_STANDARD_REQUIRED`
+  * :variable:`CMAKE_OBJC_EXTENSIONS`
+  * :variable:`CMAKE_OBJCXX_STANDARD`
+  * :variable:`CMAKE_OBJCXX_STANDARD_REQUIRED`
+  * :variable:`CMAKE_OBJCXX_EXTENSIONS`
+  * :variable:`CMAKE_CUDA_STANDARD`
+  * :variable:`CMAKE_CUDA_STANDARD_REQUIRED`
+  * :variable:`CMAKE_CUDA_EXTENSIONS`
 
-Their values are used to set the corresponding target properties in
-the generated project (unless overridden by an explicit option).
+  Their values are used to set the corresponding target properties in
+  the generated project (unless overridden by an explicit option).
 
-For the :generator:`Green Hills MULTI` generator the GHS toolset and target
-system customization cache variables are also propagated into the test project.
+.. versionchanged:: 3.14
+  For the :generator:`Green Hills MULTI` generator the GHS toolset and target
+  system customization cache variables are also propagated into the test project.
diff --git a/Help/command/try_run.rst b/Help/command/try_run.rst
index d401ebe..272c8bd 100644
--- a/Help/command/try_run.rst
+++ b/Help/command/try_run.rst
@@ -29,6 +29,11 @@
 set to ``FAILED_TO_RUN``.  See the :command:`try_compile` command for
 information on how the test project is constructed to build the source file.
 
+.. versionadded:: 3.14
+  The names of the result variables ``<runResultVar>`` and
+  ``<compileResultVar>`` are defined by the user.  Previously, they had
+  fixed names ``RUN_RESULT_VAR`` and ``COMPILE_RESULT_VAR``.
+
 The options are:
 
 ``CMAKE_FLAGS <flags>...``
@@ -46,6 +51,8 @@
   Report the compile step build output in a given variable.
 
 ``LINK_LIBRARIES <libs>...``
+  .. versionadded:: 3.2
+
   Specify libraries to be linked in the generated project.
   The list of libraries may refer to system libraries and to
   :ref:`Imported Targets <Imported Targets>` from the calling project.
@@ -54,6 +61,8 @@
   given to the ``CMAKE_FLAGS`` option will be ignored.
 
 ``LINK_OPTIONS <options>...``
+  .. versionadded:: 3.14
+
   Specify link step options to pass to :command:`target_link_options` in the
   generated project.
 
@@ -74,6 +83,10 @@
 Behavior when Cross Compiling
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
+.. versionadded:: 3.3
+  Use ``CMAKE_CROSSCOMPILING_EMULATOR`` when running cross-compiled
+  binaries.
+
 When cross compiling, the executable compiled in the first step
 usually cannot be run on the build host.  The ``try_run`` command checks
 the :variable:`CMAKE_CROSSCOMPILING` variable to detect whether CMake is in
diff --git a/Help/cpack_gen/archive.rst b/Help/cpack_gen/archive.rst
index 3656aa2..98b24ea 100644
--- a/Help/cpack_gen/archive.rst
+++ b/Help/cpack_gen/archive.rst
@@ -12,6 +12,12 @@
   - TZST (.tar.zst)
   - ZIP (.zip)
 
+.. versionadded:: 3.1
+  ``7Z`` and ``TXZ`` formats support.
+
+.. versionadded:: 3.16
+  ``TZST`` format support.
+
 When this generator is called from ``CPackSourceConfig.cmake`` (or through
 the ``package_source`` target), then the generated archive will contain all
 files in the project directory, except those specified in
@@ -46,6 +52,9 @@
   The default is ``<CPACK_PACKAGE_FILE_NAME>[-<component>]``, with spaces
   replaced by '-'.
 
+  .. versionadded:: 3.9
+    Per-component ``CPACK_ARCHIVE_<component>_FILE_NAME`` variables.
+
 .. variable:: CPACK_ARCHIVE_COMPONENT_INSTALL
 
   Enable component packaging. If enabled (ON), then the archive generator
@@ -63,6 +72,8 @@
 
 .. variable:: CPACK_ARCHIVE_THREADS
 
+  .. versionadded:: 3.18
+
   The number of threads to use when performing the compression. If set to
   ``0``, the number of available cores on the machine will be used instead.
   The default is ``1`` which limits compression to a single thread. Note that
diff --git a/Help/cpack_gen/bundle.rst b/Help/cpack_gen/bundle.rst
index b16dbda..5e335c0 100644
--- a/Help/cpack_gen/bundle.rst
+++ b/Help/cpack_gen/bundle.rst
@@ -36,6 +36,8 @@
 
 .. variable:: CPACK_BUNDLE_APPLE_CERT_APP
 
+ .. versionadded:: 3.2
+
  The name of your Apple supplied code signing certificate for the application.
  The name usually takes the form ``Developer ID Application: [Name]`` or
  ``3rd Party Mac Developer Application: [Name]``. If this variable is not set
@@ -43,23 +45,31 @@
 
 .. variable:: CPACK_BUNDLE_APPLE_ENTITLEMENTS
 
+ .. versionadded:: 3.2
+
  The name of the Property List (``.plist``) file that contains your Apple
  entitlements for sandboxing your application. This file is required
  for submission to the macOS App Store.
 
 .. variable:: CPACK_BUNDLE_APPLE_CODESIGN_FILES
 
+ .. versionadded:: 3.2
+
  A list of additional files that you wish to be signed. You do not need to
  list the main application folder, or the main executable. You should
  list any frameworks and plugins that are included in your app bundle.
 
 .. variable:: CPACK_BUNDLE_APPLE_CODESIGN_PARAMETER
 
+ .. versionadded:: 3.3
+
  Additional parameter that will passed to ``codesign``.
  Default value: ``--deep -f``
 
 .. variable:: CPACK_COMMAND_CODESIGN
 
+ .. versionadded:: 3.2
+
  Path to the ``codesign(1)`` command used to sign applications with an
  Apple cert. This variable can be used to override the automatically
  detected command (or specify its location if the auto-detection fails
diff --git a/Help/cpack_gen/cygwin.rst b/Help/cpack_gen/cygwin.rst
index c65653e..c537a79 100644
--- a/Help/cpack_gen/cygwin.rst
+++ b/Help/cpack_gen/cygwin.rst
@@ -6,7 +6,9 @@
 Variables affecting the CPack Cygwin generator
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-  - :variable:`CPACK_ARCHIVE_THREADS`
+- .. versionadded:: 3.18
+    :variable:`CPACK_ARCHIVE_THREADS`
+
 
 Variables specific to CPack Cygwin generator
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/Help/cpack_gen/deb.rst b/Help/cpack_gen/deb.rst
index bf50c55..8fbefdb 100644
--- a/Help/cpack_gen/deb.rst
+++ b/Help/cpack_gen/deb.rst
@@ -54,11 +54,16 @@
    - :variable:`CPACK_DEBIAN_PACKAGE_NAME` suffixed with -<COMPONENT>
      for component-based installations.
 
+ .. versionadded:: 3.5
+  Per-component ``CPACK_DEBIAN_<COMPONENT>_PACKAGE_NAME`` variables.
+
  See https://www.debian.org/doc/debian-policy/ch-controlfields.html#s-f-Source
 
 .. variable:: CPACK_DEBIAN_FILE_NAME
               CPACK_DEBIAN_<COMPONENT>_FILE_NAME
 
+ .. versionadded:: 3.6
+
  Package file name.
 
  * Mandatory : YES
@@ -72,6 +77,9 @@
  Alternatively provided package file name must end
  with either ``.deb`` or ``.ipk`` suffix.
 
+ .. versionadded:: 3.10
+  ``.ipk`` suffix used by OPKG packaging system.
+
  .. note::
 
    Preferred setting of this variable is ``DEB-DEFAULT`` but for backward
@@ -86,6 +94,8 @@
 
 .. variable:: CPACK_DEBIAN_PACKAGE_EPOCH
 
+ .. versionadded:: 3.10
+
  The Debian package epoch
 
  * Mandatory : No
@@ -116,6 +126,8 @@
 
 .. variable:: CPACK_DEBIAN_PACKAGE_RELEASE
 
+ .. versionadded:: 3.6
+
  The Debian package release - Debian revision number.
 
  * Mandatory : No
@@ -136,6 +148,9 @@
  * Default   : Output of ``dpkg --print-architecture`` (or ``i386``
    if ``dpkg`` is not found)
 
+ .. versionadded:: 3.6
+  Per-component ``CPACK_DEBIAN_<COMPONENT>_PACKAGE_ARCHITECTURE`` variables.
+
 .. variable:: CPACK_DEBIAN_PACKAGE_DEPENDS
               CPACK_DEBIAN_<COMPONENT>_PACKAGE_DEPENDS
 
@@ -148,6 +163,10 @@
    - :variable:`CPACK_DEBIAN_PACKAGE_DEPENDS` for component-based
      installations.
 
+
+ .. versionadded:: 3.3
+  Per-component ``CPACK_DEBIAN_<COMPONENT>_PACKAGE_DEPENDS`` variables.
+
  .. note::
 
    If :variable:`CPACK_DEBIAN_PACKAGE_SHLIBDEPS` or
@@ -165,7 +184,9 @@
 
 .. variable:: CPACK_DEBIAN_ENABLE_COMPONENT_DEPENDS
 
- Sets inter component dependencies if listed with
+ .. versionadded:: 3.6
+
+ Sets inter-component dependencies if listed with
  :variable:`CPACK_COMPONENT_<compName>_DEPENDS` variables.
 
  * Mandatory : NO
@@ -196,6 +217,15 @@
  used if set. Otherwise, :variable:`CPACK_PACKAGE_DESCRIPTION_SUMMARY` will be added as the first
  line of description as defined in `Debian Policy Manual`_.
 
+ .. versionadded:: 3.3
+  Per-component ``CPACK_COMPONENT_<compName>_DESCRIPTION`` variables.
+
+ .. versionadded:: 3.16
+  Per-component ``CPACK_DEBIAN_<COMPONENT>_DESCRIPTION`` variables.
+
+ .. versionadded:: 3.16
+  ``CPACK_PACKAGE_DESCRIPTION_FILE`` variable.
+
 .. _Debian Policy Manual: https://www.debian.org/doc/debian-policy/ch-controlfields.html#description
 
 .. variable:: CPACK_DEBIAN_PACKAGE_SECTION
@@ -206,10 +236,17 @@
  * Mandatory : YES
  * Default   : "devel"
 
+ .. versionadded:: 3.5
+  Per-component ``CPACK_DEBIAN_<COMPONENT>_PACKAGE_SECTION`` variables.
+
  See https://www.debian.org/doc/debian-policy/ch-archive.html#s-subsections
 
 .. variable:: CPACK_DEBIAN_ARCHIVE_TYPE
 
+ .. versionadded:: 3.7
+
+ .. deprecated:: 3.14
+
  The archive format used for creating the Debian package.
 
  * Mandatory : YES
@@ -228,6 +265,8 @@
 
 .. variable:: CPACK_DEBIAN_COMPRESSION_TYPE
 
+ .. versionadded:: 3.1
+
  The compression used for creating the Debian package.
 
  * Mandatory : YES
@@ -249,6 +288,9 @@
  * Mandatory : YES
  * Default   : "optional"
 
+ .. versionadded:: 3.5
+  Per-component ``CPACK_DEBIAN_<COMPONENT>_PACKAGE_PRIORITY`` varables.
+
  See https://www.debian.org/doc/debian-policy/ch-archive.html#s-priorities
 
 .. variable:: CPACK_DEBIAN_PACKAGE_HOMEPAGE
@@ -260,6 +302,9 @@
  * Mandatory : NO
  * Default   : :variable:`CMAKE_PROJECT_HOMEPAGE_URL`
 
+ .. versionadded:: 3.12
+  ``CMAKE_PROJECT_HOMEPAGE_URL`` variable.
+
  .. note::
 
    The content of this field is a simple URL without any surrounding
@@ -284,6 +329,12 @@
    may fail to find your own shared libs.
    See https://gitlab.kitware.com/cmake/community/-/wikis/doc/cmake/RPATH-handling
 
+ .. versionadded:: 3.3
+  Per-component ``CPACK_DEBIAN_<COMPONENT>_PACKAGE_SHLIBDEPS`` variables.
+
+ .. versionadded:: 3.6
+  Correct handling of ``$ORIGIN`` in :variable:`CMAKE_INSTALL_RPATH`.
+
 .. variable:: CPACK_DEBIAN_PACKAGE_DEBUG
 
  May be set when invoking cpack in order to trace debug information
@@ -308,6 +359,9 @@
    - :variable:`CPACK_DEBIAN_PACKAGE_PREDEPENDS` for component-based
      installations.
 
+ .. versionadded:: 3.4
+  Per-component ``CPACK_DEBIAN_<COMPONENT>_PACKAGE_PREDEPENDS`` variables.
+
  See http://www.debian.org/doc/debian-policy/ch-relationships.html#s-binarydeps
 
 .. variable:: CPACK_DEBIAN_PACKAGE_ENHANCES
@@ -325,6 +379,9 @@
    - :variable:`CPACK_DEBIAN_PACKAGE_ENHANCES` for component-based
      installations.
 
+ .. versionadded:: 3.4
+  Per-component ``CPACK_DEBIAN_<COMPONENT>_PACKAGE_ENHANCES`` variables.
+
  See http://www.debian.org/doc/debian-policy/ch-relationships.html#s-binarydeps
 
 .. variable:: CPACK_DEBIAN_PACKAGE_BREAKS
@@ -345,6 +402,9 @@
    - :variable:`CPACK_DEBIAN_PACKAGE_BREAKS` for component-based
      installations.
 
+ .. versionadded:: 3.4
+  Per-component ``CPACK_DEBIAN_<COMPONENT>_PACKAGE_BREAKS`` variables.
+
  See https://www.debian.org/doc/debian-policy/ch-relationships.html#s-breaks
 
 .. variable:: CPACK_DEBIAN_PACKAGE_CONFLICTS
@@ -362,6 +422,9 @@
    - :variable:`CPACK_DEBIAN_PACKAGE_CONFLICTS` for component-based
      installations.
 
+ .. versionadded:: 3.4
+  Per-component ``CPACK_DEBIAN_<COMPONENT>_PACKAGE_CONFLICTS`` variables.
+
  See https://www.debian.org/doc/debian-policy/ch-relationships.html#s-conflicts
 
  .. note::
@@ -386,6 +449,9 @@
    - :variable:`CPACK_DEBIAN_PACKAGE_PROVIDES` for component-based
      installations.
 
+ .. versionadded:: 3.4
+  Per-component ``CPACK_DEBIAN_<COMPONENT>_PACKAGE_PROVIDES`` variables.
+
  See https://www.debian.org/doc/debian-policy/ch-relationships.html#s-virtual
 
 .. variable:: CPACK_DEBIAN_PACKAGE_REPLACES
@@ -402,6 +468,9 @@
    - :variable:`CPACK_DEBIAN_PACKAGE_REPLACES` for component-based
      installations.
 
+ .. versionadded:: 3.4
+  Per-component ``CPACK_DEBIAN_<COMPONENT>_PACKAGE_REPLACES`` variables.
+
  See http://www.debian.org/doc/debian-policy/ch-relationships.html#s-binarydeps
 
 .. variable:: CPACK_DEBIAN_PACKAGE_RECOMMENDS
@@ -418,6 +487,9 @@
    - :variable:`CPACK_DEBIAN_PACKAGE_RECOMMENDS` for component-based
      installations.
 
+ .. versionadded:: 3.4
+  Per-component ``CPACK_DEBIAN_<COMPONENT>_PACKAGE_RECOMMENDS`` variables.
+
  See http://www.debian.org/doc/debian-policy/ch-relationships.html#s-binarydeps
 
 .. variable:: CPACK_DEBIAN_PACKAGE_SUGGESTS
@@ -433,10 +505,15 @@
    - :variable:`CPACK_DEBIAN_PACKAGE_SUGGESTS` for component-based
      installations.
 
+ .. versionadded:: 3.4
+  Per-component ``CPACK_DEBIAN_<COMPONENT>_PACKAGE_SUGGESTS`` variables.
+
  See http://www.debian.org/doc/debian-policy/ch-relationships.html#s-binarydeps
 
 .. variable:: CPACK_DEBIAN_PACKAGE_GENERATE_SHLIBS
 
+ .. versionadded:: 3.6
+
  * Mandatory : NO
  * Default   : OFF
 
@@ -451,6 +528,8 @@
 
 .. variable:: CPACK_DEBIAN_PACKAGE_GENERATE_SHLIBS_POLICY
 
+ .. versionadded:: 3.6
+
  Compatibility policy for auto-generated shlibs control file.
 
  * Mandatory : NO
@@ -476,17 +555,14 @@
   set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA
       "${CMAKE_CURRENT_SOURCE_DIR}/prerm;${CMAKE_CURRENT_SOURCE_DIR}/postrm")
 
- .. note::
-
-   The original permissions of the files will be used in the final
-   package unless the variable
-   :variable:`CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION` is set.
-   In particular, the scripts should have the proper executable
-   flag prior to the generation of the package.
+ .. versionadded:: 3.4
+  Per-component ``CPACK_DEBIAN_<COMPONENT>_PACKAGE_CONTROL_EXTRA`` variables.
 
 .. variable:: CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION
               CPACK_DEBIAN_<COMPONENT>_PACKAGE_CONTROL_STRICT_PERMISSION
 
+ .. versionadded:: 3.4
+
  This variable indicates if the Debian policy on control files should be
  strictly followed.
 
@@ -497,15 +573,22 @@
 
   set(CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION TRUE)
 
+ This overrides the permissions on the original files, following the rules
+ set by Debian policy
+ https://www.debian.org/doc/debian-policy/ch-files.html#s-permissions-owners
+
  .. note::
 
-   This overrides the permissions on the original files, following the rules
-   set by Debian policy
-   https://www.debian.org/doc/debian-policy/ch-files.html#s-permissions-owners
+  The original permissions of the files will be used in the final
+  package unless this variable is set to ``TRUE``.
+  In particular, the scripts should have the proper executable
+  flag prior to the generation of the package.
 
 .. variable:: CPACK_DEBIAN_PACKAGE_SOURCE
               CPACK_DEBIAN_<COMPONENT>_PACKAGE_SOURCE
 
+ .. versionadded:: 3.5
+
  Sets the ``Source`` field of the binary Debian package.
  When the binary package name is not the same as the source package name
  (in particular when several components/binaries are generated from one
@@ -529,6 +612,8 @@
 Packaging of debug information
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
+.. versionadded:: 3.13
+
 Dbgsym packages contain debug symbols for debugging packaged binaries.
 
 Dbgsym packaging has its own set of variables:
@@ -549,6 +634,8 @@
 Building Debian packages on Windows
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
+.. versionadded:: 3.10
+
 To communicate UNIX file permissions from the install stage
 to the CPack DEB generator the "cmake_mode_t" NTFS
 alternate data stream (ADT) is used.
@@ -559,6 +646,8 @@
 Reproducible packages
 ^^^^^^^^^^^^^^^^^^^^^
 
+.. versionadded:: 3.13
+
 The environment variable ``SOURCE_DATE_EPOCH`` may be set to a UNIX
 timestamp, defined as the number of seconds, excluding leap seconds,
 since 01 Jan 1970 00:00:00 UTC.  If set, the CPack DEB generator will
diff --git a/Help/cpack_gen/dmg.rst b/Help/cpack_gen/dmg.rst
index cede0f2..4c662a6 100644
--- a/Help/cpack_gen/dmg.rst
+++ b/Help/cpack_gen/dmg.rst
@@ -30,6 +30,8 @@
 
 .. variable:: CPACK_DMG_DS_STORE_SETUP_SCRIPT
 
+ .. versionadded:: 3.5
+
  Path to a custom AppleScript file.  This AppleScript is used to generate
  a ``.DS_Store`` file which specifies the Finder window position/geometry and
  layout (such as hidden toolbars, placement of the icons etc.).
@@ -47,11 +49,15 @@
 
 .. variable:: CPACK_DMG_DISABLE_APPLICATIONS_SYMLINK
 
+ .. versionadded:: 3.6
+
  Default behaviour is to include a symlink to ``/Applications`` in the DMG.
  Set this option to ``ON`` to avoid adding the symlink.
 
 .. variable:: CPACK_DMG_SLA_DIR
 
+  .. versionadded:: 3.5
+
   Directory where license and menu files for different languages are stored.
   Setting this causes CPack to look for a ``<language>.menu.txt`` and
   ``<language>.license.txt`` or ``<language>.license.rtf`` file for every
@@ -61,8 +67,13 @@
   ``<language>.license.txt`` and ``<language>.license.rtf`` exist, the ``.txt``
   file will be used.
 
+  .. versionadded:: 3.17
+    RTF support.
+
 .. variable:: CPACK_DMG_SLA_LANGUAGES
 
+  .. versionadded:: 3.5
+
   Languages for which a license agreement is provided when mounting the
   generated DMG. A menu file consists of 9 lines of text. The first line is
   is the name of the language itself, uppercase, in English (e.g. German).
@@ -85,6 +96,8 @@
 
 .. variable:: CPACK_DMG_<component>_FILE_NAME
 
+ .. versionadded:: 3.17
+
  File name when packaging ``<component>`` as its own DMG
  (``CPACK_COMPONENTS_GROUPING`` set to IGNORE).
 
diff --git a/Help/cpack_gen/external.rst b/Help/cpack_gen/external.rst
index e54b356..4c083f0 100644
--- a/Help/cpack_gen/external.rst
+++ b/Help/cpack_gen/external.rst
@@ -1,6 +1,8 @@
 CPack External Generator
 ------------------------
 
+.. versionadded:: 3.13
+
 CPack provides many generators to create packages for a variety of platforms
 and packaging systems. The intention is for CMake/CPack to be a complete
 end-to-end solution for building and packaging a software project. However, it
@@ -284,6 +286,8 @@
 
 .. variable:: CPACK_EXTERNAL_BUILT_PACKAGES
 
+  .. versionadded:: 3.19
+
   The ``CPACK_EXTERNAL_PACKAGE_SCRIPT`` script may set this list variable to the
   full paths of generated package files.  CPack will copy these files from the
   staging directory back to the top build directory and possibly produce
diff --git a/Help/cpack_gen/freebsd.rst b/Help/cpack_gen/freebsd.rst
index 47a7784..3cfa4a0 100644
--- a/Help/cpack_gen/freebsd.rst
+++ b/Help/cpack_gen/freebsd.rst
@@ -1,12 +1,15 @@
 CPack FreeBSD Generator
 -----------------------
 
+.. versionadded:: 3.10
+
 The built in (binary) CPack FreeBSD (pkg) generator (Unix only)
 
 Variables affecting the CPack FreeBSD (pkg) generator
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-  - :variable:`CPACK_ARCHIVE_THREADS`
+- .. versionadded:: 3.18
+    :variable:`CPACK_ARCHIVE_THREADS`
 
 Variables specific to CPack FreeBSD (pkg) generator
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -86,6 +89,9 @@
      :variable:`CPACK_DEBIAN_PACKAGE_HOMEPAGE` (this may be set already
      for Debian packaging, so we may as well re-use it).
 
+  .. versionadded:: 3.12
+    ``CMAKE_PROJECT_HOMEPAGE_URL`` variable.
+
 .. variable:: CPACK_FREEBSD_PACKAGE_LICENSE
 
   The license, or licenses, which apply to this software package. This must
diff --git a/Help/cpack_gen/ifw.rst b/Help/cpack_gen/ifw.rst
index 5fbbfa2..3315411 100644
--- a/Help/cpack_gen/ifw.rst
+++ b/Help/cpack_gen/ifw.rst
@@ -1,6 +1,8 @@
 CPack IFW Generator
 -------------------
 
+.. versionadded:: 3.1
+
 Configure and run the Qt Installer Framework to generate a Qt installer.
 
 .. only:: html
@@ -35,6 +37,8 @@
 
 .. variable:: CPACK_IFW_VERBOSE
 
+ .. versionadded:: 3.3
+
  Set to ``ON`` to enable addition debug output.
  By default is ``OFF``.
 
@@ -71,41 +75,51 @@
 
 .. variable:: CPACK_IFW_PACKAGE_WATERMARK
 
+ .. versionadded:: 3.8
+
  Filename for a watermark is used as QWizard::WatermarkPixmap.
 
 .. variable:: CPACK_IFW_PACKAGE_BANNER
 
+ .. versionadded:: 3.8
+
  Filename for a banner is used as QWizard::BannerPixmap.
 
 .. variable:: CPACK_IFW_PACKAGE_BACKGROUND
 
+ .. versionadded:: 3.8
+
  Filename for an image used as QWizard::BackgroundPixmap (only used by MacStyle).
 
 .. variable:: CPACK_IFW_PACKAGE_WIZARD_STYLE
 
+ .. versionadded:: 3.8
+
  Wizard style to be used ("Modern", "Mac", "Aero" or "Classic").
 
-.. variable:: CPACK_IFW_PACKAGE_STYLE_SHEET
-
- Filename for a stylesheet.
-
 .. variable:: CPACK_IFW_PACKAGE_WIZARD_DEFAULT_WIDTH
 
+ .. versionadded:: 3.8
+
  Default width of the wizard in pixels. Setting a banner image will override this.
 
 .. variable:: CPACK_IFW_PACKAGE_WIZARD_DEFAULT_HEIGHT
 
+ .. versionadded:: 3.8
+
  Default height of the wizard in pixels. Setting a watermark image will override this.
 
 .. variable:: CPACK_IFW_PACKAGE_TITLE_COLOR
 
+ .. versionadded:: 3.8
+
  Color of the titles and subtitles (takes an HTML color code, such as "#88FF33").
 
-.. variable:: CPACK_IFW_PACKAGE_START_MENU_DIRECTORY
+.. variable:: CPACK_IFW_PACKAGE_STYLE_SHEET
 
- Name of the default program group for the product in the Windows Start menu.
+ .. versionadded:: 3.15
 
- By default used :variable:`CPACK_IFW_PACKAGE_NAME`.
+ Filename for a stylesheet.
 
 .. variable:: CPACK_IFW_TARGET_DIRECTORY
 
@@ -123,6 +137,14 @@
 
  You can use predefined variables.
 
+.. variable:: CPACK_IFW_PACKAGE_REMOVE_TARGET_DIR
+
+ .. versionadded:: 3.11
+
+ Set to ``OFF`` if the target directory should not be deleted when uninstalling.
+
+ Is ``ON`` by default
+
 .. variable:: CPACK_IFW_PACKAGE_GROUP
 
  The group, which will be used to configure the root package
@@ -132,39 +154,51 @@
  The root package name, which will be used if configuration group is not
  specified
 
+.. variable:: CPACK_IFW_PACKAGE_START_MENU_DIRECTORY
+
+ .. versionadded:: 3.3
+
+ Name of the default program group for the product in the Windows Start menu.
+
+ By default used :variable:`CPACK_IFW_PACKAGE_NAME`.
+
 .. variable:: CPACK_IFW_PACKAGE_MAINTENANCE_TOOL_NAME
 
+ .. versionadded:: 3.3
+
  Filename of the generated maintenance tool.
  The platform-specific executable file extension is appended.
 
  By default used QtIFW defaults (``maintenancetool``).
 
-.. variable:: CPACK_IFW_PACKAGE_REMOVE_TARGET_DIR
-
- Set to ``OFF`` if the target directory should not be deleted when uninstalling.
-
- Is ``ON`` by default
-
 .. variable:: CPACK_IFW_PACKAGE_MAINTENANCE_TOOL_INI_FILE
 
+ .. versionadded:: 3.3
+
  Filename for the configuration of the generated maintenance tool.
 
  By default used QtIFW defaults (``maintenancetool.ini``).
 
 .. variable:: CPACK_IFW_PACKAGE_ALLOW_NON_ASCII_CHARACTERS
 
+ .. versionadded:: 3.3
+
  Set to ``ON`` if the installation path can contain non-ASCII characters.
 
  Is ``ON`` for QtIFW less 2.0 tools.
 
 .. variable:: CPACK_IFW_PACKAGE_ALLOW_SPACE_IN_PATH
 
+ .. versionadded:: 3.3
+
  Set to ``OFF`` if the installation path cannot contain space characters.
 
  Is ``ON`` for QtIFW less 2.0 tools.
 
 .. variable:: CPACK_IFW_PACKAGE_CONTROL_SCRIPT
 
+ .. versionadded:: 3.3
+
  Filename for a custom installer control script.
 
 .. variable:: CPACK_IFW_PACKAGE_RESOURCES
@@ -177,6 +211,8 @@
 
 .. variable:: CPACK_IFW_PACKAGE_FILE_EXTENSION
 
+ .. versionadded:: 3.10
+
  The target binary extension.
 
  On Linux, the name of the target binary is automatically extended with
@@ -216,6 +252,8 @@
 
 .. variable:: CPACK_IFW_REPOSITORIES_DIRECTORIES
 
+ .. versionadded:: 3.10
+
  Additional prepared repository dirs that will be used to resolve and
  repack dependent components. This feature available only
  since QtIFW 3.1.
@@ -225,6 +263,8 @@
 
 .. variable:: CPACK_IFW_FRAMEWORK_VERSION
 
+ .. versionadded:: 3.3
+
  The version of used QtIFW tools.
 
 The following variables provide the locations of the QtIFW
@@ -260,6 +300,8 @@
 
 .. variable:: CPACK_IFW_ROOT
 
+ .. versionadded:: 3.9
+
  An CMake variable which specifies the location of the QtIFW tool suite.
 
  The variable will be cached in the ``CPackConfig.cmake`` file and used at
@@ -306,6 +348,8 @@
 Internationalization
 """"""""""""""""""""
 
+.. versionadded:: 3.9
+
 Some variables and command arguments support internationalization via
 CMake script. This is an optional feature.
 
diff --git a/Help/cpack_gen/nsis.rst b/Help/cpack_gen/nsis.rst
index 0dd876e..33198e7 100644
--- a/Help/cpack_gen/nsis.rst
+++ b/Help/cpack_gen/nsis.rst
@@ -3,7 +3,8 @@
 
 CPack Nullsoft Scriptable Install System (NSIS) generator specific options.
 
-The NSIS generator requires NSIS 3.0 or newer.
+.. versionchanged:: 3.17
+ The NSIS generator requires NSIS 3.0 or newer.
 
 Variables specific to CPack NSIS generator
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -33,10 +34,14 @@
 
 .. variable:: CPACK_NSIS_MUI_WELCOMEFINISHPAGE_BITMAP
 
+ .. versionadded:: 3.5
+
  The filename of a bitmap to use as the NSIS ``MUI_WELCOMEFINISHPAGE_BITMAP``.
 
 .. variable:: CPACK_NSIS_MUI_UNWELCOMEFINISHPAGE_BITMAP
 
+ .. versionadded:: 3.5
+
  The filename of a bitmap to use as the NSIS ``MUI_UNWELCOMEFINISHPAGE_BITMAP``.
 
 .. variable:: CPACK_NSIS_EXTRA_PREINSTALL_COMMANDS
@@ -99,6 +104,8 @@
 
 .. variable:: CPACK_NSIS_<compName>_INSTALL_DIRECTORY
 
+ .. versionadded:: 3.7
+
  Custom install directory for the specified component ``<compName>`` instead
  of ``$INSTDIR``.
 
@@ -133,29 +140,43 @@
 
 .. variable:: CPACK_NSIS_UNINSTALL_NAME
 
+ .. versionadded:: 3.17
+
  Specify the name of the program to uninstall the version.
  Default is ``Uninstall``.
 
 .. variable:: CPACK_NSIS_WELCOME_TITLE
 
+  .. versionadded:: 3.17
+
   The title to display on the top of the page for the welcome page.
 
 .. variable:: CPACK_NSIS_WELCOME_TITLE_3LINES
 
+ .. versionadded:: 3.17
+
  Display the title in the welcome page on 3 lines instead of 2.
 
 .. variable:: CPACK_NSIS_FINISH_TITLE
 
+ .. versionadded:: 3.17
+
  The title to display on the top of the page for the finish page.
 
 .. variable:: CPACK_NSIS_FINISH_TITLE_3LINES
 
+ .. versionadded:: 3.17
+
  Display the title in the finish page on 3 lines instead of 2.
 
 .. variable:: CPACK_NSIS_MUI_HEADERIMAGE
 
+ .. versionadded:: 3.17
+
  The image to display on the header of installers pages.
 
 .. variable:: CPACK_NSIS_MANIFEST_DPI_AWARE
 
+ .. versionadded:: 3.18
+
  If set, declares that the installer is DPI-aware.
diff --git a/Help/cpack_gen/nuget.rst b/Help/cpack_gen/nuget.rst
index f8aa626..c980dd6 100644
--- a/Help/cpack_gen/nuget.rst
+++ b/Help/cpack_gen/nuget.rst
@@ -1,9 +1,11 @@
 CPack NuGet Generator
 ---------------------
 
+.. versionadded:: 3.12
+
 When build a NuGet package there is no direct way to control an output
 filename due a lack of the corresponding CLI option of NuGet, so there
-is no ``CPACK_NUGET_PACKAGE_FILENAME`` variable. To form the output filename
+is no ``CPACK_NUGET_PACKAGE_FILE_NAME`` variable. To form the output filename
 NuGet uses the package name and the version according to its built-in rules.
 
 Also, be aware that including a top level directory
@@ -35,7 +37,8 @@
 .. variable:: CPACK_NUGET_PACKAGE_NAME
               CPACK_NUGET_<compName>_PACKAGE_NAME
 
- The NUGET package name.
+ The NUGET package name. ``CPACK_NUGET_PACKAGE_NAME`` is used as the
+ package ``id`` on nuget.org_
 
  * Mandatory : YES
  * Default   : :variable:`CPACK_PACKAGE_NAME`
@@ -95,7 +98,7 @@
 .. variable:: CPACK_NUGET_PACKAGE_HOMEPAGE_URL
               CPACK_NUGET_<compName>_PACKAGE_HOMEPAGE_URL
 
- A URL for the package's home page, often shown in UI displays as well
+ An URL for the package's home page, often shown in UI displays as well
  as nuget.org_.
 
  * Mandatory : NO
@@ -104,8 +107,45 @@
 .. variable:: CPACK_NUGET_PACKAGE_LICENSEURL
               CPACK_NUGET_<compName>_PACKAGE_LICENSEURL
 
- A URL for the package's license, often shown in UI displays as well
- as nuget.org_.
+ .. deprecated:: 3.20
+  Use a local license file
+  (:variable:`CPACK_NUGET_PACKAGE_LICENSE_FILE_NAME`)
+  or a `(SPDX) license identifier`_
+  (:variable:`CPACK_NUGET_PACKAGE_LICENSE_EXPRESSION`) instead.
+
+ An URL for the package's license, often shown in UI displays as well
+ as on nuget.org_.
+
+ * Mandatory : NO
+ * Default   : -
+
+.. variable:: CPACK_NUGET_PACKAGE_LICENSE_EXPRESSION
+              CPACK_NUGET_<compName>_PACKAGE_LICENSE_EXPRESSION
+
+ .. versionadded:: 3.20
+
+ A Software Package Data Exchange `(SPDX) license identifier`_ such as
+ ``MIT``, ``BSD-3-Clause``, or ``LGPL-3.0-or-later``. In the case of a
+ choice of licenses or more complex restrictions, compound license
+ expressions may be formed using boolean operators, for example
+ ``MIT OR BSD-3-Clause``.  See the `SPDX specification`_ for guidance
+ on forming complex license expressions.
+
+ If ``CPACK_NUGET_PACKAGE_LICENSE_FILE_NAME`` is specified,
+ ``CPACK_NUGET_PACKAGE_LICENSE_EXPRESSION`` is ignored.
+
+ * Mandatory : NO
+ * Default   : -
+
+.. variable:: CPACK_NUGET_PACKAGE_LICENSE_FILE_NAME
+              CPACK_NUGET_<compName>_PACKAGE_LICENSE_FILE_NAME
+
+ The package's license file in :file:`.txt` or :file:`.md` format.
+
+ If ``CPACK_NUGET_PACKAGE_LICENSE_FILE_NAME`` is specified,
+ ``CPACK_NUGET_PACKAGE_LICENSE_EXPRESSION`` is ignored.
+
+ .. versionadded:: 3.20
 
  * Mandatory : NO
  * Default   : -
@@ -113,7 +153,21 @@
 .. variable:: CPACK_NUGET_PACKAGE_ICONURL
               CPACK_NUGET_<compName>_PACKAGE_ICONURL
 
- A URL for a 64x64 image with transparency background to use as the
+ .. deprecated:: 3.20
+  Use a local icon file (:variable:`CPACK_NUGET_PACKAGE_ICON`) instead.
+
+ An URL for a 64x64 image with transparency background to use as the
+ icon for the package in UI display.
+
+ * Mandatory : NO
+ * Default   : -
+
+.. variable:: CPACK_NUGET_PACKAGE_ICON
+              CPACK_NUGET_<compName>_PACKAGE_ICON
+
+ .. versionadded:: 3.20
+
+ The filename of a 64x64 image with transparency background to use as the
  icon for the package in UI display.
 
  * Mandatory : NO
@@ -146,6 +200,16 @@
  * Mandatory : NO
  * Default   : -
 
+.. variable:: CPACK_NUGET_PACKAGE_LANGUAGE
+              CPACK_NUGET_<compName>_PACKAGE_LANGUAGE
+
+ .. versionadded:: 3.20
+
+ Locale specifier for the package, for example ``en_CA``.
+
+ * Mandatory : NO
+ * Default   : -
+
 .. variable:: CPACK_NUGET_PACKAGE_TAGS
               CPACK_NUGET_<compName>_PACKAGE_TAGS
 
@@ -185,5 +249,7 @@
 
 .. _nuget.org: http://nuget.org
 .. _version specification: https://docs.microsoft.com/en-us/nuget/reference/package-versioning#version-ranges-and-wildcards
+.. _(SPDX) license identifier: https://spdx.org/licenses/
+.. _SPDX specification: https://spdx.github.io/spdx-spec/appendix-IV-SPDX-license-expressions/
 
 .. NuGet spec docs https://docs.microsoft.com/en-us/nuget/reference/nuspec
diff --git a/Help/cpack_gen/packagemaker.rst b/Help/cpack_gen/packagemaker.rst
index 357eb73..256446d 100644
--- a/Help/cpack_gen/packagemaker.rst
+++ b/Help/cpack_gen/packagemaker.rst
@@ -27,6 +27,14 @@
  don't mind missing extra features available in the installer shipping with
  later versions of macOS.
 
+Background Image
+""""""""""""""""
+
+.. versionadded:: 3.17
+
+This group of variables controls the background image of the generated
+installer.
+
 .. variable:: CPACK_PACKAGEMAKER_BACKGROUND
 
  Adds a background to Distribution XML if specified. The value contains the
diff --git a/Help/cpack_gen/productbuild.rst b/Help/cpack_gen/productbuild.rst
index fd99e5a..cf3041f 100644
--- a/Help/cpack_gen/productbuild.rst
+++ b/Help/cpack_gen/productbuild.rst
@@ -1,6 +1,8 @@
 CPack productbuild Generator
 ----------------------------
 
+.. versionadded:: 3.7
+
 productbuild CPack generator (macOS).
 
 Variables specific to CPack productbuild generator
@@ -18,11 +20,15 @@
 
 .. variable:: CPACK_PRODUCTBUILD_IDENTITY_NAME
 
+ .. versionadded:: 3.8
+
  Adds a digital signature to the resulting package.
 
 
 .. variable:: CPACK_PRODUCTBUILD_KEYCHAIN_PATH
 
+ .. versionadded:: 3.8
+
  Specify a specific keychain to search for the signing identity.
 
 
@@ -35,11 +41,15 @@
 
 .. variable:: CPACK_PKGBUILD_IDENTITY_NAME
 
+ .. versionadded:: 3.8
+
  Adds a digital signature to the resulting package.
 
 
 .. variable:: CPACK_PKGBUILD_KEYCHAIN_PATH
 
+ .. versionadded:: 3.8
+
  Specify a specific keychain to search for the signing identity.
 
 
@@ -60,12 +70,22 @@
 
 .. variable:: CPACK_PRODUCTBUILD_RESOURCES_DIR
 
+ .. versionadded:: 3.9
+
  If specified the productbuild generator copies files from this directory
  (including subdirectories) to the ``Resources`` directory. This is done
  before the :variable:`CPACK_RESOURCE_FILE_WELCOME`,
  :variable:`CPACK_RESOURCE_FILE_README`, and
  :variable:`CPACK_RESOURCE_FILE_LICENSE` files are copied.
 
+Background Image
+""""""""""""""""
+
+.. versionadded:: 3.17
+
+This group of variables controls the background image of the generated
+installer.
+
 .. variable:: CPACK_PRODUCTBUILD_BACKGROUND
 
  Adds a background to Distribution XML if specified. The value contains the
diff --git a/Help/cpack_gen/rpm.rst b/Help/cpack_gen/rpm.rst
index ccb7ebd..a8c3c5c 100644
--- a/Help/cpack_gen/rpm.rst
+++ b/Help/cpack_gen/rpm.rst
@@ -20,7 +20,7 @@
 entities. One may find information about spec files here
 http://www.rpm.org/wiki/Docs
 
-.. note::
+.. versionchanged:: 3.6
 
  `<COMPONENT>` part of variables is preferred to be in upper case (e.g. if
  component is named ``foo`` then use ``CPACK_RPM_FOO_XXXX`` variable name format)
@@ -59,6 +59,9 @@
  * Mandatory : YES
  * Default   : :variable:`CPACK_PACKAGE_DESCRIPTION_SUMMARY`
 
+ .. versionadded:: 3.2
+  Per-component ``CPACK_RPM_<component>_PACKAGE_SUMMARY`` variables.
+
 .. variable:: CPACK_RPM_PACKAGE_NAME
               CPACK_RPM_<component>_PACKAGE_NAME
 
@@ -67,9 +70,14 @@
  * Mandatory : YES
  * Default   : :variable:`CPACK_PACKAGE_NAME`
 
+ .. versionadded:: 3.5
+  Per-component ``CPACK_RPM_<component>_PACKAGE_NAME`` variables.
+
 .. variable:: CPACK_RPM_FILE_NAME
               CPACK_RPM_<component>_FILE_NAME
 
+ .. versionadded:: 3.6
+
  Package file name.
 
  * Mandatory : YES
@@ -93,6 +101,8 @@
 
 .. variable:: CPACK_RPM_MAIN_COMPONENT
 
+ .. versionadded:: 3.8
+
  Main component that is packaged without component suffix.
 
  * Mandatory : NO
@@ -104,6 +114,8 @@
 
 .. variable:: CPACK_RPM_PACKAGE_EPOCH
 
+ .. versionadded:: 3.10
+
  The RPM package epoch
 
  * Mandatory : No
@@ -129,6 +141,9 @@
 
  This may be set to ``noarch`` if you know you are building a ``noarch`` package.
 
+ .. versionadded:: 3.3
+  Per-component ``CPACK_RPM_<component>_PACKAGE_ARCHITECTURE`` variables.
+
 .. variable:: CPACK_RPM_PACKAGE_RELEASE
 
  The RPM package release.
@@ -150,6 +165,8 @@
 
 .. variable:: CPACK_RPM_PACKAGE_RELEASE_DIST
 
+ .. versionadded:: 3.6
+
  The dist tag that is added  RPM ``Release:`` field.
 
  * Mandatory : NO
@@ -174,6 +191,9 @@
  * Mandatory : YES
  * Default   : "unknown"
 
+ .. versionadded:: 3.5
+  Per-component ``CPACK_RPM_<component>_PACKAGE_GROUP`` variables.
+
 .. variable:: CPACK_RPM_PACKAGE_VENDOR
 
  The RPM package vendor.
@@ -189,6 +209,9 @@
  * Mandatory : NO
  * Default   : :variable:`CMAKE_PROJECT_HOMEPAGE_URL`
 
+ .. versionadded:: 3.12
+  ``CMAKE_PROJECT_HOMEPAGE_URL`` variable.
+
 .. variable:: CPACK_RPM_PACKAGE_DESCRIPTION
               CPACK_RPM_<component>_PACKAGE_DESCRIPTION
 
@@ -199,6 +222,9 @@
    based installers only) if set, :variable:`CPACK_PACKAGE_DESCRIPTION_FILE`
    if set or "no package description available"
 
+ .. versionadded:: 3.2
+  Per-component ``CPACK_RPM_<component>_PACKAGE_DESCRIPTION`` variables.
+
 .. variable:: CPACK_RPM_COMPRESSION_TYPE
 
  RPM compression type.
@@ -302,6 +328,8 @@
 .. variable:: CPACK_RPM_PACKAGE_REQUIRES_PRE
               CPACK_RPM_<component>_PACKAGE_REQUIRES_PRE
 
+ .. versionadded:: 3.2
+
  RPM spec requires(pre) field.
 
  * Mandatory : NO
@@ -315,6 +343,8 @@
 .. variable:: CPACK_RPM_PACKAGE_REQUIRES_POST
               CPACK_RPM_<component>_PACKAGE_REQUIRES_POST
 
+ .. versionadded:: 3.2
+
  RPM spec requires(post) field.
 
  * Mandatory : NO
@@ -328,6 +358,8 @@
 .. variable:: CPACK_RPM_PACKAGE_REQUIRES_POSTUN
               CPACK_RPM_<component>_PACKAGE_REQUIRES_POSTUN
 
+ .. versionadded:: 3.2
+
  RPM spec requires(postun) field.
 
  * Mandatory : NO
@@ -342,6 +374,8 @@
 .. variable:: CPACK_RPM_PACKAGE_REQUIRES_PREUN
               CPACK_RPM_<component>_PACKAGE_REQUIRES_PREUN
 
+ .. versionadded:: 3.2
+
  RPM spec requires(preun) field.
 
  * Mandatory : NO
@@ -492,6 +526,9 @@
 
   rpm -qp --scripts  package.rpm
 
+ .. versionadded:: 3.18
+  ``CPACK_RPM_PRE_TRANS_SCRIPT_FILE`` variable.
+
 .. variable:: CPACK_RPM_POST_INSTALL_SCRIPT_FILE
               CPACK_RPM_POST_UNINSTALL_SCRIPT_FILE
               CPACK_RPM_POST_TRANS_SCRIPT_FILE
@@ -513,6 +550,9 @@
 
   rpm -qp --scripts  package.rpm
 
+ .. versionadded:: 3.18
+  ``CPACK_RPM_POST_TRANS_SCRIPT_FILE`` variable.
+
 .. variable:: CPACK_RPM_USER_FILELIST
               CPACK_RPM_<COMPONENT>_USER_FILELIST
 
@@ -521,13 +561,16 @@
 
  May be used to explicitly specify ``%(<directive>)`` file line
  in the spec file. Like ``%config(noreplace)`` or any other directive
- that be found in the ``%files`` section. You can have multiple directives
- per line, as in ``%attr(600,root,root) %config(noreplace)``. Since
+ that be found in the ``%files`` section. Since
  the CPack RPM generator is generating the list of files (and directories) the
  user specified files of the ``CPACK_RPM_<COMPONENT>_USER_FILELIST`` list will
  be removed from the generated list. If referring to directories do
  not add a trailing slash.
 
+ .. versionadded:: 3.8
+  You can have multiple directives per line, as in
+  ``%attr(600,root,root) %config(noreplace)``.
+
 .. variable:: CPACK_RPM_CHANGELOG_FILE
 
  RPM changelog file.
@@ -555,6 +598,9 @@
  the default path. If you want to add some path to the default list then you
  can use :variable:`CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION` variable.
 
+ .. versionadded:: 3.10
+  Added ``/usr/share/aclocal`` to the default list of excludes.
+
 .. variable:: CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION
 
  additional list of path to be excluded.
@@ -568,6 +614,8 @@
 
 .. variable:: CPACK_RPM_RELOCATION_PATHS
 
+ .. versionadded:: 3.2
+
  Packages relocation paths list.
 
  * Mandatory : NO
@@ -591,6 +639,8 @@
 
 .. variable:: CPACK_RPM_<COMPONENT>_PACKAGE_PREFIX
 
+ .. versionadded:: 3.2
+
  Per component relocation path install prefix.
 
  * Mandatory : NO
@@ -602,6 +652,8 @@
 .. variable:: CPACK_RPM_NO_INSTALL_PREFIX_RELOCATION
               CPACK_RPM_NO_<COMPONENT>_INSTALL_PREFIX_RELOCATION
 
+ .. versionadded:: 3.3
+
  Removal of default install prefix from relocation paths list.
 
  * Mandatory : NO
@@ -613,6 +665,8 @@
 
 .. variable:: CPACK_RPM_ADDITIONAL_MAN_DIRS
 
+ .. versionadded:: 3.3
+
  * Mandatory : NO
  * Default   : -
 
@@ -641,6 +695,8 @@
 .. variable:: CPACK_RPM_DEFAULT_USER
               CPACK_RPM_<compName>_DEFAULT_USER
 
+ .. versionadded:: 3.6
+
  default user ownership of RPM content
 
  * Mandatory : NO
@@ -652,6 +708,8 @@
 .. variable:: CPACK_RPM_DEFAULT_GROUP
               CPACK_RPM_<compName>_DEFAULT_GROUP
 
+ .. versionadded:: 3.6
+
  default group ownership of RPM content
 
  * Mandatory : NO
@@ -663,6 +721,8 @@
 .. variable:: CPACK_RPM_DEFAULT_FILE_PERMISSIONS
               CPACK_RPM_<compName>_DEFAULT_FILE_PERMISSIONS
 
+ .. versionadded:: 3.6
+
  default permissions used for packaged files
 
  * Mandatory : NO
@@ -686,6 +746,8 @@
 .. variable:: CPACK_RPM_DEFAULT_DIR_PERMISSIONS
               CPACK_RPM_<compName>_DEFAULT_DIR_PERMISSIONS
 
+ .. versionadded:: 3.6
+
  default permissions used for packaged directories
 
  * Mandatory : NO
@@ -697,6 +759,8 @@
 
 .. variable:: CPACK_RPM_INSTALL_WITH_EXEC
 
+ .. versionadded:: 3.11
+
  force execute permissions on programs and shared libraries
 
  * Mandatory : NO
@@ -714,6 +778,8 @@
 Packaging of Symbolic Links
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
+.. versionadded:: 3.3
+
 The CPack RPM generator supports packaging of symbolic links::
 
   execute_process(COMMAND ${CMAKE_COMMAND}
@@ -731,8 +797,10 @@
 while determining if symlink should be either created or present in a
 post install script - depending on relocation paths.
 
-Symbolic links that point to locations outside packaging path produce a
-warning and are treated as non relocatable permanent symbolic links.
+.. versionchanged:: 3.6
+ Symbolic links that point to locations outside packaging path produce a
+ warning and are treated as non relocatable permanent symbolic links.
+ Previous versions of CMake produced an error in this case.
 
 Currently there are a few limitations though:
 
@@ -750,6 +818,8 @@
 Packaging of debug information
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
+.. versionadded:: 3.7
+
 Debuginfo packages contain debug symbols and sources for debugging packaged
 binaries.
 
@@ -832,6 +902,8 @@
 
 .. variable:: CPACK_RPM_DEBUGINFO_SINGLE_PACKAGE
 
+ .. versionadded:: 3.8
+
  Create a single debuginfo package even if components packaging is set.
 
  * Mandatory : NO
@@ -853,6 +925,8 @@
 .. variable:: CPACK_RPM_DEBUGINFO_FILE_NAME
               CPACK_RPM_<component>_DEBUGINFO_FILE_NAME
 
+ .. versionadded:: 3.9
+
  Debuginfo package file name.
 
  * Mandatory : NO
@@ -877,6 +951,8 @@
 Packaging of sources (SRPM)
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
+.. versionadded:: 3.7
+
 SRPM packaging is enabled by setting :variable:`CPACK_RPM_PACKAGE_SOURCES`
 variable while usually using :variable:`CPACK_INSTALLED_DIRECTORIES` variable
 to provide directory containing CMakeLists.txt and source files.
diff --git a/Help/cpack_gen/wix.rst b/Help/cpack_gen/wix.rst
index 5b880ba..79f835e 100644
--- a/Help/cpack_gen/wix.rst
+++ b/Help/cpack_gen/wix.rst
@@ -3,6 +3,9 @@
 
 CPack WIX generator specific options
 
+.. versionadded:: 3.7
+  Support :variable:`CPACK_COMPONENT_<compName>_DISABLED` variable.
+
 Variables specific to CPack WIX generator
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
@@ -95,9 +98,10 @@
 
  If this variable is not set, it will be initialized with CPACK_PACKAGE_NAME
 
- If this variable is set to ``.``, then application shortcuts will be
- created directly in the start menu and the uninstaller shortcut will be
- omitted.
+ .. versionadded:: 3.16
+  If this variable is set to ``.``, then application shortcuts will be
+  created directly in the start menu and the uninstaller shortcut will be
+  omitted.
 
 .. variable:: CPACK_WIX_CULTURES
 
@@ -123,7 +127,10 @@
 .. variable:: CPACK_WIX_PATCH_FILE
 
  Optional list of XML files with fragments to be inserted into
- generated WiX sources
+ generated WiX sources.
+
+ .. versionadded:: 3.5
+  Support listing multiple patch files.
 
  This optional variable can be used to specify an XML file that the
  WIX generator will use to inject fragments into its generated
@@ -152,10 +159,17 @@
  Currently fragments can be injected into most
  Component, File, Directory and Feature elements.
 
- The following additional special Ids can be used:
+ .. versionadded:: 3.3
+  The following additional special Ids can be used:
 
- * ``#PRODUCT`` for the ``<Product>`` element.
- * ``#PRODUCTFEATURE`` for the root ``<Feature>`` element.
+  * ``#PRODUCT`` for the ``<Product>`` element.
+  * ``#PRODUCTFEATURE`` for the root ``<Feature>`` element.
+
+ .. versionadded:: 3.7
+  Support patching arbitrary ``<Feature>`` elements.
+
+ .. versionadded:: 3.9
+  Allow setting additional attributes.
 
  The following example illustrates how this works.
 
@@ -227,6 +241,8 @@
 
 .. variable:: CPACK_WIX_PROPERTY_<PROPERTY>
 
+ .. versionadded:: 3.1
+
  This variable can be used to provide a value for
  the Windows Installer property ``<PROPERTY>``
 
@@ -243,16 +259,22 @@
 
 .. variable:: CPACK_WIX_ROOT_FEATURE_TITLE
 
+ .. versionadded:: 3.7
+
  Sets the name of the root install feature in the WIX installer. Same as
  CPACK_COMPONENT_<compName>_DISPLAY_NAME for components.
 
 .. variable:: CPACK_WIX_ROOT_FEATURE_DESCRIPTION
 
+ .. versionadded:: 3.7
+
  Sets the description of the root install feature in the WIX installer. Same as
  CPACK_COMPONENT_<compName>_DESCRIPTION for components.
 
 .. variable:: CPACK_WIX_SKIP_PROGRAM_FOLDER
 
+ .. versionadded:: 3.7
+
  If this variable is set to true, the default install location
  of the generated package will be CPACK_PACKAGE_INSTALL_DIRECTORY directly.
  The install location will not be located relatively below
@@ -270,6 +292,8 @@
 
 .. variable:: CPACK_WIX_ROOT_FOLDER_ID
 
+ .. versionadded:: 3.9
+
  This variable allows specification of a custom root folder ID.
  The generator specific ``<64>`` token can be used for
  folder IDs that come in 32-bit and 64-bit variants.
@@ -289,6 +313,8 @@
 
 .. variable:: CPACK_WIX_CUSTOM_XMLNS
 
+ .. versionadded:: 3.19
+
  This variable provides a list of custom namespace declarations that are necessary
  for using WiX extensions. Each declaration should be in the form name=url, where
  name is the plain namespace without the usual xmlns: prefix and url is an unquoted
diff --git a/Help/dev/maint.rst b/Help/dev/maint.rst
index 75d685c..664b7a4 100644
--- a/Help/dev/maint.rst
+++ b/Help/dev/maint.rst
@@ -357,3 +357,13 @@
   The files generatd by `install(EXPORT)` and `export()` commands
   are known to work with policies as of CMake $prev, so enable them
   in sufficiently new CMake versions.
+
+Update the ``cmake_minimum_required`` version range in CMake itself:
+
+* ``CMakeLists.txt``
+* ``Utilities/Doxygen/CMakeLists.txt``
+* ``Utilities/Sphinx/CMakeLists.txt``
+
+to end in the previous release.  Commit with a message such as::
+
+  Configure CMake itself with policies through CMake $prev
diff --git a/Help/generator/CodeBlocks.rst b/Help/generator/CodeBlocks.rst
index d830542..85da715 100644
--- a/Help/generator/CodeBlocks.rst
+++ b/Help/generator/CodeBlocks.rst
@@ -7,13 +7,15 @@
 in every subdirectory which features a ``CMakeLists.txt`` file containing
 a :command:`project` call.  Additionally a hierarchy of makefiles is generated
 into the build tree.
-The :variable:`CMAKE_CODEBLOCKS_EXCLUDE_EXTERNAL_FILES` variable may
-be set to ``ON`` to exclude any files which are located outside of
-the project root directory.
 The appropriate make program can build the
 project through the default ``all`` target.  An ``install`` target is
 also provided.
 
+.. versionadded:: 3.10
+ The :variable:`CMAKE_CODEBLOCKS_EXCLUDE_EXTERNAL_FILES` variable may
+ be set to ``ON`` to exclude any files which are located outside of
+ the project root directory.
+
 This "extra" generator may be specified as:
 
 ``CodeBlocks - MinGW Makefiles``
@@ -23,7 +25,8 @@
  Generate with :generator:`NMake Makefiles`.
 
 ``CodeBlocks - NMake Makefiles JOM``
- Generate with :generator:`NMake Makefiles JOM`.
+ .. versionadded:: 3.8
+  Generate with :generator:`NMake Makefiles JOM`.
 
 ``CodeBlocks - Ninja``
  Generate with :generator:`Ninja`.
diff --git a/Help/generator/CodeLite.rst b/Help/generator/CodeLite.rst
index 46fa5be..4f276df 100644
--- a/Help/generator/CodeLite.rst
+++ b/Help/generator/CodeLite.rst
@@ -6,13 +6,15 @@
 Project files for CodeLite will be created in the top directory and
 in every subdirectory which features a CMakeLists.txt file containing
 a :command:`project` call.
-The :variable:`CMAKE_CODELITE_USE_TARGETS` variable may be set to ``ON``
-to change the default behavior from projects to targets as the basis
-for project files.
 The appropriate make program can build the
 project through the default ``all`` target.  An ``install`` target
 is also provided.
 
+.. versionadded:: 3.7
+ The :variable:`CMAKE_CODELITE_USE_TARGETS` variable may be set to ``ON``
+ to change the default behavior from projects to targets as the basis
+ for project files.
+
 This "extra" generator may be specified as:
 
 ``CodeLite - MinGW Makefiles``
diff --git a/Help/generator/Green Hills MULTI.rst b/Help/generator/Green Hills MULTI.rst
index 2246699..c25c5f5 100644
--- a/Help/generator/Green Hills MULTI.rst
+++ b/Help/generator/Green Hills MULTI.rst
@@ -3,22 +3,36 @@
 
 .. versionadded:: 3.3
 
+.. versionadded:: 3.15
+  Linux support.
+
 Generates Green Hills MULTI project files (experimental, work-in-progress).
 
-The buildsystem has predetermined build-configuration settings that can be controlled
-via the :variable:`CMAKE_BUILD_TYPE` variable.
+Customizations are available through the following cache variables:
+
+* ``GHS_CUSTOMIZATION``
+* ``GHS_GPJ_MACROS``
+
+.. versionadded:: 3.14
+  The buildsystem has predetermined build-configuration settings that can be controlled
+  via the :variable:`CMAKE_BUILD_TYPE` variable.
+
+Toolset and Platform Selection
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. versionadded:: 3.13
 
 Customizations that are used to pick toolset and target system:
 
-The ``-A <arch>`` can be supplied for setting the target architecture.
-``<arch>`` usually is one of ``arm``, ``ppc``, ``86``, etcetera.
-If the target architecture is not specified then
-the default architecture of ``arm`` will be used.
+* The ``-A <arch>`` can be supplied for setting the target architecture.
+  ``<arch>`` usually is one of ``arm``, ``ppc``, ``86``, etcetera.
+  If the target architecture is not specified then
+  the default architecture of ``arm`` will be used.
 
-The ``-T <toolset>`` option can be used to set the directory location of the toolset.
-Both absolute and relative paths are valid. Relative paths use ``GHS_TOOLSET_ROOT``
-as the root. If the toolset is not specified then the latest toolset found in
-``GHS_TOOLSET_ROOT`` will be used.
+* The ``-T <toolset>`` option can be used to set the directory location of the toolset.
+  Both absolute and relative paths are valid. Relative paths use ``GHS_TOOLSET_ROOT``
+  as the root. If the toolset is not specified then the latest toolset found in
+  ``GHS_TOOLSET_ROOT`` will be used.
 
 Cache variables that are used for toolset and target system customization:
 
@@ -50,15 +64,18 @@
     a specific RTOS is to be used.
   | ``GHS_OS_DIR_OPTION`` default value is ``-os_dir``.
 
+  .. versionadded:: 3.15
+    ``GHS_OS_DIR_OPTION`` variable.
+
 * ``GHS_BSP_NAME``
 
   | Sets ``-bsp`` entry in project file.
   | Defaults to ``sim<arch>`` for ``integrity`` platforms.
 
-Customizations are available through the following cache variables:
+Target Properties
+^^^^^^^^^^^^^^^^^
 
-* ``GHS_CUSTOMIZATION``
-* ``GHS_GPJ_MACROS``
+.. versionadded:: 3.14
 
 The following properties are available:
 
diff --git a/Help/generator/NMake Makefiles JOM.rst b/Help/generator/NMake Makefiles JOM.rst
index 3a8744c..e0f4c90 100644
--- a/Help/generator/NMake Makefiles JOM.rst
+++ b/Help/generator/NMake Makefiles JOM.rst
@@ -2,3 +2,6 @@
 -------------------
 
 Generates JOM makefiles.
+
+.. versionadded:: 3.8
+  :generator:`CodeBlocks` generator can be used as an extra generator.
diff --git a/Help/generator/Ninja.rst b/Help/generator/Ninja.rst
index 08ee81b..f3ba222 100644
--- a/Help/generator/Ninja.rst
+++ b/Help/generator/Ninja.rst
@@ -11,32 +11,57 @@
 are generated:
 
 ``sub/dir/all``
-  Depends on all targets required by the subdirectory.
+
+  .. versionadded:: 3.6
+
+    Depends on all targets required by the subdirectory.
 
 ``sub/dir/install``
-  Runs the install step in the subdirectory, if any.
+
+  .. versionadded:: 3.7
+
+    Runs the install step in the subdirectory, if any.
 
 ``sub/dir/install/strip``
-  Runs the install step in the subdirectory followed by a ``CMAKE_STRIP`` command,
-  if any.
 
-  The ``CMAKE_STRIP`` variable will contain the platform's ``strip`` utility, which
-  removes symbols information from generated binaries.
+  .. versionadded:: 3.7
+    Runs the install step in the subdirectory followed by a ``CMAKE_STRIP`` command,
+    if any.
+
+    The ``CMAKE_STRIP`` variable will contain the platform's ``strip`` utility, which
+    removes symbols information from generated binaries.
 
 ``sub/dir/test``
-  Runs the test step in the subdirectory, if any.
+
+  .. versionadded:: 3.7
+
+    Runs the test step in the subdirectory, if any.
 
 ``sub/dir/package``
-  Runs the package step in the subdirectory, if any.
+
+  .. versionadded:: 3.7
+
+    Runs the package step in the subdirectory, if any.
 
 Fortran Support
 ^^^^^^^^^^^^^^^
 
+.. versionadded:: 3.7
+
 The ``Ninja`` generator conditionally supports Fortran when the ``ninja``
 tool is at least version 1.10 (which has the required features).
 
+Swift Support
+^^^^^^^^^^^^^
+
+.. versionadded:: 3.15
+
+The Swift support is experimental, not considered stable, and may change
+in future releases of CMake.
+
 See Also
 ^^^^^^^^
 
-The :generator:`Ninja Multi-Config` generator is similar to the ``Ninja``
-generator, but generates multiple configurations at once.
+.. versionadded:: 3.17
+  The :generator:`Ninja Multi-Config` generator is similar to the ``Ninja``
+  generator, but generates multiple configurations at once.
diff --git a/Help/generator/VS_TOOLSET_HOST_ARCH.txt b/Help/generator/VS_TOOLSET_HOST_ARCH.txt
index 0293631..e361719 100644
--- a/Help/generator/VS_TOOLSET_HOST_ARCH.txt
+++ b/Help/generator/VS_TOOLSET_HOST_ARCH.txt
@@ -1,7 +1,11 @@
-For each toolset that comes with this version of Visual Studio, there are
-variants that are themselves compiled for 32-bit (``x86``) and
-64-bit (``x64``) hosts (independent of the architecture they target).
-|VS_TOOLSET_HOST_ARCH_DEFAULT|
-One may explicitly request use of either the 32-bit or 64-bit host tools
-by adding either ``host=x86`` or ``host=x64`` to the toolset specification.
-See the :variable:`CMAKE_GENERATOR_TOOLSET` variable for details.
+.. versionadded:: 3.8
+  For each toolset that comes with this version of Visual Studio, there are
+  variants that are themselves compiled for 32-bit (``x86``) and
+  64-bit (``x64``) hosts (independent of the architecture they target).
+  |VS_TOOLSET_HOST_ARCH_DEFAULT|
+  One may explicitly request use of either the 32-bit or 64-bit host tools
+  by adding either ``host=x86`` or ``host=x64`` to the toolset specification.
+  See the :variable:`CMAKE_GENERATOR_TOOLSET` variable for details.
+
+.. versionadded:: 3.14
+  Added suport for ``host=x86`` option.
diff --git a/Help/generator/Visual Studio 10 2010.rst b/Help/generator/Visual Studio 10 2010.rst
index 4bf9a8f..b4376d8 100644
--- a/Help/generator/Visual Studio 10 2010.rst
+++ b/Help/generator/Visual Studio 10 2010.rst
@@ -17,13 +17,14 @@
 
 The default target platform name (architecture) is ``Win32``.
 
-The :variable:`CMAKE_GENERATOR_PLATFORM` variable may be set, perhaps
-via the :manual:`cmake(1)` ``-A`` option, to specify a target platform
-name (architecture).  For example:
+.. versionadded:: 3.1
+  The :variable:`CMAKE_GENERATOR_PLATFORM` variable may be set, perhaps
+  via the :manual:`cmake(1)` ``-A`` option, to specify a target platform
+  name (architecture).  For example:
 
-* ``cmake -G "Visual Studio 10 2010" -A Win32``
-* ``cmake -G "Visual Studio 10 2010" -A x64``
-* ``cmake -G "Visual Studio 10 2010" -A Itanium``
+  * ``cmake -G "Visual Studio 10 2010" -A Win32``
+  * ``cmake -G "Visual Studio 10 2010" -A x64``
+  * ``cmake -G "Visual Studio 10 2010" -A Itanium``
 
 For compatibility with CMake versions prior to 3.1, one may specify
 a target platform name optionally at the end of the generator name.
diff --git a/Help/generator/Visual Studio 11 2012.rst b/Help/generator/Visual Studio 11 2012.rst
index 5d89a6e..932548b 100644
--- a/Help/generator/Visual Studio 11 2012.rst
+++ b/Help/generator/Visual Studio 11 2012.rst
@@ -17,15 +17,16 @@
 
 The default target platform name (architecture) is ``Win32``.
 
-The :variable:`CMAKE_GENERATOR_PLATFORM` variable may be set, perhaps
-via the :manual:`cmake(1)` ``-A`` option, to specify a target platform
-name (architecture).  For example:
+.. versionadded:: 3.1
+  The :variable:`CMAKE_GENERATOR_PLATFORM` variable may be set, perhaps
+  via the :manual:`cmake(1)` ``-A`` option, to specify a target platform
+  name (architecture).  For example:
 
-* ``cmake -G "Visual Studio 11 2012" -A Win32``
-* ``cmake -G "Visual Studio 11 2012" -A x64``
-* ``cmake -G "Visual Studio 11 2012" -A ARM``
-* ``cmake -G "Visual Studio 11 2012" -A <WinCE-SDK>``
-  (Specify a target platform matching a Windows CE SDK name.)
+  * ``cmake -G "Visual Studio 11 2012" -A Win32``
+  * ``cmake -G "Visual Studio 11 2012" -A x64``
+  * ``cmake -G "Visual Studio 11 2012" -A ARM``
+  * ``cmake -G "Visual Studio 11 2012" -A <WinCE-SDK>``
+    (Specify a target platform matching a Windows CE SDK name.)
 
 For compatibility with CMake versions prior to 3.1, one may specify
 a target platform name optionally at the end of the generator name.
diff --git a/Help/generator/Visual Studio 12 2013.rst b/Help/generator/Visual Studio 12 2013.rst
index fb8e021..b5fa1bf 100644
--- a/Help/generator/Visual Studio 12 2013.rst
+++ b/Help/generator/Visual Studio 12 2013.rst
@@ -17,13 +17,14 @@
 
 The default target platform name (architecture) is ``Win32``.
 
-The :variable:`CMAKE_GENERATOR_PLATFORM` variable may be set, perhaps
-via the :manual:`cmake(1)` ``-A`` option, to specify a target platform
-name (architecture).  For example:
+.. versionadded:: 3.1
+  The :variable:`CMAKE_GENERATOR_PLATFORM` variable may be set, perhaps
+  via the :manual:`cmake(1)` ``-A`` option, to specify a target platform
+  name (architecture).  For example:
 
-* ``cmake -G "Visual Studio 12 2013" -A Win32``
-* ``cmake -G "Visual Studio 12 2013" -A x64``
-* ``cmake -G "Visual Studio 12 2013" -A ARM``
+  * ``cmake -G "Visual Studio 12 2013" -A Win32``
+  * ``cmake -G "Visual Studio 12 2013" -A x64``
+  * ``cmake -G "Visual Studio 12 2013" -A ARM``
 
 For compatibility with CMake versions prior to 3.1, one may specify
 a target platform name optionally at the end of the generator name.
diff --git a/Help/generator/Visual Studio 14 2015.rst b/Help/generator/Visual Studio 14 2015.rst
index 5b319bb..9c61641 100644
--- a/Help/generator/Visual Studio 14 2015.rst
+++ b/Help/generator/Visual Studio 14 2015.rst
@@ -51,6 +51,8 @@
 Windows 10 SDK Maximum Version for VS 2015
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
+.. versionadded:: 3.19
+
 Microsoft stated in a "Windows 10 October 2018 Update" blog post that Windows
 10 SDK versions (15063, 16299, 17134, 17763) are not supported by VS 2015 and
 are only supported by VS 2017 and later.  Therefore by default CMake
diff --git a/Help/generator/Visual Studio 15 2017.rst b/Help/generator/Visual Studio 15 2017.rst
index e7baaad..a002f2f 100644
--- a/Help/generator/Visual Studio 15 2017.rst
+++ b/Help/generator/Visual Studio 15 2017.rst
@@ -14,18 +14,20 @@
 Instance Selection
 ^^^^^^^^^^^^^^^^^^
 
-VS 2017 supports multiple installations on the same machine.
-The :variable:`CMAKE_GENERATOR_INSTANCE` variable may be set as a
-cache entry containing the absolute path to a Visual Studio instance.
-If the value is not specified explicitly by the user or a toolchain file,
-CMake queries the Visual Studio Installer to locate VS instances, chooses
-one, and sets the variable as a cache entry to hold the value persistently.
+.. versionadded:: 3.9
+  VS 2017 supports multiple installations on the same machine.
+  The :variable:`CMAKE_GENERATOR_INSTANCE` variable may be set as a
+  cache entry containing the absolute path to a Visual Studio instance.
+  If the value is not specified explicitly by the user or a toolchain file,
+  CMake queries the Visual Studio Installer to locate VS instances, chooses
+  one, and sets the variable as a cache entry to hold the value persistently.
 
-When CMake first chooses an instance, if the ``VS150COMNTOOLS`` environment
-variable is set and points to the ``Common7/Tools`` directory within
-one of the instances, that instance will be used.  Otherwise, if more
-than one instance is installed we do not define which one is chosen
-by default.
+.. versionadded:: 3.11
+  When CMake first chooses an instance, if the ``VS150COMNTOOLS`` environment
+  variable is set and points to the ``Common7/Tools`` directory within
+  one of the instances, that instance will be used.  Otherwise, if more
+  than one instance is installed we do not define which one is chosen
+  by default.
 
 Platform Selection
 ^^^^^^^^^^^^^^^^^^
diff --git a/Help/generator/Visual Studio 9 2008.rst b/Help/generator/Visual Studio 9 2008.rst
index a09d047..644f936 100644
--- a/Help/generator/Visual Studio 9 2008.rst
+++ b/Help/generator/Visual Studio 9 2008.rst
@@ -8,15 +8,16 @@
 
 The default target platform name (architecture) is ``Win32``.
 
-The :variable:`CMAKE_GENERATOR_PLATFORM` variable may be set, perhaps
-via the :manual:`cmake(1)` ``-A`` option, to specify a target platform
-name (architecture).  For example:
+.. versionadded:: 3.1
+  The :variable:`CMAKE_GENERATOR_PLATFORM` variable may be set, perhaps
+  via the :manual:`cmake(1)` ``-A`` option, to specify a target platform
+  name (architecture).  For example:
 
-* ``cmake -G "Visual Studio 9 2008" -A Win32``
-* ``cmake -G "Visual Studio 9 2008" -A x64``
-* ``cmake -G "Visual Studio 9 2008" -A Itanium``
-* ``cmake -G "Visual Studio 9 2008" -A <WinCE-SDK>``
-  (Specify a target platform matching a Windows CE SDK name.)
+  * ``cmake -G "Visual Studio 9 2008" -A Win32``
+  * ``cmake -G "Visual Studio 9 2008" -A x64``
+  * ``cmake -G "Visual Studio 9 2008" -A Itanium``
+  * ``cmake -G "Visual Studio 9 2008" -A <WinCE-SDK>``
+    (Specify a target platform matching a Windows CE SDK name.)
 
 For compatibility with CMake versions prior to 3.1, one may specify
 a target platform name optionally at the end of the generator name.
diff --git a/Help/generator/Xcode.rst b/Help/generator/Xcode.rst
index be03a22..e4900a1 100644
--- a/Help/generator/Xcode.rst
+++ b/Help/generator/Xcode.rst
@@ -3,7 +3,8 @@
 
 Generate Xcode project files.
 
-This supports Xcode 5.0 and above.
+.. versionchanged:: 3.15
+  This generator supports Xcode 5.0 and above.
 
 .. _`Xcode Build System Selection`:
 
@@ -14,7 +15,8 @@
 The :variable:`CMAKE_GENERATOR_TOOLSET` option may be set, perhaps
 via the :manual:`cmake(1)` ``-T`` option, to specify another toolset.
 
-This generator supports toolset specification using one of these forms:
+.. versionadded:: 3.19
+  This generator supports toolset specification using one of these forms:
 
 * ``toolset``
 * ``toolset[,key=value]*``
@@ -33,3 +35,12 @@
 
   For example, to select the original build system under Xcode 12,
   run :manual:`cmake(1)` with the option ``-T buildsystem=1``.
+
+Swift Support
+^^^^^^^^^^^^^
+
+.. versionadded:: 3.4
+
+When using the :generator:`Xcode` generator with Xcode 6.1 or higher,
+one may enable the ``Swift`` language with the :command:`enable_language`
+command or the :command:`project`.
diff --git a/Help/guide/ide-integration/index.rst b/Help/guide/ide-integration/index.rst
index 8ea31a0..addf932 100644
--- a/Help/guide/ide-integration/index.rst
+++ b/Help/guide/ide-integration/index.rst
@@ -82,8 +82,8 @@
 artifacts. Such information can be obtained by using the
 :manual:`File API <cmake-file-api(7)>`. The manual page for the File API
 contains more information about the API and how to invoke it.
-:manual:`Server mode <cmake-server(7)>` is deprecated and should not be
-used on CMake 3.14 or later.
+:manual:`Server mode <cmake-server(7)>` was removed as of CMake 3.20 and
+should not be used on CMake 3.14 or later.
 
 IDEs should avoid creating more build trees than necessary, and only create
 multiple build trees if the user wishes to switch to a different compiler,
diff --git a/Help/manual/cmake-commands.7.rst b/Help/manual/cmake-commands.7.rst
index 0aa4f75..036fa8f 100644
--- a/Help/manual/cmake-commands.7.rst
+++ b/Help/manual/cmake-commands.7.rst
@@ -20,6 +20,7 @@
    /command/cmake_language
    /command/cmake_minimum_required
    /command/cmake_parse_arguments
+   /command/cmake_path
    /command/cmake_policy
    /command/configure_file
    /command/continue
diff --git a/Help/manual/cmake-modules.7.rst b/Help/manual/cmake-modules.7.rst
index 14af149..e90c9ee 100644
--- a/Help/manual/cmake-modules.7.rst
+++ b/Help/manual/cmake-modules.7.rst
@@ -97,9 +97,7 @@
    /module/TestForSSTREAM
    /module/TestForSTDNamespace
    /module/UseEcos
-   /module/UseJavaClassFilelist
    /module/UseJava
-   /module/UseJavaSymlinks
    /module/UseSWIG
    /module/UsewxWidgets
    /module/WriteCompilerDetectionHeader
diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst
index fa10f66..03eb93e 100644
--- a/Help/manual/cmake-policies.7.rst
+++ b/Help/manual/cmake-policies.7.rst
@@ -51,6 +51,16 @@
 to determine whether to report an error on use of deprecated macros or
 functions.
 
+Policies Introduced by CMake 3.20
+=================================
+
+.. toctree::
+   :maxdepth: 1
+
+   CMP0117: MSVC RTTI flag /GR is not added to CMAKE_CXX_FLAGS by default. </policy/CMP0117>
+   CMP0116: Ninja generators transform DEPFILEs from add_custom_command(). </policy/CMP0116>
+   CMP0115: Source file extensions must be explicit. </policy/CMP0115>
+
 Policies Introduced by CMake 3.19
 =================================
 
diff --git a/Help/manual/cmake-server.7.rst b/Help/manual/cmake-server.7.rst
index 8f10b9f..6c8d0f4 100644
--- a/Help/manual/cmake-server.7.rst
+++ b/Help/manual/cmake-server.7.rst
@@ -3,742 +3,5 @@
 cmake-server(7)
 ***************
 
-.. only:: html
-
-   .. contents::
-
-.. deprecated:: 3.15
-
-  This will be removed from a future version of CMake.
-  Clients should use the :manual:`cmake-file-api(7)` instead.
-
-Introduction
-============
-
-:manual:`cmake(1)` is capable of providing semantic information about
-CMake code it executes to generate a buildsystem.  If executed with
-the ``-E server`` command line options, it starts in a long running mode
-and allows a client to request the available information via a JSON protocol.
-
-The protocol is designed to be useful to IDEs, refactoring tools, and
-other tools which have a need to understand the buildsystem in entirety.
-
-A single :manual:`cmake-buildsystem(7)` may describe buildsystem contents
-and build properties which differ based on
-:manual:`generation-time context <cmake-generator-expressions(7)>`
-including:
-
-* The Platform (eg, Windows, APPLE, Linux).
-* The build configuration (eg, Debug, Release, Coverage).
-* The Compiler (eg, MSVC, GCC, Clang) and compiler version.
-* The language of the source files compiled.
-* Available compile features (eg CXX variadic templates).
-* CMake policies.
-
-The protocol aims to provide information to tooling to satisfy several
-needs:
-
-#. Provide a complete and easily parsed source of all information relevant
-   to the tooling as it relates to the source code.  There should be no need
-   for tooling to parse generated buildsystems to access include directories
-   or compile definitions for example.
-#. Semantic information about the CMake buildsystem itself.
-#. Provide a stable interface for reading the information in the CMake cache.
-#. Information for determining when cmake needs to be re-run as a result of
-   file changes.
-
-
-Operation
-=========
-
-Start :manual:`cmake(1)` in the server command mode, supplying the path to
-the build directory to process::
-
-  cmake -E server (--debug|--pipe=<NAMED_PIPE>)
-
-The server will communicate using stdin/stdout (with the ``--debug`` parameter)
-or using a named pipe (with the ``--pipe=<NAMED_PIPE>`` parameter).  Note
-that "named pipe" refers to a local domain socket on Unix and to a named pipe
-on Windows.
-
-When connecting to the server (via named pipe or by starting it in ``--debug``
-mode), the server will reply with a hello message::
-
-  [== "CMake Server" ==[
-  {"supportedProtocolVersions":[{"major":1,"minor":0}],"type":"hello"}
-  ]== "CMake Server" ==]
-
-Messages sent to and from the process are wrapped in magic strings::
-
-  [== "CMake Server" ==[
-  {
-    ... some JSON message ...
-  }
-  ]== "CMake Server" ==]
-
-The server is now ready to accept further requests via the named pipe
-or stdin.
-
-
-Debugging
-=========
-
-CMake server mode can be asked to provide statistics on execution times, etc.
-or to dump a copy of the response into a file. This is done passing a "debug"
-JSON object as a child of the request.
-
-The debug object supports the "showStats" key, which takes a boolean and makes
-the server mode return a "zzzDebug" object with stats as part of its response.
-"dumpToFile" takes a string value and will cause the cmake server to copy
-the response into the given filename.
-
-This is a response from the cmake server with "showStats" set to true::
-
-  [== "CMake Server" ==[
-  {
-    "cookie":"",
-    "errorMessage":"Waiting for type \"handshake\".",
-    "inReplyTo":"unknown",
-   "type":"error",
-    "zzzDebug": {
-      "dumpFile":"/tmp/error.txt",
-      "jsonSerialization":0.011016,
-      "size":111,
-      "totalTime":0.025995
-    }
-  }
-  ]== "CMake Server" ==]
-
-The server has made a copy of this response into the file /tmp/error.txt and
-took 0.011 seconds to turn the JSON response into a string, and it took 0.025
-seconds to process the request in total. The reply has a size of 111 bytes.
-
-
-Protocol API
-============
-
-
-General Message Layout
-----------------------
-
-All messages need to have a "type" value, which identifies the type of
-message that is passed back or forth. E.g. the initial message sent by the
-server is of type "hello". Messages without a type will generate an response
-of type "error".
-
-All requests sent to the server may contain a "cookie" value. This value
-will he handed back unchanged in all responses triggered by the request.
-
-All responses will contain a value "inReplyTo", which may be empty in
-case of parse errors, but will contain the type of the request message
-in all other cases.
-
-
-Type "reply"
-^^^^^^^^^^^^
-
-This type is used by the server to reply to requests.
-
-The message may -- depending on the type of the original request --
-contain values.
-
-Example::
-
-  [== "CMake Server" ==[
-  {"cookie":"zimtstern","inReplyTo":"handshake","type":"reply"}
-  ]== "CMake Server" ==]
-
-
-Type "error"
-^^^^^^^^^^^^
-
-This type is used to return an error condition to the client. It will
-contain an "errorMessage".
-
-Example::
-
-  [== "CMake Server" ==[
-  {"cookie":"","errorMessage":"Protocol version not supported.","inReplyTo":"handshake","type":"error"}
-  ]== "CMake Server" ==]
-
-
-Type "progress"
-^^^^^^^^^^^^^^^
-
-When the server is busy for a long time, it is polite to send back replies of
-type "progress" to the client. These will contain a "progressMessage" with a
-string describing the action currently taking place as well as
-"progressMinimum", "progressMaximum" and "progressCurrent" with integer values
-describing the range of progress.
-
-Messages of type "progress" will be followed by more "progress" messages or with
-a message of type "reply" or "error" that complete the request.
-
-"progress" messages may not be emitted after the "reply" or "error" message for
-the request that triggered the responses was delivered.
-
-
-Type "message"
-^^^^^^^^^^^^^^
-
-A message is triggered when the server processes a request and produces some
-form of output that should be displayed to the user. A Message has a "message"
-with the actual text to display as well as a "title" with a suggested dialog
-box title.
-
-Example::
-
-  [== "CMake Server" ==[
-  {"cookie":"","message":"Something happened.","title":"Title Text","inReplyTo":"handshake","type":"message"}
-  ]== "CMake Server" ==]
-
-
-Type "signal"
-^^^^^^^^^^^^^
-
-The server can send signals when it detects changes in the system state. Signals
-are of type "signal", have an empty "cookie" and "inReplyTo" field and always
-have a "name" set to show which signal was sent.
-
-
-Specific Signals
-----------------
-
-The cmake server may sent signals with the following names:
-
-"dirty" Signal
-^^^^^^^^^^^^^^
-
-The "dirty" signal is sent whenever the server determines that the configuration
-of the project is no longer up-to-date. This happens when any of the files that have
-an influence on the build system is changed.
-
-The "dirty" signal may look like this::
-
-  [== "CMake Server" ==[
-  {
-    "cookie":"",
-    "inReplyTo":"",
-    "name":"dirty",
-    "type":"signal"}
-  ]== "CMake Server" ==]
-
-
-"fileChange" Signal
-^^^^^^^^^^^^^^^^^^^
-
-The "fileChange" signal is sent whenever a watched file is changed. It contains
-the "path" that has changed and a list of "properties" with the kind of change
-that was detected. Possible changes are "change" and "rename".
-
-The "fileChange" signal looks like this::
-
-  [== "CMake Server" ==[
-  {
-    "cookie":"",
-    "inReplyTo":"",
-    "name":"fileChange",
-    "path":"/absolute/CMakeLists.txt",
-    "properties":["change"],
-    "type":"signal"}
-  ]== "CMake Server" ==]
-
-
-Specific Message Types
-----------------------
-
-
-Type "hello"
-^^^^^^^^^^^^
-
-The initial message send by the cmake server on startup is of type "hello".
-This is the only message ever sent by the server that is not of type "reply",
-"progress" or "error".
-
-It will contain "supportedProtocolVersions" with an array of server protocol
-versions supported by the cmake server. These are JSON objects with "major" and
-"minor" keys containing non-negative integer values. Some versions may be marked
-as experimental. These will contain the "isExperimental" key set to true. Enabling
-these requires a special command line argument when starting the cmake server mode.
-
-Within a "major" version all "minor" versions are fully backwards compatible.
-New "minor" versions may introduce functionality in such a way that existing
-clients of the same "major" version will continue to work, provided they
-ignore keys in the output that they do not know about.
-
-Example::
-
-  [== "CMake Server" ==[
-  {"supportedProtocolVersions":[{"major":0,"minor":1}],"type":"hello"}
-  ]== "CMake Server" ==]
-
-
-Type "handshake"
-^^^^^^^^^^^^^^^^
-
-The first request that the client may send to the server is of type "handshake".
-
-This request needs to pass one of the "supportedProtocolVersions" of the "hello"
-type response received earlier back to the server in the "protocolVersion" field.
-Giving the "major" version of the requested protocol version will make the server
-use the latest minor version of that protocol. Use this if you do not explicitly
-need to depend on a specific minor version.
-
-Protocol version 1.0 requires the following attributes to be set:
-
-  * "sourceDirectory" with a path to the sources
-  * "buildDirectory" with a path to the build directory
-  * "generator" with the generator name
-  * "extraGenerator" (optional!) with the extra generator to be used
-  * "platform" with the generator platform (if supported by the generator)
-  * "toolset" with the generator toolset (if supported by the generator)
-
-Protocol version 1.2 makes all but the build directory optional, provided
-there is a valid cache in the build directory that contains all the other
-information already.
-
-Example::
-
-  [== "CMake Server" ==[
-  {"cookie":"zimtstern","type":"handshake","protocolVersion":{"major":0},
-   "sourceDirectory":"/home/code/cmake", "buildDirectory":"/tmp/testbuild",
-   "generator":"Ninja"}
-  ]== "CMake Server" ==]
-
-which will result in a response type "reply"::
-
-  [== "CMake Server" ==[
-  {"cookie":"zimtstern","inReplyTo":"handshake","type":"reply"}
-  ]== "CMake Server" ==]
-
-indicating that the server is ready for action.
-
-
-Type "globalSettings"
-^^^^^^^^^^^^^^^^^^^^^
-
-This request can be sent after the initial handshake. It will return a
-JSON structure with information on cmake state.
-
-Example::
-
-  [== "CMake Server" ==[
-  {"type":"globalSettings"}
-  ]== "CMake Server" ==]
-
-which will result in a response type "reply"::
-
-  [== "CMake Server" ==[
-  {
-    "buildDirectory": "/tmp/test-build",
-    "capabilities": {
-      "generators": [
-        {
-          "extraGenerators": [],
-          "name": "Watcom WMake",
-          "platformSupport": false,
-          "toolsetSupport": false
-        },
-        <...>
-      ],
-      "serverMode": false,
-      "version": {
-        "isDirty": false,
-        "major": 3,
-        "minor": 6,
-        "patch": 20160830,
-        "string": "3.6.20160830-gd6abad",
-        "suffix": "gd6abad"
-      }
-    },
-    "checkSystemVars": false,
-    "cookie": "",
-    "extraGenerator": "",
-    "generator": "Ninja",
-    "debugOutput": false,
-    "inReplyTo": "globalSettings",
-    "sourceDirectory": "/home/code/cmake",
-    "trace": false,
-    "traceExpand": false,
-    "type": "reply",
-    "warnUninitialized": false,
-    "warnUnused": false,
-    "warnUnusedCli": true
-  }
-  ]== "CMake Server" ==]
-
-
-Type "setGlobalSettings"
-^^^^^^^^^^^^^^^^^^^^^^^^
-
-This request can be sent to change the global settings attributes. Unknown
-attributes are going to be ignored. Read-only attributes reported by
-"globalSettings" are all capabilities, buildDirectory, generator,
-extraGenerator and sourceDirectory. Any attempt to set these will be ignored,
-too.
-
-All other settings will be changed.
-
-The server will respond with an empty reply message or an error.
-
-Example::
-
-  [== "CMake Server" ==[
-  {"type":"setGlobalSettings","debugOutput":true}
-  ]== "CMake Server" ==]
-
-CMake will reply to this with::
-
-  [== "CMake Server" ==[
-  {"inReplyTo":"setGlobalSettings","type":"reply"}
-  ]== "CMake Server" ==]
-
-
-Type "configure"
-^^^^^^^^^^^^^^^^
-
-This request will configure a project for build.
-
-To configure a build directory already containing cmake files, it is enough to
-set "buildDirectory" via "setGlobalSettings". To create a fresh build directory
-you also need to set "currentGenerator" and "sourceDirectory" via "setGlobalSettings"
-in addition to "buildDirectory".
-
-You may a list of strings to "configure" via the "cacheArguments" key. These
-strings will be interpreted similar to command line arguments related to
-cache handling that are passed to the cmake command line client.
-
-Example::
-
-  [== "CMake Server" ==[
-  {"type":"configure", "cacheArguments":["-Dsomething=else"]}
-  ]== "CMake Server" ==]
-
-CMake will reply like this (after reporting progress for some time)::
-
-  [== "CMake Server" ==[
-  {"cookie":"","inReplyTo":"configure","type":"reply"}
-  ]== "CMake Server" ==]
-
-
-Type "compute"
-^^^^^^^^^^^^^^
-
-This request will generate build system files in the build directory and
-is only available after a project was successfully "configure"d.
-
-Example::
-
-  [== "CMake Server" ==[
-  {"type":"compute"}
-  ]== "CMake Server" ==]
-
-CMake will reply (after reporting progress information)::
-
-  [== "CMake Server" ==[
-  {"cookie":"","inReplyTo":"compute","type":"reply"}
-  ]== "CMake Server" ==]
-
-
-Type "codemodel"
-^^^^^^^^^^^^^^^^
-
-The "codemodel" request can be used after a project was "compute"d successfully.
-
-It will list the complete project structure as it is known to cmake.
-
-The reply will contain a key "configurations", which will contain a list of
-configuration objects. Configuration objects are used to destinquish between
-different configurations the build directory might have enabled. While most
-generators only support one configuration, others might support several.
-
-Each configuration object can have the following keys:
-
-"name"
-  contains the name of the configuration. The name may be empty.
-"projects"
-  contains a list of project objects, one for each build project.
-
-Project objects define one (sub-)project defined in the cmake build system.
-
-Each project object can have the following keys:
-
-"name"
-  contains the (sub-)projects name.
-"minimumCMakeVersion"
-  contains the minimum cmake version allowed for this project, null if the
-  project doesn't specify one.
-"hasInstallRule"
-  true if the project contains any install rules, false otherwise.
-"sourceDirectory"
-  contains the current source directory
-"buildDirectory"
-  contains the current build directory.
-"targets"
-  contains a list of build system target objects.
-
-Target objects define individual build targets for a certain configuration.
-
-Each target object can have the following keys:
-
-"name"
-  contains the name of the target.
-"type"
-  defines the type of build of the target. Possible values are
-  "STATIC_LIBRARY", "MODULE_LIBRARY", "SHARED_LIBRARY", "OBJECT_LIBRARY",
-  "EXECUTABLE", "UTILITY" and "INTERFACE_LIBRARY".
-"fullName"
-  contains the full name of the build result (incl. extensions, etc.).
-"sourceDirectory"
-  contains the current source directory.
-"buildDirectory"
-  contains the current build directory.
-"isGeneratorProvided"
-  true if the target is auto-created by a generator, false otherwise
-"hasInstallRule"
-  true if the target contains any install rules, false otherwise.
-"installPaths"
-  full path to the destination directories defined by target install rules.
-"artifacts"
-  with a list of build artifacts. The list is sorted with the most
-  important artifacts first (e.g. a .DLL file is listed before a
-  .PDB file on windows).
-"linkerLanguage"
-  contains the language of the linker used to produce the artifact.
-"linkLibraries"
-  with a list of libraries to link to. This value is encoded in the
-  system's native shell format.
-"linkFlags"
-  with a list of flags to pass to the linker. This value is encoded in
-  the system's native shell format.
-"linkLanguageFlags"
-  with the flags for a compiler using the linkerLanguage. This value is
-  encoded in the system's native shell format.
-"frameworkPath"
-  with the framework path (on Apple computers). This value is encoded
-  in the system's native shell format.
-"linkPath"
-  with the link path. This value is encoded in the system's native shell
-  format.
-"sysroot"
-  with the sysroot path.
-"fileGroups"
-  contains the source files making up the target.
-
-FileGroups are used to group sources using similar settings together.
-
-Each fileGroup object may contain the following keys:
-
-"language"
-  contains the programming language used by all files in the group.
-"compileFlags"
-  with a string containing all the flags passed to the compiler
-  when building any of the files in this group. This value is encoded in
-  the system's native shell format.
-"includePath"
-  with a list of include paths. Each include path is an object
-  containing a "path" with the actual include path and "isSystem" with a bool
-  value informing whether this is a normal include or a system include. This
-  value is encoded in the system's native shell format.
-"defines"
-  with a list of defines in the form "SOMEVALUE" or "SOMEVALUE=42". This
-  value is encoded in the system's native shell format.
-"sources"
-  with a list of source files.
-
-All file paths in the fileGroup are either absolute or relative to the
-sourceDirectory of the target.
-
-Example::
-
-  [== "CMake Server" ==[
-  {"type":"codemodel"}
-  ]== "CMake Server" ==]
-
-CMake will reply::
-
-  [== "CMake Server" ==[
-  {
-    "configurations": [
-      {
-        "name": "",
-        "projects": [
-          {
-            "buildDirectory": "/tmp/build/Source/CursesDialog/form",
-            "name": "CMAKE_FORM",
-            "sourceDirectory": "/home/code/src/cmake/Source/CursesDialog/form",
-            "targets": [
-              {
-                "artifacts": [ "/tmp/build/Source/CursesDialog/form/libcmForm.a" ],
-                "buildDirectory": "/tmp/build/Source/CursesDialog/form",
-                "fileGroups": [
-                  {
-                    "compileFlags": "  -std=gnu11",
-                    "defines": [ "CURL_STATICLIB", "LIBARCHIVE_STATIC" ],
-                    "includePath": [ { "path": "/tmp/build/Utilities" }, <...> ],
-                    "isGenerated": false,
-                    "language": "C",
-                    "sources": [ "fld_arg.c", <...> ]
-                  }
-                ],
-                "fullName": "libcmForm.a",
-                "linkerLanguage": "C",
-                "name": "cmForm",
-                "sourceDirectory": "/home/code/src/cmake/Source/CursesDialog/form",
-                "type": "STATIC_LIBRARY"
-              }
-            ]
-          },
-          <...>
-        ]
-      }
-    ],
-    "cookie": "",
-    "inReplyTo": "codemodel",
-    "type": "reply"
-  }
-  ]== "CMake Server" ==]
-
-
-Type "ctestInfo"
-^^^^^^^^^^^^^^^^
-
-The "ctestInfo" request can be used after a project was "compute"d successfully.
-
-It will list the complete project test structure as it is known to cmake.
-
-The reply will contain a key "configurations", which will contain a list of
-configuration objects. Configuration objects are used to destinquish between
-different configurations the build directory might have enabled. While most
-generators only support one configuration, others might support several.
-
-Each configuration object can have the following keys:
-
-"name"
-  contains the name of the configuration. The name may be empty.
-"projects"
-  contains a list of project objects, one for each build project.
-
-Project objects define one (sub-)project defined in the cmake build system.
-
-Each project object can have the following keys:
-
-"name"
-  contains the (sub-)projects name.
-"ctestInfo"
-  contains a list of test objects.
-
-Each test object can have the following keys:
-
-"ctestName"
-  contains the name of the test.
-"ctestCommand"
-  contains the test command.
-"properties"
-  contains a list of test property objects.
-
-Each test property object can have the following keys:
-
-"key"
-  contains the test property key.
-"value"
-  contains the test property value.
-
-
-Type "cmakeInputs"
-^^^^^^^^^^^^^^^^^^
-
-The "cmakeInputs" requests will report files used by CMake as part
-of the build system itself.
-
-This request is only available after a project was successfully
-"configure"d.
-
-Example::
-
-  [== "CMake Server" ==[
-  {"type":"cmakeInputs"}
-  ]== "CMake Server" ==]
-
-CMake will reply with the following information::
-
-  [== "CMake Server" ==[
-  {"buildFiles":
-    [
-      {"isCMake":true,"isTemporary":false,"sources":["/usr/lib/cmake/...", ... ]},
-      {"isCMake":false,"isTemporary":false,"sources":["CMakeLists.txt", ...]},
-      {"isCMake":false,"isTemporary":true,"sources":["/tmp/build/CMakeFiles/...", ...]}
-    ],
-    "cmakeRootDirectory":"/usr/lib/cmake",
-    "sourceDirectory":"/home/code/src/cmake",
-    "cookie":"",
-    "inReplyTo":"cmakeInputs",
-    "type":"reply"
-  }
-  ]== "CMake Server" ==]
-
-All file names are either relative to the top level source directory or
-absolute.
-
-The list of files which "isCMake" set to true are part of the cmake installation.
-
-The list of files witch "isTemporary" set to true are part of the build directory
-and will not survive the build directory getting cleaned out.
-
-
-Type "cache"
-^^^^^^^^^^^^
-
-The "cache" request will list the cached configuration values.
-
-Example::
-
-  [== "CMake Server" ==[
-  {"type":"cache"}
-  ]== "CMake Server" ==]
-
-CMake will respond with the following output::
-
-  [== "CMake Server" ==[
-  {
-    "cookie":"","inReplyTo":"cache","type":"reply",
-    "cache":
-    [
-      {
-        "key":"SOMEVALUE",
-        "properties":
-        {
-          "ADVANCED":"1",
-          "HELPSTRING":"This is not helpful"
-        }
-        "type":"STRING",
-        "value":"TEST"}
-    ]
-  }
-  ]== "CMake Server" ==]
-
-The output can be limited to a list of keys by passing an array of key names
-to the "keys" optional field of the "cache" request.
-
-
-Type "fileSystemWatchers"
-^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The server can watch the filesystem for changes. The "fileSystemWatchers"
-command will report on the files and directories watched.
-
-Example::
-
-  [== "CMake Server" ==[
-  {"type":"fileSystemWatchers"}
-  ]== "CMake Server" ==]
-
-CMake will respond with the following output::
-
-  [== "CMake Server" ==[
-  {
-    "cookie":"","inReplyTo":"fileSystemWatchers","type":"reply",
-    "watchedFiles": [ "/absolute/path" ],
-    "watchedDirectories": [ "/absolute" ]
-  }
-  ]== "CMake Server" ==]
+The :manual:`cmake(1)` server mode has been removed since CMake 3.20.
+Clients should use the :manual:`cmake-file-api(7)` instead.
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index 17d0882..f0c9d99 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -336,6 +336,7 @@
    /variable/CMAKE_ANDROID_ARM_MODE
    /variable/CMAKE_ANDROID_ARM_NEON
    /variable/CMAKE_ANDROID_ASSETS_DIRECTORIES
+   /variable/CMAKE_ANDROID_EXCEPTIONS
    /variable/CMAKE_ANDROID_GUI
    /variable/CMAKE_ANDROID_JAR_DEPENDENCIES
    /variable/CMAKE_ANDROID_JAR_DIRECTORIES
@@ -349,6 +350,7 @@
    /variable/CMAKE_ANDROID_PROCESS_MAX
    /variable/CMAKE_ANDROID_PROGUARD
    /variable/CMAKE_ANDROID_PROGUARD_CONFIG_PATH
+   /variable/CMAKE_ANDROID_RTTI
    /variable/CMAKE_ANDROID_SECURE_PROPS_PATH
    /variable/CMAKE_ANDROID_SKIP_ANT_STEP
    /variable/CMAKE_ANDROID_STANDALONE_TOOLCHAIN
@@ -521,6 +523,7 @@
    /variable/CMAKE_LANG_ARCHIVE_APPEND
    /variable/CMAKE_LANG_ARCHIVE_CREATE
    /variable/CMAKE_LANG_ARCHIVE_FINISH
+   /variable/CMAKE_LANG_BYTE_ORDER
    /variable/CMAKE_LANG_COMPILER
    /variable/CMAKE_LANG_COMPILER_EXTERNAL_TOOLCHAIN
    /variable/CMAKE_LANG_COMPILER_ID
diff --git a/Help/manual/cmake.1.rst b/Help/manual/cmake.1.rst
index 921f5c4..7efe0cd 100644
--- a/Help/manual/cmake.1.rst
+++ b/Help/manual/cmake.1.rst
@@ -580,6 +580,7 @@
 
   ``serverMode``
     ``true`` if cmake supports server-mode and ``false`` otherwise.
+    Always false since CMake 3.20.
 
 ``cat <files>...``
   Concatenate files and print on the standard output.
diff --git a/Help/module/UseJavaClassFilelist.rst b/Help/module/UseJavaClassFilelist.rst
deleted file mode 100644
index b9cd476..0000000
--- a/Help/module/UseJavaClassFilelist.rst
+++ /dev/null
@@ -1 +0,0 @@
-.. cmake-module:: ../../Modules/UseJavaClassFilelist.cmake
diff --git a/Help/module/UseJavaSymlinks.rst b/Help/module/UseJavaSymlinks.rst
deleted file mode 100644
index 2fab8e8..0000000
--- a/Help/module/UseJavaSymlinks.rst
+++ /dev/null
@@ -1 +0,0 @@
-.. cmake-module:: ../../Modules/UseJavaSymlinks.cmake
diff --git a/Help/policy/CMP0115.rst b/Help/policy/CMP0115.rst
new file mode 100644
index 0000000..7f82c43
--- /dev/null
+++ b/Help/policy/CMP0115.rst
@@ -0,0 +1,34 @@
+CMP0115
+-------
+
+.. versionadded:: 3.20
+
+Source file extensions must be explicit.
+
+In CMake 3.19 and below, if a source file could not be found by the name
+specified, it would append a list of known extensions to the name to see if
+the file with the extension could be found. For example, this would allow the
+user to run:
+
+.. code-block:: cmake
+
+  add_executable(exe main)
+
+and put ``main.c`` in the executable without specifying the extension.
+
+Starting in CMake 3.20, CMake prefers all source files to have their extensions
+explicitly listed:
+
+.. code-block:: cmake
+
+  add_executable(exe main.c)
+
+The ``OLD`` behavior for this policy is to implicitly append known extensions
+to source files if they can't be found. The ``NEW`` behavior of this policy is
+to not append known extensions and require them to be explicit.
+
+This policy was introduced in CMake version 3.20.  CMake version |release|
+warns when the policy is not set and uses ``OLD`` behavior. Use the
+:command:`cmake_policy` command to set it to ``OLD`` or ``NEW`` explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0116.rst b/Help/policy/CMP0116.rst
new file mode 100644
index 0000000..25a14c4
--- /dev/null
+++ b/Help/policy/CMP0116.rst
@@ -0,0 +1,38 @@
+CMP0116
+-------
+
+.. versionadded:: 3.20
+
+Ninja generators transform ``DEPFILE`` s from :command:`add_custom_command`.
+
+In CMake 3.19 and below, files given to the ``DEPFILE`` argument of
+:command:`add_custom_command` were passed directly to Ninja's ``depfile``
+variable without any path resolution. This meant that if
+:command:`add_custom_command` was called from a subdirectory (created by
+:command:`add_subdirectory`), the ``DEPFILE`` argument would have to be either
+an absolute path or a path relative to :variable:`CMAKE_BINARY_DIR`, rather
+than :variable:`CMAKE_CURRENT_BINARY_DIR`. In addition, no transformation was
+done on the file listed in ``DEPFILE``, which meant that the paths within the
+``DEPFILE`` had the same restrictions.
+
+Starting with CMake 3.20, the ``DEPFILE`` argument is relative to
+:variable:`CMAKE_CURRENT_BINARY_DIR` (unless it is absolute), and the paths in
+the ``DEPFILE`` are also relative to :variable:`CMAKE_CURRENT_BINARY_DIR`.
+CMake automatically transforms the paths in the ``DEPFILE`` (unless they are
+absolute) after the custom command is run. The file listed in ``DEPFILE`` is
+not modified in any way. Instead, CMake writes the transformation to its own
+internal file, and passes this internal file to Ninja's ``depfile`` variable.
+This transformation happens regardless of whether or not ``DEPFILE`` is
+relative, and regardless of whether or not :command:`add_custom_command` is
+called from a subdirectory.
+
+The ``OLD`` behavior for this policy is to pass the ``DEPFILE`` to Ninja
+unaltered. The ``NEW`` behavior for this policy is to transform the ``DEPFILE``
+after running the custom command.
+
+This policy was introduced in CMake version 3.20.  Unlike most policies,
+CMake version |release| does *not* warn by default when this policy is not set
+(unless ``DEPFILE`` is used in a subdirectory) and simply uses ``OLD``
+behavior.  See documentation of the
+:variable:`CMAKE_POLICY_WARNING_CMP0116 <CMAKE_POLICY_WARNING_CMP<NNNN>>`
+variable to control the warning.
diff --git a/Help/policy/CMP0117.rst b/Help/policy/CMP0117.rst
new file mode 100644
index 0000000..0c4dd30
--- /dev/null
+++ b/Help/policy/CMP0117.rst
@@ -0,0 +1,43 @@
+CMP0117
+-------
+
+.. versionadded:: 3.20
+
+MSVC RTTI flag ``/GR`` is not added to
+:variable:`CMAKE_CXX_FLAGS <CMAKE_<LANG>_FLAGS>` by default.
+
+When using MSVC-like compilers in CMake 3.19 and below, the RTTI flag
+``/GR`` is added to :variable:`CMAKE_CXX_FLAGS <CMAKE_<LANG>_FLAGS>` by
+default.  This behavior is left from support for MSVC versions from Visual
+Studio 2003 and below that did not enable RTTI by default.  It is no longer
+necessary.  Furthermore, it is problematic for projects that want to change
+to ``/GR-`` programmatically.  In particular, it requires string editing of
+the :variable:`CMAKE_CXX_FLAGS <CMAKE_<LANG>_FLAGS>` variable with knowledge
+of the CMake builtin default so it can be replaced.
+
+CMake 3.20 and above prefer to leave out ``/GR`` from the value of
+:variable:`CMAKE_CXX_FLAGS <CMAKE_<LANG>_FLAGS>` by default.
+
+This policy provides compatibility with projects that have not been updated
+to expect the lack of the ``/GR`` flag.  The policy setting takes effect as
+of the first :command:`project` or :command:`enable_language` command that
+initializes :variable:`CMAKE_CXX_FLAGS <CMAKE_<LANG>_FLAGS>`.
+
+.. note::
+
+  Once the policy has taken effect at the top of a project for a given
+  language, that choice must be used throughout the tree for that language.
+  In projects that have nested projects in subdirectories, be sure to
+  convert everything together.
+
+The ``OLD`` behavior for this policy is to place the MSVC ``/GR`` flag in the
+default :variable:`CMAKE_CXX_FLAGS <CMAKE_<LANG>_FLAGS>` cache entry.  The
+``NEW`` behavior for this policy is to *not* place the MSVC ``/GR`` flag in
+the default cache entry.
+
+This policy was introduced in CMake version 3.20.  Use the
+:command:`cmake_policy` command to set it to ``OLD`` or ``NEW`` explicitly.
+Unlike many policies, CMake version |release| does *not* warn
+when this policy is not set and simply uses ``OLD`` behavior.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/prop_tgt/LANG_CLANG_TIDY.rst b/Help/prop_tgt/LANG_CLANG_TIDY.rst
index 7fc2372..af16d3c 100644
--- a/Help/prop_tgt/LANG_CLANG_TIDY.rst
+++ b/Help/prop_tgt/LANG_CLANG_TIDY.rst
@@ -3,7 +3,7 @@
 
 .. versionadded:: 3.6
 
-This property is implemented only when ``<LANG>`` is ``C`` or ``CXX``.
+This property is implemented only when ``<LANG>`` is ``C``, ``CXX``, ``OBJC`` or ``OBJCXX``.
 
 Specify a :ref:`semicolon-separated list <CMake Language Lists>` containing a command
 line for the ``clang-tidy`` tool.  The :ref:`Makefile Generators`
diff --git a/Help/release/dev/0-sample-topic.rst b/Help/release/dev/0-sample-topic.rst
new file mode 100644
index 0000000..e4cc01e
--- /dev/null
+++ b/Help/release/dev/0-sample-topic.rst
@@ -0,0 +1,7 @@
+0-sample-topic
+--------------
+
+* This is a sample release note for the change in a topic.
+  Developers should add similar notes for each topic branch
+  making a noteworthy change.  Each document should be named
+  and titled to match the topic name to avoid merge conflicts.
diff --git a/Help/release/dev/ExternalData-suppress-progress.rst b/Help/release/dev/ExternalData-suppress-progress.rst
new file mode 100644
index 0000000..bf4183f
--- /dev/null
+++ b/Help/release/dev/ExternalData-suppress-progress.rst
@@ -0,0 +1,6 @@
+ExternalData-suppress-progress
+------------------------------
+
+* The :module:`ExternalData` module ``ExternalData_add_target`` now supports a
+  ``SHOW_PROGRESS <bool>`` argument to suppress progress output during the
+  build.
diff --git a/Help/release/dev/FindIntl-imported-target.rst b/Help/release/dev/FindIntl-imported-target.rst
new file mode 100644
index 0000000..5770f21
--- /dev/null
+++ b/Help/release/dev/FindIntl-imported-target.rst
@@ -0,0 +1,4 @@
+FindIntl-imported-target
+------------------------
+
+* The :module:`FindIntl` module now provides an imported target.
diff --git a/Help/release/dev/FindPython-FIND_UNVERSIONED_NAMES.rst b/Help/release/dev/FindPython-FIND_UNVERSIONED_NAMES.rst
new file mode 100644
index 0000000..a0b5838
--- /dev/null
+++ b/Help/release/dev/FindPython-FIND_UNVERSIONED_NAMES.rst
@@ -0,0 +1,6 @@
+FindPython-FIND_UNVERSIONED_NAMES
+---------------------------------
+
+* Modules :module:`FindPython3`, :module:`FindPython2` and :module:`FindPython`
+  gain the capability to control how interpreter unversioned names are
+  searched.
diff --git a/Help/release/dev/TestBigEndian-use-abi-result.rst b/Help/release/dev/TestBigEndian-use-abi-result.rst
new file mode 100644
index 0000000..1a5bf7f
--- /dev/null
+++ b/Help/release/dev/TestBigEndian-use-abi-result.rst
@@ -0,0 +1,5 @@
+TestBigEndian-use-abi-result
+----------------------------
+
+* The :module:`TestBigEndian` module has been deprecated in favor
+  of the :variable:`CMAKE_<LANG>_BYTE_ORDER` variable.
diff --git a/Help/release/dev/abi-byte-order.rst b/Help/release/dev/abi-byte-order.rst
new file mode 100644
index 0000000..e8beebc
--- /dev/null
+++ b/Help/release/dev/abi-byte-order.rst
@@ -0,0 +1,5 @@
+abi-byte-order
+--------------
+
+* The :variable:`CMAKE_<LANG>_BYTE_ORDER` variable was added to provide the
+  target architecture byte order detected from the toolchain.
diff --git a/Help/release/dev/clang-tidy-objc.rst b/Help/release/dev/clang-tidy-objc.rst
new file mode 100644
index 0000000..c899257
--- /dev/null
+++ b/Help/release/dev/clang-tidy-objc.rst
@@ -0,0 +1,5 @@
+clang-tidy-objc
+---------------
+
+* The target property :prop_tgt:`<LANG>_CLANG_TIDY` and the associated
+  variable :variable:`CMAKE_<LANG>_CLANG_TIDY` learned to support OBJC and OBJCXX.
diff --git a/Help/release/dev/cmake_path.rst b/Help/release/dev/cmake_path.rst
new file mode 100644
index 0000000..9d252ae
--- /dev/null
+++ b/Help/release/dev/cmake_path.rst
@@ -0,0 +1,5 @@
+cmake_path
+----------
+
+* The :command:`cmake_path` command was added for operations on
+  filesystem paths.
diff --git a/Help/release/dev/configure_file-user-permissions.rst b/Help/release/dev/configure_file-user-permissions.rst
new file mode 100644
index 0000000..b757fb1
--- /dev/null
+++ b/Help/release/dev/configure_file-user-permissions.rst
@@ -0,0 +1,6 @@
+configure_file-user-permissions
+-------------------------------
+
+* The :command:`configure_file` command gained a ``USE_SOURCE_PERMISSIONS``
+  and ``FILE_PERMISSIONS`` option to support copying of permissions of source
+  file and specifying user defined permissions.
diff --git a/Help/release/dev/cpack-nsis-utf-8-bom.rst b/Help/release/dev/cpack-nsis-utf-8-bom.rst
new file mode 100644
index 0000000..b2a20ce
--- /dev/null
+++ b/Help/release/dev/cpack-nsis-utf-8-bom.rst
@@ -0,0 +1,6 @@
+cpack-nsis-utf8-bom
+-------------------
+
+* The :cpack_gen:`CPack NSIS Generator` now handles correctly Unicode characters.
+  If you want to have a ``CPACK_RESOURCE_FILE_LICENSE`` with UTF-8 characters
+  it needs to be encoded in UTF-8 BOM.
diff --git a/Help/release/dev/cpack-nuget.rst b/Help/release/dev/cpack-nuget.rst
new file mode 100644
index 0000000..2c28b59
--- /dev/null
+++ b/Help/release/dev/cpack-nuget.rst
@@ -0,0 +1,31 @@
+cpack-nuget
+-----------
+
+* The :cpack_gen:`CPack NuGet Generator` gained options:
+
+  - :variable:`CPACK_NUGET_PACKAGE_ICON` and
+    :variable:`CPACK_NUGET_<compName>_PACKAGE_ICON`
+    allow package icons to be specified by local files.
+  - :variable:`CPACK_NUGET_PACKAGE_LICENSE_EXPRESSION` and
+    :variable:`CPACK_NUGET_<compName>_PACKAGE_LICENSE_EXPRESSION` add
+    support for specifying licenses recognized by the
+    `Software Package Data Exchange`_ (SPDX).
+  - :variable:`CPACK_NUGET_PACKAGE_LICENSE_FILE_NAME` and
+    :variable:`CPACK_NUGET_<compName>_PACKAGE_LICENSE_FILE_NAME` allow
+    licenses to be specified by local files.
+  - :variable:`CPACK_NUGET_PACKAGE_LANGUAGE` and
+    :variable:`CPACK_NUGET_<compName>_PACKAGE_LANGUAGE` allow the locale
+    for a package to be specified, for example ``en_CA``.
+
+ Some other variables have been deprecated to reflect changes in the
+ NuGet specification:
+
+ - :variable:`CPACK_NUGET_PACKAGE_ICONURL` and
+   :variable:`CPACK_NUGET_<compName>_PACKAGE_ICONURL` have been deprecated;
+   replace with a reference to a local icon file.
+ - :variable:`CPACK_NUGET_PACKAGE_LICENSEURL` and
+   :variable:`CPACK_NUGET_<compName>_PACKAGE_LICENSEURL` have been deprecated;
+   replace with a reference to the project's license file or SPDX
+   license expression.
+
+.. _Software Package Data Exchange: https://spdx.org/
diff --git a/Help/release/dev/explicit-source-extensions.rst b/Help/release/dev/explicit-source-extensions.rst
new file mode 100644
index 0000000..ccd9339
--- /dev/null
+++ b/Help/release/dev/explicit-source-extensions.rst
@@ -0,0 +1,5 @@
+explicit-source-extensions
+--------------------------
+
+* Source file extensions must now be explicit. See policy :policy:`CMP0115` for
+  details.
diff --git a/Help/release/dev/msvc-no-GR.rst b/Help/release/dev/msvc-no-GR.rst
new file mode 100644
index 0000000..e5ca850
--- /dev/null
+++ b/Help/release/dev/msvc-no-GR.rst
@@ -0,0 +1,7 @@
+msvc-no-GR
+----------
+
+* With MSVC-like compilers the value of
+  :variable:`CMAKE_CXX_FLAGS <CMAKE_<LANG>_FLAGS>` no longer contains
+  the ``/GR`` flag for runtime type information by default.
+  See policy :policy:`CMP0117`.
diff --git a/Help/release/dev/ninja-depfile-transformation.rst b/Help/release/dev/ninja-depfile-transformation.rst
new file mode 100644
index 0000000..edf7f58
--- /dev/null
+++ b/Help/release/dev/ninja-depfile-transformation.rst
@@ -0,0 +1,5 @@
+ninja-depfile-transformation
+----------------------------
+
+* Ninja generators now transform ``DEPFILE`` s from
+  :command:`add_custom_command`. See policy :policy:`CMP0116` for details.
diff --git a/Help/release/dev/remove-server-mode.rst b/Help/release/dev/remove-server-mode.rst
new file mode 100644
index 0000000..7c986b1
--- /dev/null
+++ b/Help/release/dev/remove-server-mode.rst
@@ -0,0 +1,5 @@
+remove-server-mode
+------------------
+
+* The :manual:`cmake-server(7)` mode has been removed.
+  Clients should use the :manual:`cmake-file-api(7)` instead.
diff --git a/Help/release/dev/target-sources-supports-custom-target.rst b/Help/release/dev/target-sources-supports-custom-target.rst
new file mode 100644
index 0000000..131fb3a
--- /dev/null
+++ b/Help/release/dev/target-sources-supports-custom-target.rst
@@ -0,0 +1,4 @@
+target-sources-supports-custom-target
+-------------------------------------
+
+* The :command:`target_sources` now supports custom targets.
diff --git a/Help/release/index.rst b/Help/release/index.rst
index 6fb0f1a..a8329a6 100644
--- a/Help/release/index.rst
+++ b/Help/release/index.rst
@@ -7,6 +7,8 @@
   This file should include the adjacent "dev.txt" file
   in development versions but not in release versions.
 
+.. include:: dev.txt
+
 Releases
 ========
 
diff --git a/Help/variable/CMAKE_ANDROID_EXCEPTIONS.rst b/Help/variable/CMAKE_ANDROID_EXCEPTIONS.rst
new file mode 100644
index 0000000..6dd44f8
--- /dev/null
+++ b/Help/variable/CMAKE_ANDROID_EXCEPTIONS.rst
@@ -0,0 +1,7 @@
+CMAKE_ANDROID_EXCEPTIONS
+------------------------
+
+.. versionadded:: 3.20
+
+When :ref:`Cross Compiling for Android with the NDK`, this variable may be set
+to specify whether exceptions are enabled.
diff --git a/Help/variable/CMAKE_ANDROID_RTTI.rst b/Help/variable/CMAKE_ANDROID_RTTI.rst
new file mode 100644
index 0000000..0e98206
--- /dev/null
+++ b/Help/variable/CMAKE_ANDROID_RTTI.rst
@@ -0,0 +1,7 @@
+CMAKE_ANDROID_RTTI
+------------------
+
+.. versionadded:: 3.20
+
+When :ref:`Cross Compiling for Android with the NDK`, this variable may be set
+to specify whether RTTI is enabled.
diff --git a/Help/variable/CMAKE_BUILD_TYPE.rst b/Help/variable/CMAKE_BUILD_TYPE.rst
index 2d35635..405f7d5 100644
--- a/Help/variable/CMAKE_BUILD_TYPE.rst
+++ b/Help/variable/CMAKE_BUILD_TYPE.rst
@@ -18,3 +18,8 @@
 having :variable:`CMAKE_C_FLAGS_DEBUG <CMAKE_<LANG>_FLAGS_DEBUG>` settings get
 added to the :variable:`CMAKE_C_FLAGS <CMAKE_<LANG>_FLAGS>` settings.  See
 also :variable:`CMAKE_CONFIGURATION_TYPES`.
+
+Note that configuration names are case-insensitive.  The value of this
+variable will be the same as it is specified when invoking CMake.
+For instance, if ``-DCMAKE_BUILD_TYPE=ReLeAsE`` is specified, then the
+value of ``CMAKE_BUILD_TYPE`` will be ``ReLeAsE``.
diff --git a/Help/variable/CMAKE_LANG_BYTE_ORDER.rst b/Help/variable/CMAKE_LANG_BYTE_ORDER.rst
new file mode 100644
index 0000000..78f0ae6
--- /dev/null
+++ b/Help/variable/CMAKE_LANG_BYTE_ORDER.rst
@@ -0,0 +1,20 @@
+CMAKE_<LANG>_BYTE_ORDER
+-----------------------
+
+.. versionadded:: 3.20
+
+Byte order of ``<LANG>`` compiler target architecture, if known.
+If defined and not empty, the value is one of:
+
+``BIG_ENDIAN``
+  The target architecture is Big Endian.
+
+``LITTLE_ENDIAN``
+  The target architecture is Little Endian.
+
+This is defined for languages ``C``, ``CXX``, ``OBJC``, ``OBJCXX``,
+and ``CUDA``.
+
+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.
diff --git a/Help/variable/CMAKE_LANG_CLANG_TIDY.rst b/Help/variable/CMAKE_LANG_CLANG_TIDY.rst
index 78f0f6a..32e27b0 100644
--- a/Help/variable/CMAKE_LANG_CLANG_TIDY.rst
+++ b/Help/variable/CMAKE_LANG_CLANG_TIDY.rst
@@ -4,7 +4,7 @@
 .. versionadded:: 3.6
 
 Default value for :prop_tgt:`<LANG>_CLANG_TIDY` target property
-when ``<LANG>`` is ``C`` or ``CXX``.
+when ``<LANG>`` is ``C``, ``CXX``, ``OBJC`` or ``OBJCXX``.
 
 This variable is used to initialize the property on each target as it is
 created.  For example:
diff --git a/Help/variable/CMAKE_POLICY_WARNING_CMPNNNN.rst b/Help/variable/CMAKE_POLICY_WARNING_CMPNNNN.rst
index d35595a..9f68741 100644
--- a/Help/variable/CMAKE_POLICY_WARNING_CMPNNNN.rst
+++ b/Help/variable/CMAKE_POLICY_WARNING_CMPNNNN.rst
@@ -27,6 +27,8 @@
   policy :policy:`CMP0102`.
 * ``CMAKE_POLICY_WARNING_CMP0112`` controls the warning for
   policy :policy:`CMP0112`.
+* ``CMAKE_POLICY_WARNING_CMP0116`` controls the warning for
+  policy :policy:`CMP0116`.
 
 This variable should not be set by a project in CMake code.  Project
 developers running CMake may set this variable in their cache to
diff --git a/Modules/CMakeCCompiler.cmake.in b/Modules/CMakeCCompiler.cmake.in
index eea3f5d..7f73891 100644
--- a/Modules/CMakeCCompiler.cmake.in
+++ b/Modules/CMakeCCompiler.cmake.in
@@ -48,6 +48,7 @@
 # Save compiler ABI information.
 set(CMAKE_C_SIZEOF_DATA_PTR "@CMAKE_C_SIZEOF_DATA_PTR@")
 set(CMAKE_C_COMPILER_ABI "@CMAKE_C_COMPILER_ABI@")
+set(CMAKE_C_BYTE_ORDER "@CMAKE_C_BYTE_ORDER@")
 set(CMAKE_C_LIBRARY_ARCHITECTURE "@CMAKE_C_LIBRARY_ARCHITECTURE@")
 
 if(CMAKE_C_SIZEOF_DATA_PTR)
diff --git a/Modules/CMakeCCompilerABI.c b/Modules/CMakeCCompilerABI.c
index 08cf39b..f0ee21a 100644
--- a/Modules/CMakeCCompilerABI.c
+++ b/Modules/CMakeCCompilerABI.c
@@ -17,6 +17,8 @@
 {
   int require = 0;
   require += info_sizeof_dptr[argc];
+  require += info_byte_order_big_endian[argc];
+  require += info_byte_order_little_endian[argc];
 #if defined(ABI_ID)
   require += info_abi[argc];
 #endif
diff --git a/Modules/CMakeCUDACompiler.cmake.in b/Modules/CMakeCUDACompiler.cmake.in
index 871e18e..d4e6e2e 100644
--- a/Modules/CMakeCUDACompiler.cmake.in
+++ b/Modules/CMakeCUDACompiler.cmake.in
@@ -31,6 +31,7 @@
 
 set(CMAKE_CUDA_SIZEOF_DATA_PTR "@CMAKE_CUDA_SIZEOF_DATA_PTR@")
 set(CMAKE_CUDA_COMPILER_ABI "@CMAKE_CUDA_COMPILER_ABI@")
+set(CMAKE_CUDA_BYTE_ORDER "@CMAKE_CUDA_BYTE_ORDER@")
 set(CMAKE_CUDA_LIBRARY_ARCHITECTURE "@CMAKE_CUDA_LIBRARY_ARCHITECTURE@")
 
 if(CMAKE_CUDA_SIZEOF_DATA_PTR)
diff --git a/Modules/CMakeCUDACompilerABI.cu b/Modules/CMakeCUDACompilerABI.cu
index 702a7c5..449a079 100644
--- a/Modules/CMakeCUDACompilerABI.cu
+++ b/Modules/CMakeCUDACompilerABI.cu
@@ -8,6 +8,8 @@
 {
   int require = 0;
   require += info_sizeof_dptr[argc];
+  require += info_byte_order_big_endian[argc];
+  require += info_byte_order_little_endian[argc];
 #if defined(ABI_ID)
   require += info_abi[argc];
 #endif
diff --git a/Modules/CMakeCXXCompiler.cmake.in b/Modules/CMakeCXXCompiler.cmake.in
index 09bdc23..a235ebb 100644
--- a/Modules/CMakeCXXCompiler.cmake.in
+++ b/Modules/CMakeCXXCompiler.cmake.in
@@ -60,6 +60,7 @@
 # Save compiler ABI information.
 set(CMAKE_CXX_SIZEOF_DATA_PTR "@CMAKE_CXX_SIZEOF_DATA_PTR@")
 set(CMAKE_CXX_COMPILER_ABI "@CMAKE_CXX_COMPILER_ABI@")
+set(CMAKE_CXX_BYTE_ORDER "@CMAKE_CXX_BYTE_ORDER@")
 set(CMAKE_CXX_LIBRARY_ARCHITECTURE "@CMAKE_CXX_LIBRARY_ARCHITECTURE@")
 
 if(CMAKE_CXX_SIZEOF_DATA_PTR)
diff --git a/Modules/CMakeCXXCompilerABI.cpp b/Modules/CMakeCXXCompilerABI.cpp
index 2360534..036b96e 100644
--- a/Modules/CMakeCXXCompilerABI.cpp
+++ b/Modules/CMakeCXXCompilerABI.cpp
@@ -8,6 +8,8 @@
 {
   int require = 0;
   require += info_sizeof_dptr[argc];
+  require += info_byte_order_big_endian[argc];
+  require += info_byte_order_little_endian[argc];
 #if defined(ABI_ID)
   require += info_abi[argc];
 #endif
diff --git a/Modules/CMakeCompilerABI.h b/Modules/CMakeCompilerABI.h
index 45532af..c5ce4dd 100644
--- a/Modules/CMakeCompilerABI.h
+++ b/Modules/CMakeCompilerABI.h
@@ -9,6 +9,18 @@
   /* clang-format on */
 };
 
+/* Byte order.  Only one of these will have bytes in the right order.  */
+static unsigned short const info_byte_order_big_endian[] = {
+  /* INFO:byte_order string for BIG_ENDIAN */
+  0x494E, 0x464F, 0x3A62, 0x7974, 0x655F, 0x6F72, 0x6465, 0x725B,
+  0x4249, 0x475F, 0x454E, 0x4449, 0x414E, 0x5D00, 0x0000
+};
+static unsigned short const info_byte_order_little_endian[] = {
+  /* INFO:byte_order string for LITTLE_ENDIAN */
+  0x4E49, 0x4F46, 0x623A, 0x7479, 0x5F65, 0x726F, 0x6564, 0x5B72,
+  0x494C, 0x5454, 0x454C, 0x455F, 0x444E, 0x4149, 0x5D4E, 0x0000
+};
+
 /* Application Binary Interface.  */
 
 /* Check for (some) ARM ABIs.
diff --git a/Modules/CMakeDetermineCompilerABI.cmake b/Modules/CMakeDetermineCompilerABI.cmake
index 7e5b375..67c42a2a 100644
--- a/Modules/CMakeDetermineCompilerABI.cmake
+++ b/Modules/CMakeDetermineCompilerABI.cmake
@@ -75,12 +75,25 @@
       message(CHECK_PASS "done")
       file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
         "Detecting ${lang} compiler ABI info compiled with the following output:\n${OUTPUT}\n\n")
-      file(STRINGS "${BIN}" ABI_STRINGS LIMIT_COUNT 2 REGEX "INFO:[A-Za-z0-9_]+\\[[^]]*\\]")
+      file(STRINGS "${BIN}" ABI_STRINGS LIMIT_COUNT 32 REGEX "INFO:[A-Za-z0-9_]+\\[[^]]*\\]")
+      set(ABI_SIZEOF_DPTR "NOTFOUND")
+      set(ABI_BYTE_ORDER "NOTFOUND")
+      set(ABI_NAME "NOTFOUND")
       foreach(info ${ABI_STRINGS})
-        if("${info}" MATCHES "INFO:sizeof_dptr\\[0*([^]]*)\\]")
+        if("${info}" MATCHES "INFO:sizeof_dptr\\[0*([^]]*)\\]" AND NOT ABI_SIZEOF_DPTR)
           set(ABI_SIZEOF_DPTR "${CMAKE_MATCH_1}")
         endif()
-        if("${info}" MATCHES "INFO:abi\\[([^]]*)\\]")
+        if("${info}" MATCHES "INFO:byte_order\\[(BIG_ENDIAN|LITTLE_ENDIAN)\\]")
+          set(byte_order "${CMAKE_MATCH_1}")
+          if(ABI_BYTE_ORDER STREQUAL "NOTFOUND")
+            # Tentatively use the value because this is the first occurrence.
+            set(ABI_BYTE_ORDER "${byte_order}")
+          elseif(NOT ABI_BYTE_ORDER STREQUAL "${byte_order}")
+            # Drop value because multiple occurrences do not match.
+            set(ABI_BYTE_ORDER "")
+          endif()
+        endif()
+        if("${info}" MATCHES "INFO:abi\\[([^]]*)\\]" AND NOT ABI_NAME)
           set(ABI_NAME "${CMAKE_MATCH_1}")
         endif()
       endforeach()
@@ -91,6 +104,10 @@
         set(CMAKE_${lang}_SIZEOF_DATA_PTR "${CMAKE_${lang}_SIZEOF_DATA_PTR_DEFAULT}" PARENT_SCOPE)
       endif()
 
+      if(ABI_BYTE_ORDER)
+        set(CMAKE_${lang}_BYTE_ORDER "${ABI_BYTE_ORDER}" PARENT_SCOPE)
+      endif()
+
       if(ABI_NAME)
         set(CMAKE_${lang}_COMPILER_ABI "${ABI_NAME}" PARENT_SCOPE)
       endif()
diff --git a/Modules/CMakeOBJCCompiler.cmake.in b/Modules/CMakeOBJCCompiler.cmake.in
index 1555517..608adce 100644
--- a/Modules/CMakeOBJCCompiler.cmake.in
+++ b/Modules/CMakeOBJCCompiler.cmake.in
@@ -45,6 +45,7 @@
 # Save compiler ABI information.
 set(CMAKE_OBJC_SIZEOF_DATA_PTR "@CMAKE_OBJC_SIZEOF_DATA_PTR@")
 set(CMAKE_OBJC_COMPILER_ABI "@CMAKE_OBJC_COMPILER_ABI@")
+set(CMAKE_OBJC_BYTE_ORDER "@CMAKE_OBJC_BYTE_ORDER@")
 set(CMAKE_OBJC_LIBRARY_ARCHITECTURE "@CMAKE_OBJC_LIBRARY_ARCHITECTURE@")
 
 if(CMAKE_OBJC_SIZEOF_DATA_PTR)
diff --git a/Modules/CMakeOBJCCompilerABI.m b/Modules/CMakeOBJCCompilerABI.m
index 8fa8511..0726cd3 100644
--- a/Modules/CMakeOBJCCompilerABI.m
+++ b/Modules/CMakeOBJCCompilerABI.m
@@ -12,6 +12,8 @@
 {
   int require = 0;
   require += info_sizeof_dptr[argc];
+  require += info_byte_order_big_endian[argc];
+  require += info_byte_order_little_endian[argc];
 #if defined(ABI_ID)
   require += info_abi[argc];
 #endif
diff --git a/Modules/CMakeOBJCXXCompiler.cmake.in b/Modules/CMakeOBJCXXCompiler.cmake.in
index b6452c4..18eb7ff 100644
--- a/Modules/CMakeOBJCXXCompiler.cmake.in
+++ b/Modules/CMakeOBJCXXCompiler.cmake.in
@@ -55,6 +55,7 @@
 # Save compiler ABI information.
 set(CMAKE_OBJCXX_SIZEOF_DATA_PTR "@CMAKE_OBJCXX_SIZEOF_DATA_PTR@")
 set(CMAKE_OBJCXX_COMPILER_ABI "@CMAKE_OBJCXX_COMPILER_ABI@")
+set(CMAKE_OBJCXX_BYTE_ORDER "@CMAKE_OBJCXX_BYTE_ORDER@")
 set(CMAKE_OBJCXX_LIBRARY_ARCHITECTURE "@CMAKE_OBJCXX_LIBRARY_ARCHITECTURE@")
 
 if(CMAKE_OBJCXX_SIZEOF_DATA_PTR)
diff --git a/Modules/CMakeOBJCXXCompilerABI.mm b/Modules/CMakeOBJCXXCompilerABI.mm
index 288a58c..7b9fefc 100644
--- a/Modules/CMakeOBJCXXCompilerABI.mm
+++ b/Modules/CMakeOBJCXXCompilerABI.mm
@@ -12,6 +12,8 @@
 {
   int require = 0;
   require += info_sizeof_dptr[argc];
+  require += info_byte_order_big_endian[argc];
+  require += info_byte_order_little_endian[argc];
 #if defined(ABI_ID)
   require += info_abi[argc];
 #endif
diff --git a/Modules/CTest.cmake b/Modules/CTest.cmake
index 8265bd2..a18e85b 100644
--- a/Modules/CTest.cmake
+++ b/Modules/CTest.cmake
@@ -179,12 +179,6 @@
     "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Rational Software\\Purify\\Setup;InstallFolder]"
     DOC "Path to the memory checking command, used for memory error detection."
     )
-  find_program(SLURM_SBATCH_COMMAND sbatch DOC
-    "Path to the SLURM sbatch executable"
-    )
-  find_program(SLURM_SRUN_COMMAND srun DOC
-    "Path to the SLURM srun executable"
-    )
   set(MEMORYCHECK_SUPPRESSIONS_FILE "" CACHE FILEPATH
     "File that contains suppressions for the memory checker")
   find_program(COVERAGE_COMMAND gcov DOC
@@ -194,7 +188,14 @@
     "Extra command line flags to pass to the coverage tool")
 
   # set the site name
-  site_name(SITE)
+  if(COMMAND cmake_host_system_information)
+    cmake_host_system_information(RESULT _ctest_hostname QUERY HOSTNAME)
+    set(SITE "${_ctest_hostname}" CACHE STRING "Name of the computer/site where compile is being run")
+    unset(_ctest_hostname)
+  else()
+    # This code path is needed for CMake itself during bootstrap.
+    site_name(SITE)
+  endif()
   # set the build name
   if(NOT BUILDNAME)
     set(DART_COMPILER "${CMAKE_CXX_COMPILER}")
@@ -256,8 +257,6 @@
     MAKECOMMAND
     MEMORYCHECK_COMMAND
     MEMORYCHECK_SUPPRESSIONS_FILE
-    SLURM_SBATCH_COMMAND
-    SLURM_SRUN_COMMAND
     SITE
     SVNCOMMAND
     )
diff --git a/Modules/CheckLanguage.cmake b/Modules/CheckLanguage.cmake
index 44387d4..928881c 100644
--- a/Modules/CheckLanguage.cmake
+++ b/Modules/CheckLanguage.cmake
@@ -68,6 +68,11 @@
     else()
       set(_D_CMAKE_MAKE_PROGRAM "-DCMAKE_MAKE_PROGRAM:FILEPATH=${CMAKE_MAKE_PROGRAM}")
     endif()
+    if(CMAKE_TOOLCHAIN_FILE)
+      set(_D_CMAKE_TOOLCHAIN_FILE "-DCMAKE_TOOLCHAIN_FILE:FILEPATH=${CMAKE_TOOLCHAIN_FILE}")
+    else()
+      set(_D_CMAKE_TOOLCHAIN_FILE "")
+    endif()
     execute_process(
       WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/Check${lang}
       COMMAND ${CMAKE_COMMAND} . -G ${CMAKE_GENERATOR}
@@ -75,6 +80,7 @@
                                  -T "${CMAKE_GENERATOR_TOOLSET}"
                                  ${_D_CMAKE_GENERATOR_INSTANCE}
                                  ${_D_CMAKE_MAKE_PROGRAM}
+                                 ${_D_CMAKE_TOOLCHAIN_FILE}
       OUTPUT_VARIABLE _cl_output
       ERROR_VARIABLE _cl_output
       RESULT_VARIABLE _cl_result
diff --git a/Modules/DartConfiguration.tcl.in b/Modules/DartConfiguration.tcl.in
index 90a56e2..e5b1e5d 100644
--- a/Modules/DartConfiguration.tcl.in
+++ b/Modules/DartConfiguration.tcl.in
@@ -83,10 +83,6 @@
 CoverageCommand: @COVERAGE_COMMAND@
 CoverageExtraFlags: @COVERAGE_EXTRA_FLAGS@
 
-# Cluster commands
-SlurmBatchCommand: @SLURM_SBATCH_COMMAND@
-SlurmRunCommand: @SLURM_SRUN_COMMAND@
-
 # Testing options
 # TimeOut is the amount of time in seconds to wait for processes
 # to complete during testing.  After TimeOut seconds, the
diff --git a/Modules/ExternalData.cmake b/Modules/ExternalData.cmake
index 6fe8685..294167c 100644
--- a/Modules/ExternalData.cmake
+++ b/Modules/ExternalData.cmake
@@ -78,7 +78,8 @@
   manage local instances of data files stored externally::
 
     ExternalData_Add_Target(
-      <target>   # Name of data management target
+      <target>                  # Name of data management target
+      [SHOW_PROGRESS <ON|OFF>]  # Show progress during the download
       )
 
   It creates custom commands in the target as necessary to make data
@@ -89,6 +90,11 @@
   in one of the paths specified in the ``ExternalData_OBJECT_STORES``
   variable.
 
+  The ``SHOW_PROGRESS`` argument may be passed to suppress progress information
+  during the download of objects. If not provided, it defaults to ``OFF`` for
+  :generator:`Ninja` and :generator:`Ninja Multi-Config` generators and ``ON``
+  otherwise.
+
   Typically only one target is needed to manage all external data within
   a project.  Call this function once at the end of configuration after
   all data references have been processed.
@@ -344,6 +350,30 @@
   endif()
   set(_ExternalData_CONFIG_CODE "")
 
+  cmake_parse_arguments(PARSE_ARGV 1 _ExternalData_add_target
+    ""
+    "SHOW_PROGRESS"
+    "")
+  if (_ExternalData_add_target_UNPARSED_ARGUMENTS)
+    message(AUTHOR_WARNING
+      "Ignoring unrecognized arguments passed to ExternalData_add_target: "
+      "`${_ExternalData_add_target_UNPARSED_ARGUMENTS}`")
+  endif ()
+
+  # Turn `SHOW_PROGRESS` into a boolean
+  if (NOT DEFINED _ExternalData_add_target_SHOW_PROGRESS)
+    # The default setting
+    if (CMAKE_GENERATOR MATCHES "Ninja")
+      set(_ExternalData_add_target_SHOW_PROGRESS OFF)
+    else ()
+      set(_ExternalData_add_target_SHOW_PROGRESS ON)
+    endif ()
+  elseif (_ExternalData_add_target_SHOW_PROGRESS)
+    set(_ExternalData_add_target_SHOW_PROGRESS ON)
+  else ()
+    set(_ExternalData_add_target_SHOW_PROGRESS OFF)
+  endif ()
+
   # Store custom script configuration.
   foreach(url_template IN LISTS ExternalData_URL_TEMPLATES)
     if("${url_template}" MATCHES "^ExternalDataCustomScript://([^/]*)/(.*)$")
@@ -423,6 +453,7 @@
           COMMAND ${CMAKE_COMMAND} -Drelative_top=${CMAKE_BINARY_DIR}
                                    -Dfile=${file} -Dname=${name}
                                    -DExternalData_ACTION=local
+                                   -DExternalData_SHOW_PROGRESS=${_ExternalData_add_target_SHOW_PROGRESS}
                                    -DExternalData_CONFIG=${config}
                                    -P ${_ExternalData_SELF}
           MAIN_DEPENDENCY "${name}"
@@ -459,6 +490,7 @@
           COMMAND ${CMAKE_COMMAND} -Drelative_top=${CMAKE_BINARY_DIR}
                                    -Dfile=${file} -Dname=${name} -Dexts=${exts}
                                    -DExternalData_ACTION=fetch
+                                   -DExternalData_SHOW_PROGRESS=${_ExternalData_add_target_SHOW_PROGRESS}
                                    -DExternalData_CONFIG=${config}
                                    -P ${_ExternalData_SELF}
           # Update whenever the object hash changes.
@@ -925,7 +957,11 @@
     else()
       set(absolute_timeout "")
     endif()
-    file(DOWNLOAD "${url}" "${file}" STATUS status LOG log ${inactivity_timeout} ${absolute_timeout} SHOW_PROGRESS)
+    set(show_progress_args)
+    if (ExternalData_SHOW_PROGRESS)
+      list(APPEND show_progress_args SHOW_PROGRESS)
+    endif ()
+    file(DOWNLOAD "${url}" "${file}" STATUS status LOG log ${inactivity_timeout} ${absolute_timeout} ${show_progress_args})
     list(GET status 0 err)
     list(GET status 1 msg)
     if(err)
diff --git a/Modules/FindBLAS.cmake b/Modules/FindBLAS.cmake
index e4353df..715049b 100644
--- a/Modules/FindBLAS.cmake
+++ b/Modules/FindBLAS.cmake
@@ -586,16 +586,22 @@
     else()
       find_package(Threads REQUIRED)
     endif()
+    set(_threadlibs "${CMAKE_THREAD_LIBS_INIT}")
+    if(BLA_STATIC)
+      find_package(OpenMP COMPONENTS C)
+      list(PREPEND _threadlibs "${OpenMP_C_LIBRARIES}")
+    endif()
     check_blas_libraries(
       BLAS_LIBRARIES
       BLAS
       sgemm
       ""
       "openblas"
-      "${CMAKE_THREAD_LIBS_INIT}"
+      "${_threadlibs}"
       ""
       ""
       )
+    unset(_threadlibs)
   endif()
 endif()
 
diff --git a/Modules/FindGTest.cmake b/Modules/FindGTest.cmake
index 10e31b2..ff50869 100644
--- a/Modules/FindGTest.cmake
+++ b/Modules/FindGTest.cmake
@@ -12,6 +12,15 @@
 
 This module defines the following :prop_tgt:`IMPORTED` targets:
 
+``GTest::gtest``
+  The Google Test ``gtest`` library, if found; adds Thread::Thread
+  automatically
+``GTest::gtest_main``
+  The Google Test ``gtest_main`` library, if found
+
+For backwards compatibility, this module defines additionally the
+following deprecated :prop_tgt:`IMPORTED` targets:
+
 ``GTest::GTest``
   The Google Test ``gtest`` library, if found; adds Thread::Thread
   automatically
@@ -24,7 +33,7 @@
 
 This module will set the following variables in your project:
 
-``GTEST_FOUND``
+``GTest_FOUND``
   Found the Google Testing framework
 ``GTEST_INCLUDE_DIRS``
   the directory containing the Google Test headers
@@ -62,7 +71,7 @@
     find_package(GTest REQUIRED)
 
     add_executable(foo foo.cc)
-    target_link_libraries(foo GTest::GTest GTest::Main)
+    target_link_libraries(foo GTest::gtest GTest::gtest_main)
 
     add_test(AllTestsInFoo foo)
 
@@ -167,8 +176,41 @@
     endif()
 endfunction()
 
+function(__gtest_define_backwards_compatible_library_targets)
+    set(GTEST_BOTH_LIBRARIES ${GTEST_LIBRARIES} ${GTEST_MAIN_LIBRARIES} PARENT_SCOPE)
+
+    # Add targets mapping the same library names as defined in
+    # older versions of CMake's FindGTest
+    if(NOT TARGET GTest::GTest)
+        add_library(GTest::GTest INTERFACE IMPORTED)
+        target_link_libraries(GTest::GTest INTERFACE GTest::gtest)
+    endif()
+    if(NOT TARGET GTest::Main)
+        add_library(GTest::Main INTERFACE IMPORTED)
+        target_link_libraries(GTest::Main INTERFACE GTest::gtest_main)
+    endif()
+endfunction()
+
 #
 
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+
+# first specifically look for the CMake version of GTest
+find_package(GTest QUIET NO_MODULE)
+
+# if we found the GTest cmake package then we are done, and
+# can print what we found and return.
+if(GTest_FOUND)
+    FIND_PACKAGE_HANDLE_STANDARD_ARGS(GTest HANDLE_COMPONENTS CONFIG_MODE)
+
+    set(GTEST_LIBRARIES      GTest::gtest)
+    set(GTEST_MAIN_LIBRARIES GTest::gtest_main)
+
+    __gtest_define_backwards_compatible_library_targets()
+
+    return()
+endif()
+
 if(NOT DEFINED GTEST_MSVC_SEARCH)
     set(GTEST_MSVC_SEARCH MD)
 endif()
@@ -208,8 +250,6 @@
 )
 mark_as_advanced(GTEST_INCLUDE_DIR)
 
-# Allow GTEST_LIBRARY and GTEST_MAIN_LIBRARY to be set manually, as the
-# locations of the gtest and gtest_main libraries, respectively.
 if(NOT GTEST_LIBRARY)
     __gtest_find_and_select_library_configurations(GTEST gtest)
 endif()
@@ -217,54 +257,43 @@
     __gtest_find_and_select_library_configurations(GTEST_MAIN gtest_main)
 endif()
 
-include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
 FIND_PACKAGE_HANDLE_STANDARD_ARGS(GTest DEFAULT_MSG GTEST_LIBRARY GTEST_INCLUDE_DIR GTEST_MAIN_LIBRARY)
 
-if(GTEST_FOUND)
+if(GTest_FOUND)
     set(GTEST_INCLUDE_DIRS ${GTEST_INCLUDE_DIR})
     __gtest_append_debugs(GTEST_LIBRARIES      GTEST_LIBRARY)
     __gtest_append_debugs(GTEST_MAIN_LIBRARIES GTEST_MAIN_LIBRARY)
-    set(GTEST_BOTH_LIBRARIES ${GTEST_LIBRARIES} ${GTEST_MAIN_LIBRARIES})
 
     find_package(Threads QUIET)
 
-    if(NOT TARGET GTest::GTest)
+    if(NOT TARGET GTest::gtest)
         __gtest_determine_library_type(GTEST_LIBRARY)
-        add_library(GTest::GTest ${GTEST_LIBRARY_TYPE} IMPORTED)
+        add_library(GTest::gtest ${GTEST_LIBRARY_TYPE} IMPORTED)
         if(TARGET Threads::Threads)
-            set_target_properties(GTest::GTest PROPERTIES
+            set_target_properties(GTest::gtest PROPERTIES
                 INTERFACE_LINK_LIBRARIES Threads::Threads)
         endif()
         if(GTEST_LIBRARY_TYPE STREQUAL "SHARED")
-            set_target_properties(GTest::GTest PROPERTIES
+            set_target_properties(GTest::gtest PROPERTIES
                 INTERFACE_COMPILE_DEFINITIONS "GTEST_LINKED_AS_SHARED_LIBRARY=1")
         endif()
         if(GTEST_INCLUDE_DIRS)
-            set_target_properties(GTest::GTest PROPERTIES
+            set_target_properties(GTest::gtest PROPERTIES
                 INTERFACE_INCLUDE_DIRECTORIES "${GTEST_INCLUDE_DIRS}")
         endif()
-        __gtest_import_library(GTest::GTest GTEST_LIBRARY "")
-        __gtest_import_library(GTest::GTest GTEST_LIBRARY "RELEASE")
-        __gtest_import_library(GTest::GTest GTEST_LIBRARY "DEBUG")
-    endif()
-    if(NOT TARGET GTest::Main)
-        __gtest_determine_library_type(GTEST_MAIN_LIBRARY)
-        add_library(GTest::Main ${GTEST_MAIN_LIBRARY_TYPE} IMPORTED)
-        set_target_properties(GTest::Main PROPERTIES
-            INTERFACE_LINK_LIBRARIES "GTest::GTest")
-        __gtest_import_library(GTest::Main GTEST_MAIN_LIBRARY "")
-        __gtest_import_library(GTest::Main GTEST_MAIN_LIBRARY "RELEASE")
-        __gtest_import_library(GTest::Main GTEST_MAIN_LIBRARY "DEBUG")
-    endif()
-
-    # Add targets mapping the same library names as defined in
-    # GTest's CMake package config.
-    if(NOT TARGET GTest::gtest)
-        add_library(GTest::gtest INTERFACE IMPORTED)
-        target_link_libraries(GTest::gtest INTERFACE GTest::GTest)
+        __gtest_import_library(GTest::gtest GTEST_LIBRARY "")
+        __gtest_import_library(GTest::gtest GTEST_LIBRARY "RELEASE")
+        __gtest_import_library(GTest::gtest GTEST_LIBRARY "DEBUG")
     endif()
     if(NOT TARGET GTest::gtest_main)
-        add_library(GTest::gtest_main INTERFACE IMPORTED)
-        target_link_libraries(GTest::gtest_main INTERFACE GTest::Main)
+        __gtest_determine_library_type(GTEST_MAIN_LIBRARY)
+        add_library(GTest::gtest_main ${GTEST_MAIN_LIBRARY_TYPE} IMPORTED)
+        set_target_properties(GTest::gtest_main PROPERTIES
+            INTERFACE_LINK_LIBRARIES "GTest::gtest")
+        __gtest_import_library(GTest::gtest_main GTEST_MAIN_LIBRARY "")
+        __gtest_import_library(GTest::gtest_main GTEST_MAIN_LIBRARY "RELEASE")
+        __gtest_import_library(GTest::gtest_main GTEST_MAIN_LIBRARY "DEBUG")
     endif()
+
+    __gtest_define_backwards_compatible_library_targets()
 endif()
diff --git a/Modules/FindICU.cmake b/Modules/FindICU.cmake
index c8b3e1f..fa0cba3 100644
--- a/Modules/FindICU.cmake
+++ b/Modules/FindICU.cmake
@@ -31,7 +31,7 @@
   ICU::<C>
 
 Where ``<C>`` is the name of an ICU component, for example
-``ICU::i18n``.
+``ICU::i18n``; ``<C>`` is lower-case.
 
 ICU programs are reported in::
 
@@ -54,16 +54,14 @@
 
 ICU component libraries are reported in::
 
-  ICU_<C>_FOUND - ON if component was found
-  ICU_<C>_LIBRARIES - libraries for component
+  ICU_<C>_FOUND - ON if component was found; ``<C>`` is upper-case.
+  ICU_<C>_LIBRARIES - libraries for component; ``<C>`` is upper-case.
 
 ICU datafiles are reported in::
 
   ICU_MAKEFILE_INC - Makefile.inc
   ICU_PKGDATA_INC - pkgdata.inc
 
-Note that ``<C>`` is the uppercased name of the component.
-
 This module reads hints about search results from::
 
   ICU_ROOT - the root of the ICU installation
@@ -73,9 +71,9 @@
 
 The following cache variables may also be set::
 
-  ICU_<P>_EXECUTABLE - the path to executable <P>
+  ICU_<P>_EXECUTABLE - the path to executable <P>; ``<P>`` is upper-case.
   ICU_INCLUDE_DIR - the directory containing the ICU headers
-  ICU_<C>_LIBRARY - the library for component <C>
+  ICU_<C>_LIBRARY - the library for component <C>; ``<C>`` is upper-case.
 
 .. note::
 
@@ -188,7 +186,8 @@
     set(component_cache "ICU_${component_upcase}_LIBRARY")
     set(component_cache_release "${component_cache}_RELEASE")
     set(component_cache_debug "${component_cache}_DEBUG")
-    set(component_found "${component_upcase}_FOUND")
+    set(component_found "ICU_${component_upcase}_FOUND")
+    set(component_found_compat "${component_upcase}_FOUND")
     set(component_libnames "icu${component}")
     set(component_debug_libnames "icu${component}d")
 
@@ -250,12 +249,15 @@
     mark_as_advanced("${component_cache_release}" "${component_cache_debug}")
     if(${component_cache})
       set("${component_found}" ON)
+      set("${component_found_compat}" ON)
       list(APPEND ICU_LIBRARY "${${component_cache}}")
     endif()
     mark_as_advanced("${component_found}")
+    mark_as_advanced("${component_found_compat}")
     set("${component_cache}" "${${component_cache}}" PARENT_SCOPE)
     set("${component_found}" "${${component_found}}" PARENT_SCOPE)
-    if(${component_found})
+    set("${component_found_compat}" "${${component_found_compat}}" PARENT_SCOPE)
+    if(component_found OR component_found_compat)
       if (ICU_FIND_REQUIRED_${component})
         list(APPEND ICU_LIBS_FOUND "${component} (required)")
       else()
@@ -346,7 +348,7 @@
     set(_ICU_component_cache_release "ICU_${_ICU_component_upcase}_LIBRARY_RELEASE")
     set(_ICU_component_cache_debug "ICU_${_ICU_component_upcase}_LIBRARY_DEBUG")
     set(_ICU_component_lib "ICU_${_ICU_component_upcase}_LIBRARIES")
-    set(_ICU_component_found "${_ICU_component_upcase}_FOUND")
+    set(_ICU_component_found "ICU_${_ICU_component_upcase}_FOUND")
     set(_ICU_imported_target "ICU::${_ICU_component}")
     if(${_ICU_component_found})
       set("${_ICU_component_lib}" "${${_ICU_component_cache}}")
@@ -400,7 +402,7 @@
   foreach(program IN LISTS icu_programs)
     string(TOUPPER "${program}" program_upcase)
     set(program_lib "ICU_${program_upcase}_EXECUTABLE")
-    message(STATUS "${program} program: ${${program_lib}}")
+    message(STATUS "${program} program: ${program_lib}=${${program_lib}}")
     unset(program_upcase)
     unset(program_lib)
   endforeach()
@@ -409,7 +411,7 @@
     string(TOUPPER "${data}" data_upcase)
     string(REPLACE "." "_" data_upcase "${data_upcase}")
     set(data_lib "ICU_${data_upcase}")
-    message(STATUS "${data} data: ${${data_lib}}")
+    message(STATUS "${data} data: ${data_lib}=${${data_lib}}")
     unset(data_upcase)
     unset(data_lib)
   endforeach()
@@ -417,12 +419,15 @@
   foreach(component IN LISTS ICU_FIND_COMPONENTS)
     string(TOUPPER "${component}" component_upcase)
     set(component_lib "ICU_${component_upcase}_LIBRARIES")
-    set(component_found "${component_upcase}_FOUND")
-    message(STATUS "${component} library found: ${${component_found}}")
-    message(STATUS "${component} library: ${${component_lib}}")
+    set(component_found "ICU_${component_upcase}_FOUND")
+    set(component_found_compat "${component_upcase}_FOUND")
+    message(STATUS "${component} library found: ${component_found}=${${component_found}}")
+    message(STATUS "${component} library found (compat name): ${component_found_compat}=${${component_found_compat}}")
+    message(STATUS "${component} library: ${component_lib}=${${component_lib}}")
     unset(component_upcase)
     unset(component_lib)
     unset(component_found)
+    unset(component_found_compat)
   endforeach()
   message(STATUS "----------------")
 endif()
diff --git a/Modules/FindIntl.cmake b/Modules/FindIntl.cmake
index 1a09a60..d29f554 100644
--- a/Modules/FindIntl.cmake
+++ b/Modules/FindIntl.cmake
@@ -15,11 +15,16 @@
   Intl_FOUND - true if the libintl headers and libraries were found
   Intl_INCLUDE_DIRS - the directory containing the libintl headers
   Intl_LIBRARIES - libintl libraries to be linked
+  Intl::Intl - imported target for Intl
 
 The following cache variables may also be set::
 
   Intl_INCLUDE_DIR - the directory containing the libintl headers
   Intl_LIBRARY - the libintl library (if any)
+  Intl_HAVE_GETTEXT_BUILTIN - check if gettext is in the C library
+  Intl_HAVE_DCGETTEXT_BUILTIN - check if dcgettext is in the C library
+  Intl_IS_BUILTIN - whether intl is a part of the C library determined
+      from the result of Intl_HAVE_GETTEXT_BUILTIN and Intl_HAVE_DCGETTEXT_BUILTIN
 
 .. note::
   On some platforms, such as Linux with GNU libc, the gettext
@@ -35,6 +40,22 @@
 
 # Written by Roger Leigh <rleigh@codelibre.net>
 
+include(${CMAKE_CURRENT_LIST_DIR}/CMakePushCheckState.cmake)
+include(${CMAKE_CURRENT_LIST_DIR}/CheckSymbolExists.cmake)
+
+# Check if we have libintl is a part of libc
+cmake_push_check_state(RESET)
+set(CMAKE_REQUIRED_QUIET TRUE)
+check_symbol_exists(gettext libintl.h Intl_HAVE_GETTEXT_BUILTIN)
+check_symbol_exists(dcgettext libintl.h Intl_HAVE_DCGETTEXT_BUILTIN) # redundant check
+cmake_pop_check_state()
+
+if(Intl_HAVE_GETTEXT_BUILTIN AND Intl_HAVE_DCGETTEXT_BUILTIN)
+  set(Intl_IS_BUILTIN TRUE)
+else()
+  set(Intl_IS_BUILTIN FALSE)
+endif()
+
 # Find include directory
 find_path(Intl_INCLUDE_DIR
           NAMES "libintl.h"
@@ -42,21 +63,28 @@
 mark_as_advanced(Intl_INCLUDE_DIR)
 
 # Find all Intl libraries
-find_library(Intl_LIBRARY "intl" NAMES_PER_DIR
-  DOC "libintl libraries (if not in the C library)")
-mark_as_advanced(Intl_LIBRARY)
+set(Intl_REQUIRED_VARS)
+if(NOT Intl_IS_BUILTIN)
+  find_library(Intl_LIBRARY "intl" "libintl" NAMES_PER_DIR
+    DOC "libintl libraries (if not in the C library)")
+  mark_as_advanced(Intl_LIBRARY)
+  list(APPEND Intl_REQUIRED_VARS Intl_LIBRARY)
+endif()
 
 include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
 FIND_PACKAGE_HANDLE_STANDARD_ARGS(Intl
                                   FOUND_VAR Intl_FOUND
-                                  REQUIRED_VARS Intl_INCLUDE_DIR
+                                  REQUIRED_VARS Intl_INCLUDE_DIR ${Intl_REQUIRED_VARS}
                                   FAIL_MESSAGE "Failed to find Gettext libintl")
+unset(Intl_REQUIRED_VARS)
 
 if(Intl_FOUND)
   set(Intl_INCLUDE_DIRS "${Intl_INCLUDE_DIR}")
-  if(Intl_LIBRARY)
-    set(Intl_LIBRARIES "${Intl_LIBRARY}")
-  else()
-    unset(Intl_LIBRARIES)
+  set(Intl_LIBRARIES "${Intl_LIBRARY}")
+  if(NOT TARGET Intl::Intl)
+    add_library(Intl::Intl INTERFACE IMPORTED)
+    set_target_properties(Intl::Intl PROPERTIES
+      INTERFACE_INCLUDE_DIRECTORIES "${Intl_INCLUDE_DIRS}"
+      INTERFACE_LINK_LIBRARIES "${Intl_LIBRARIES}")
   endif()
 endif()
diff --git a/Modules/FindProtobuf.cmake b/Modules/FindProtobuf.cmake
index 4bf54ef..0c9d695 100644
--- a/Modules/FindProtobuf.cmake
+++ b/Modules/FindProtobuf.cmake
@@ -204,7 +204,7 @@
   foreach(_proto ${protobuf_generate_PROTOS})
     get_filename_component(_abs_file ${_proto} ABSOLUTE)
     get_filename_component(_abs_dir ${_abs_file} DIRECTORY)
-    get_filename_component(_basename ${_proto} NAME_WE)
+    get_filename_component(_basename ${_proto} NAME_WLE)
     file(RELATIVE_PATH _rel_dir ${CMAKE_CURRENT_SOURCE_DIR} ${_abs_dir})
 
     set(_possible_rel_dir)
diff --git a/Modules/FindPython.cmake b/Modules/FindPython.cmake
index 5fc6a3b..e842e6b 100644
--- a/Modules/FindPython.cmake
+++ b/Modules/FindPython.cmake
@@ -318,6 +318,22 @@
     ``.Net`` interpreter (i.e. ``mono`` command) is expected to be available
     through the ``PATH`` variable.
 
+``Python_FIND_UNVERSIONED_NAMES``
+
+  .. versionadded:: 3.20
+
+  This variable defines how the generic names will be searched. Currently, it
+  only applies to the generic names of the interpreter, namely, ``python3`` or
+  ``python2`` and ``python``.
+  The ``Python_FIND_UNVERSIONED_NAMES`` variable can be set to one of the
+  following values:
+
+  * ``FIRST``: The generic names are searched before the more specialized ones
+    (such as ``python2.5`` for example).
+  * ``LAST``: The generic names are searched after the more specialized ones.
+    This is the default.
+  * ``NEVER``: The generic name are not searched at all.
+
 Artifacts Specification
 ^^^^^^^^^^^^^^^^^^^^^^^
 
diff --git a/Modules/FindPython/Support.cmake b/Modules/FindPython/Support.cmake
index 028ce08..0e76468 100644
--- a/Modules/FindPython/Support.cmake
+++ b/Modules/FindPython/Support.cmake
@@ -337,6 +337,9 @@
 
   foreach (implementation IN LISTS _PGN_IMPLEMENTATIONS)
     if (implementation STREQUAL "CPython")
+      if (_PGN_INTERPRETER AND _${_PYTHON_PREFIX}_FIND_UNVERSIONED_NAMES STREQUAL "FIRST")
+        list (APPEND names python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} python)
+      endif()
       foreach (version IN LISTS _PGN_VERSION)
         if (_PGN_WIN32)
           string (REPLACE "." "" version_no_dots ${version})
@@ -386,7 +389,7 @@
           endif()
         endif()
       endforeach()
-      if (_PGN_INTERPRETER)
+      if (_PGN_INTERPRETER AND _${_PYTHON_PREFIX}_FIND_UNVERSIONED_NAMES STREQUAL "LAST")
         list (APPEND names python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} python)
       endif()
     elseif (implementation STREQUAL "IronPython")
@@ -1364,9 +1367,22 @@
 endif()
 
 
+# Python naming handling
+if (DEFINED ${_PYTHON_PREFIX}_FIND_UNVERSIONED_NAMES)
+  if (NOT ${_PYTHON_PREFIX}_FIND_UNVERSIONED_NAMES MATCHES "^(FIRST|LAST|NEVER)$")
+    message (AUTHOR_WARNING "Find${_PYTHON_PREFIX}: ${_${_PYTHON_PREFIX}_FIND_UNVERSIONED_NAMES}: invalid value for '${_PYTHON_PREFIX}_FIND_UNVERSIONED_NAMES'. 'FIRST', 'LAST' or 'NEVER' expected. 'LAST' will be used instead.")
+    set (_${_PYTHON_PREFIX}_FIND_UNVERSIONED_NAMES LAST)
+  else()
+    set (_${_PYTHON_PREFIX}_FIND_UNVERSIONED_NAMES ${${_PYTHON_PREFIX}_FIND_UNVERSIONED_NAMES})
+  endif()
+else()
+  set (_${_PYTHON_PREFIX}_FIND_UNVERSIONED_NAMES LAST)
+endif()
+
+
 # Compute search signature
 # This signature will be used to check validity of cached variables on new search
-set (_${_PYTHON_PREFIX}_SIGNATURE "${${_PYTHON_PREFIX}_ROOT_DIR}:${_${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS}:${_${_PYTHON_PREFIX}_FIND_STRATEGY}:${${_PYTHON_PREFIX}_FIND_VIRTUALENV}")
+set (_${_PYTHON_PREFIX}_SIGNATURE "${${_PYTHON_PREFIX}_ROOT_DIR}:${_${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS}:${_${_PYTHON_PREFIX}_FIND_STRATEGY}:${${_PYTHON_PREFIX}_FIND_VIRTUALENV}${_${_PYTHON_PREFIX}_FIND_UNVERSIONED_NAMES}")
 if (NOT WIN32)
   string (APPEND _${_PYTHON_PREFIX}_SIGNATURE ":${${_PYTHON_PREFIX}_USE_STATIC_LIBS}:")
 endif()
@@ -2997,8 +3013,9 @@
     unset(_${_PYTHON_PREFIX}_is_prefix)
     foreach (_${_PYTHON_PREFIX}_implementation IN LISTS _${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS)
       foreach (_${_PYTHON_PREFIX}_framework IN LISTS _${_PYTHON_PREFIX}_${_${_PYTHON_PREFIX}_implementation}_FRAMEWORKS)
-        if (${_PYTHON_PREFIX}_LIBRARY_RELEASE MATCHES "^${_${_PYTHON_PREFIX}_framework}")
-          get_filename_component (_${_PYTHON_PREFIX}_framework "${_${_PYTHON_PREFIX}_framework}" DIRECTORY)
+        cmake_path (IS_PREFIX _${_PYTHON_PREFIX}_framework "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}" _${_PYTHON_PREFIX}_is_prefix)
+        if (_${_PYTHON_PREFIX}_is_prefix)
+          cmake_path (GET _${_PYTHON_PREFIX}_framework PARENT_PATH _${_PYTHON_PREFIX}_framework)
           set (${_PYTHON_PREFIX}_LINK_OPTIONS "LINKER:-rpath,${_${_PYTHON_PREFIX}_framework}")
           break()
         endif()
diff --git a/Modules/FindPython2.cmake b/Modules/FindPython2.cmake
index 9cd22e1..5277e33 100644
--- a/Modules/FindPython2.cmake
+++ b/Modules/FindPython2.cmake
@@ -265,6 +265,22 @@
     ``.Net`` interpreter (i.e. ``mono`` command) is expected to be available
     through the ``PATH`` variable.
 
+``Python2_FIND_UNVERSIONED_NAMES``
+
+  .. versionadded:: 3.20
+
+  This variable defines how the generic names will be searched. Currently, it
+  only applies to the generic names of the interpreter, namely, ``python2`` and
+  ``python``.
+  The ``Python2_FIND_UNVERSIONED_NAMES`` variable can be set to one of the
+  following values:
+
+  * ``FIRST``: The generic names are searched before the more specialized ones
+    (such as ``python2.5`` for example).
+  * ``LAST``: The generic names are searched after the more specialized ones.
+    This is the default.
+  * ``NEVER``: The generic name are not searched at all.
+
 Artifacts Specification
 ^^^^^^^^^^^^^^^^^^^^^^^
 
diff --git a/Modules/FindPython3.cmake b/Modules/FindPython3.cmake
index c79d482..2bd4d76 100644
--- a/Modules/FindPython3.cmake
+++ b/Modules/FindPython3.cmake
@@ -315,6 +315,22 @@
     ``.Net`` interpreter (i.e. ``mono`` command) is expected to be available
     through the ``PATH`` variable.
 
+``Python3_FIND_UNVERSIONED_NAMES``
+
+  .. versionadded:: 3.20
+
+  This variable defines how the generic names will be searched. Currently, it
+  only applies to the generic names of the interpreter, namely, ``python3`` and
+  ``python``.
+  The ``Python3_FIND_UNVERSIONED_NAMES`` variable can be set to one of the
+  following values:
+
+  * ``FIRST``: The generic names are searched before the more specialized ones
+    (such as ``python3.5`` for example).
+  * ``LAST``: The generic names are searched after the more specialized ones.
+    This is the default.
+  * ``NEVER``: The generic name are not searched at all.
+
 Artifacts Specification
 ^^^^^^^^^^^^^^^^^^^^^^^
 
diff --git a/Modules/FortranCInterface.cmake b/Modules/FortranCInterface.cmake
index 547346b..733c723 100644
--- a/Modules/FortranCInterface.cmake
+++ b/Modules/FortranCInterface.cmake
@@ -343,6 +343,13 @@
     set(_desc "Verifying Fortran/${lang} Compiler Compatibility")
     message(CHECK_START "${_desc}")
 
+    cmake_policy(GET CMP0056 _FortranCInterface_CMP0056)
+    if(_FortranCInterface_CMP0056 STREQUAL "NEW")
+      set(_FortranCInterface_EXE_LINKER_FLAGS "-DCMAKE_EXE_LINKER_FLAGS:STRING=${CMAKE_EXE_LINKER_FLAGS}")
+    else()
+      set(_FortranCInterface_EXE_LINKER_FLAGS "")
+    endif()
+
     # Build a sample project which reports symbols.
     set(CMAKE_TRY_COMPILE_CONFIGURATION Release)
     try_compile(FortranCInterface_VERIFY_${lang}_COMPILED
@@ -358,6 +365,7 @@
                  "-DCMAKE_C_FLAGS_RELEASE:STRING=${CMAKE_C_FLAGS_RELEASE}"
                  "-DCMAKE_CXX_FLAGS_RELEASE:STRING=${CMAKE_CXX_FLAGS_RELEASE}"
                  "-DCMAKE_Fortran_FLAGS_RELEASE:STRING=${CMAKE_Fortran_FLAGS_RELEASE}"
+                 ${_FortranCInterface_EXE_LINKER_FLAGS}
       OUTPUT_VARIABLE _output)
     file(WRITE "${FortranCInterface_BINARY_DIR}/Verify${lang}/output.txt" "${_output}")
 
diff --git a/Modules/FortranCInterface/Detect.cmake b/Modules/FortranCInterface/Detect.cmake
index c75067b..998faf1 100644
--- a/Modules/FortranCInterface/Detect.cmake
+++ b/Modules/FortranCInterface/Detect.cmake
@@ -26,6 +26,14 @@
 
 set(_result)
 
+cmake_policy(GET CMP0056 _FortranCInterface_CMP0056)
+if(_FortranCInterface_CMP0056 STREQUAL "NEW")
+  set(_FortranCInterface_EXE_LINKER_FLAGS "-DCMAKE_EXE_LINKER_FLAGS:STRING=${CMAKE_EXE_LINKER_FLAGS}")
+else()
+  set(_FortranCInterface_EXE_LINKER_FLAGS "")
+endif()
+unset(_FortranCInterface_CMP0056)
+
 # Build a sample project which reports symbols.
 set(CMAKE_TRY_COMPILE_CONFIGURATION Release)
 try_compile(FortranCInterface_COMPILED
@@ -38,9 +46,11 @@
     "-DCMAKE_Fortran_FLAGS:STRING=${CMAKE_Fortran_FLAGS}"
     "-DCMAKE_C_FLAGS_RELEASE:STRING=${CMAKE_C_FLAGS_RELEASE}"
     "-DCMAKE_Fortran_FLAGS_RELEASE:STRING=${CMAKE_Fortran_FLAGS_RELEASE}"
+    ${_FortranCInterface_EXE_LINKER_FLAGS}
   OUTPUT_VARIABLE FortranCInterface_OUTPUT)
 set(FortranCInterface_COMPILED ${FortranCInterface_COMPILED})
 unset(FortranCInterface_COMPILED CACHE)
+unset(_FortranCInterface_EXE_LINKER_FLAGS)
 
 # Locate the sample project executable.
 set(FortranCInterface_EXE)
diff --git a/Modules/GNUInstallDirs.cmake b/Modules/GNUInstallDirs.cmake
index 13d067a..888f7b1 100644
--- a/Modules/GNUInstallDirs.cmake
+++ b/Modules/GNUInstallDirs.cmake
@@ -113,7 +113,7 @@
 
   ::
 
-    GNUInstallDirs_get_absolute_install_dir(absvar var)
+    GNUInstallDirs_get_absolute_install_dir(absvar var dirname)
 
   Set the given variable ``absvar`` to the absolute path contained
   within the variable ``var``.  This is to allow the computation of an
@@ -121,7 +121,8 @@
   above.  While this macro is used to compute the various
   ``CMAKE_INSTALL_FULL_<dir>`` variables, it is exposed publicly to
   allow users who create additional path variables to also compute
-  absolute paths where necessary, using the same logic.
+  absolute paths where necessary, using the same logic.  ``dirname`` is
+  the directory name to get, e.g. ``BINDIR``.
 #]=======================================================================]
 
 cmake_policy(PUSH)
@@ -334,13 +335,25 @@
   )
 
 macro(GNUInstallDirs_get_absolute_install_dir absvar var)
+  set(GGAID_extra_args ${ARGN})
+  list(LENGTH GGAID_extra_args GGAID_extra_arg_count)
+  if(GGAID_extra_arg_count GREATER 0)
+    list(GET GGAID_extra_args 0 GGAID_dir)
+  else()
+    # Historical behaviour: use ${dir} from caller's scope
+    set(GGAID_dir "${dir}")
+    message(AUTHOR_WARNING
+      "GNUInstallDirs_get_absolute_install_dir called without third argument. "
+      "Using \${dir} from the caller's scope for compatibility with CMake 3.19 and below.")
+  endif()
+
   if(NOT IS_ABSOLUTE "${${var}}")
     # Handle special cases:
     # - CMAKE_INSTALL_PREFIX == /
     # - CMAKE_INSTALL_PREFIX == /usr
     # - CMAKE_INSTALL_PREFIX == /opt/...
     if("${CMAKE_INSTALL_PREFIX}" STREQUAL "/")
-      if("${dir}" STREQUAL "SYSCONFDIR" OR "${dir}" STREQUAL "LOCALSTATEDIR" OR "${dir}" STREQUAL "RUNSTATEDIR")
+      if("${GGAID_dir}" STREQUAL "SYSCONFDIR" OR "${GGAID_dir}" STREQUAL "LOCALSTATEDIR" OR "${GGAID_dir}" STREQUAL "RUNSTATEDIR")
         set(${absvar} "/${${var}}")
       else()
         if (NOT "${${var}}" MATCHES "^usr/")
@@ -349,13 +362,13 @@
         set(${absvar} "/${${var}}")
       endif()
     elseif("${CMAKE_INSTALL_PREFIX}" MATCHES "^/usr/?$")
-      if("${dir}" STREQUAL "SYSCONFDIR" OR "${dir}" STREQUAL "LOCALSTATEDIR" OR "${dir}" STREQUAL "RUNSTATEDIR")
+      if("${GGAID_dir}" STREQUAL "SYSCONFDIR" OR "${GGAID_dir}" STREQUAL "LOCALSTATEDIR" OR "${GGAID_dir}" STREQUAL "RUNSTATEDIR")
         set(${absvar} "/${${var}}")
       else()
         set(${absvar} "${CMAKE_INSTALL_PREFIX}/${${var}}")
       endif()
     elseif("${CMAKE_INSTALL_PREFIX}" MATCHES "^/opt/.*")
-      if("${dir}" STREQUAL "SYSCONFDIR" OR "${dir}" STREQUAL "LOCALSTATEDIR" OR "${dir}" STREQUAL "RUNSTATEDIR")
+      if("${GGAID_dir}" STREQUAL "SYSCONFDIR" OR "${GGAID_dir}" STREQUAL "LOCALSTATEDIR" OR "${GGAID_dir}" STREQUAL "RUNSTATEDIR")
         set(${absvar} "/${${var}}${CMAKE_INSTALL_PREFIX}")
       else()
         set(${absvar} "${CMAKE_INSTALL_PREFIX}/${${var}}")
@@ -366,6 +379,10 @@
   else()
     set(${absvar} "${${var}}")
   endif()
+
+  unset(GGAID_dir)
+  unset(GGAID_extra_arg_count)
+  unset(GGAID_extra_args)
 endmacro()
 
 # Result directories
@@ -388,7 +405,7 @@
     MANDIR
     DOCDIR
     )
-  GNUInstallDirs_get_absolute_install_dir(CMAKE_INSTALL_FULL_${dir} CMAKE_INSTALL_${dir})
+  GNUInstallDirs_get_absolute_install_dir(CMAKE_INSTALL_FULL_${dir} CMAKE_INSTALL_${dir} ${dir})
 endforeach()
 
 cmake_policy(POP)
diff --git a/Modules/Internal/CPack/CPack.NuGet.nuspec.in b/Modules/Internal/CPack/CPack.NuGet.nuspec.in
index b7beb5d..d89d69f 100644
--- a/Modules/Internal/CPack/CPack.NuGet.nuspec.in
+++ b/Modules/Internal/CPack/CPack.NuGet.nuspec.in
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
+<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
     <metadata>
         <!-- Required elements-->
         <id>@CPACK_NUGET_PACKAGE_NAME@</id>
@@ -12,11 +12,14 @@
         @_CPACK_NUGET_OWNERS_TAG@
         @_CPACK_NUGET_PROJECTURL_TAG@
         @_CPACK_NUGET_LICENSEURL_TAG@
+        @_CPACK_NUGET_LICENSE_TAG@
         @_CPACK_NUGET_ICONURL_TAG@
+        @_CPACK_NUGET_ICON_TAG@
         @_CPACK_NUGET_REQUIRELICENSEACCEPTANCE_TAG@
         @_CPACK_NUGET_SUMMARY_TAG@
         @_CPACK_NUGET_RELEASENOTES_TAG@
         @_CPACK_NUGET_COPYRIGHT_TAG@
+        @_CPACK_NUGET_LANGUAGE_TAG@
         @_CPACK_NUGET_TAGS_TAG@
         @_CPACK_NUGET_DEPENDENCIES_TAG@
     </metadata>
diff --git a/Modules/Internal/CPack/CPackDeb.cmake b/Modules/Internal/CPack/CPackDeb.cmake
index 431b074..48d451a 100644
--- a/Modules/Internal/CPack/CPackDeb.cmake
+++ b/Modules/Internal/CPack/CPackDeb.cmake
@@ -768,6 +768,10 @@
     set(GEN_CPACK_DBGSYM_OUTPUT_FILE_NAME "${CPACK_DBGSYM_OUTPUT_FILE_NAME}" PARENT_SCOPE)
     list(JOIN BUILD_IDS " " BUILD_IDS)
     set(GEN_BUILD_IDS "${BUILD_IDS}" PARENT_SCOPE)
+  else()
+    unset(GEN_DBGSYMDIR PARENT_SCOPE)
+    unset(GEN_CPACK_DBGSYM_OUTPUT_FILE_NAME PARENT_SCOPE)
+    unset(GEN_BUILD_IDS PARENT_SCOPE)
   endif()
 endfunction()
 
diff --git a/Modules/Internal/CPack/CPackNuGet.cmake b/Modules/Internal/CPack/CPackNuGet.cmake
index 20eed2e..56bbffd 100644
--- a/Modules/Internal/CPack/CPackNuGet.cmake
+++ b/Modules/Internal/CPack/CPackNuGet.cmake
@@ -107,18 +107,41 @@
 function(_cpack_nuget_variable_fallback_and_wrap_into_element ELEMENT NUGET_VAR_NAME)
     set(_options)
     set(_one_value_args)
-    set(_multi_value_args FALLBACK_VARS)
-    cmake_parse_arguments(PARSE_ARGV 0 _args "${_options}" "${_one_value_args}" "${_multi_value_args}")
+    set(_multi_value_args FALLBACK_VARS ATTRIBUTES)
+    cmake_parse_arguments(PARSE_ARGV 2 _args "${_options}" "${_one_value_args}" "${_multi_value_args}")
+
+    if(_args_ATTRIBUTES)
+        list(JOIN _args_ATTRIBUTES " " _attributes)
+        string(PREPEND _attributes " ")
+    endif()
 
     _cpack_nuget_variable_fallback(_value ${NUGET_VAR_NAME} ${ARGN} USE_CDATA)
 
+    string(TOUPPER "${ELEMENT}" _ELEMENT_UP)
     if(_value)
-        string(TOUPPER "${ELEMENT}" _ELEMENT_UP)
         set(
             _CPACK_NUGET_${_ELEMENT_UP}_TAG
-            "<${ELEMENT}>${_value}</${ELEMENT}>"
+            "<${ELEMENT}${_attributes}>${_value}</${ELEMENT}>"
             PARENT_SCOPE
           )
+    elseif(_attributes)
+        set(
+            _CPACK_NUGET_${_ELEMENT_UP}_TAG
+            "<${ELEMENT}${_attributes} />"
+            PARENT_SCOPE
+          )
+    endif()
+endfunction()
+
+# Warn of obsolete nuspec fields, referencing CMake variables and suggested
+# replacement, if any
+function(_cpack_nuget_deprecation_warning NUGET_ELEMENT VARNAME REPLACEMENT)
+    if(${VARNAME})
+        if(REPLACEMENT)
+            message(DEPRECATION "nuspec element `${NUGET_ELEMENT}` is deprecated in NuGet; consider replacing `${VARNAME}` with `${REPLACEMENT}`")
+        else()
+            message(DEPRECATION "nuspec element `${NUGET_ELEMENT}` is deprecated in NuGet; consider removing `${VARNAME}`")
+        endif()
     endif()
 endfunction()
 
@@ -168,6 +191,21 @@
         set(CPACK_NUGET_PACKAGE_NAME "${CPACK_PACKAGE_NAME}")
     endif()
 
+    # Warn about deprecated nuspec elements; warnings only display if
+    # variable is set
+    # Note that while nuspec's "summary" element is deprecated, there
+    # is no suggested replacement so (for now) no deprecation warning
+    # is shown for `CPACK_NUGET_*_DESCRIPTION_SUMMARY`
+    _cpack_nuget_deprecation_warning("licenseUrl" CPACK_NUGET_PACKAGE_LICENSEURL
+        "CPACK_NUGET_PACKAGE_LICENSE_FILE_NAME or CPACK_NUGET_PACKAGE_LICENSE_EXPRESSION")
+    _cpack_nuget_deprecation_warning("licenseUrl" CPACK_NUGET_${CPACK_NUGET_PACKAGE_COMPONENT}_LICENSEURL
+        "CPACK_NUGET_${CPACK_NUGET_PACKAGE_COMPONENT}_LICENSE_FILE_NAME or CPACK_NUGET_${CPACK_NUGET_PACKAGE_COMPONENT}_LICENSE_EXPRESSION")
+    _cpack_nuget_deprecation_warning("iconUrl" CPACK_NUGET_PACKAGE_ICONURL
+        "CPACK_NUGET_PACKAGE_ICON")
+    _cpack_nuget_deprecation_warning("iconUrl" CPACK_NUGET_${CPACK_NUGET_PACKAGE_COMPONENT}_ICONURL
+        "CPACK_NUGET_${CPACK_NUGET_PACKAGE_COMPONENT}_ICON")
+
+    # Set nuspec fields
     _cpack_nuget_variable_fallback(
         CPACK_NUGET_PACKAGE_VERSION VERSION
         FALLBACK_VARS
@@ -207,8 +245,35 @@
         FALLBACK_VARS
             CPACK_PACKAGE_HOMEPAGE_URL
       )
+
+    # "licenseUrl" is deprecated in favor of "license"
     _cpack_nuget_variable_fallback_and_wrap_into_element(licenseUrl LICENSEURL)
+
+    # "iconUrl" is deprecated in favor of "icon"
     _cpack_nuget_variable_fallback_and_wrap_into_element(iconUrl ICONURL)
+
+    # "license" takes a "type" attribute of either "file" or "expression"
+    # "file" refers to a file path of a .txt or .md file relative to the installation root
+    # "expression" refers to simple or compound expression of license identifiers
+    # listed at https://spdx.org/licenses/
+    # Note that only one of CPACK_NUGET_PACKAGE_LICENSE_FILE_NAME and
+    # CPACK_NUGET_PACKAGE_LICENSE_EXPRESSION may be specified. If both are specified,
+    # CPACK_NUGET_PACKAGE_LICENSE_FILE_NAME takes precedence and CPACK_NUGET_PACKAGE_LICENSE_EXPRESSION is ignored.
+    if(CPACK_NUGET_PACKAGE_LICENSE_FILE_NAME)
+        _cpack_nuget_variable_fallback_and_wrap_into_element(
+            license LICENSE_FILE_NAME
+            ATTRIBUTES [[type="file"]]
+          )
+    elseif(CPACK_NUGET_PACKAGE_LICENSE_EXPRESSION)
+        _cpack_nuget_variable_fallback_and_wrap_into_element(
+            license LICENSE_EXPRESSION
+            ATTRIBUTES [[type="expression"]]
+          )
+    endif()
+
+    # "icon" refers to a file path relative to the installation root
+    _cpack_nuget_variable_fallback_and_wrap_into_element(icon ICON)
+    # "summary" is deprecated in favor of "description"
     _cpack_nuget_variable_fallback_and_wrap_into_element(
         summary DESCRIPTION_SUMMARY
         FALLBACK_VARS
@@ -222,7 +287,12 @@
     endif()
     _cpack_nuget_variable_fallback_and_wrap_into_element(releaseNotes RELEASE_NOTES)
     _cpack_nuget_variable_fallback_and_wrap_into_element(copyright COPYRIGHT)
+    # "language" is a locale identifier such as "en_CA"
+    _cpack_nuget_variable_fallback_and_wrap_into_element(language LANGUAGE)
     _cpack_nuget_variable_fallback_and_wrap_into_element(tags TAGS LIST_GLUE " ")
+    # "repository" holds repository metadata consisting of four optional
+    # attributes: "type", "url", "branch", and "commit". While all fields are
+    # considered optional, they are not independent. Currently unsupported.
 
     # Handle dependencies
     _cpack_nuget_variable_fallback(_deps DEPENDENCIES)
diff --git a/Modules/Internal/CPack/NSIS.template.in b/Modules/Internal/CPack/NSIS.template.in
index 6009ce0..b448c76 100644
--- a/Modules/Internal/CPack/NSIS.template.in
+++ b/Modules/Internal/CPack/NSIS.template.in
@@ -1,4 +1,4 @@
-; CPack install script designed for a nmake build
+; CPack install script designed for a nmake build
 
 ;--------------------------------
 ; You must define these values
diff --git a/Modules/Platform/Android-Clang.cmake b/Modules/Platform/Android-Clang.cmake
index 160eada..3a279ca 100644
--- a/Modules/Platform/Android-Clang.cmake
+++ b/Modules/Platform/Android-Clang.cmake
@@ -7,6 +7,23 @@
 endif()
 set(__ANDROID_COMPILER_CLANG 1)
 
+# Include the NDK hook.
+# It can be used by NDK to inject necessary fixes for an earlier cmake.
+if(CMAKE_ANDROID_NDK)
+  include(${CMAKE_ANDROID_NDK}/build/cmake/hooks/pre/Android-Clang.cmake OPTIONAL)
+endif()
+
+# Load flags from NDK. This file may provides the following variables:
+#   _ANDROID_NDK_INIT_CFLAGS
+#   _ANDROID_NDK_INIT_CFLAGS_DEBUG
+#   _ANDROID_NDK_INIT_CFLAGS_RELEASE
+#   _ANDROID_NDK_INIT_LDFLAGS
+#   _ANDROID_NDK_INIT_LDFLAGS_EXE
+if(CMAKE_ANDROID_NDK)
+  include(${CMAKE_ANDROID_NDK}/build/cmake/flags.cmake OPTIONAL
+          RESULT_VARIABLE _INCLUDED_FLAGS)
+endif()
+
 # Support for NVIDIA Nsight Tegra Visual Studio Edition was previously
 # implemented in the CMake VS IDE generators.  Avoid interfering with
 # that functionality for now.  Later we may try to integrate this.
@@ -34,20 +51,29 @@
 
 include(Platform/Android-Common)
 
-# The NDK toolchain configuration files at:
-#
-#   <ndk>/[build/core/]toolchains/*-clang*/setup.mk
-#
-# contain logic to set LLVM_TRIPLE for Clang-based toolchains for each target.
-# We need to produce the same target here to produce compatible binaries.
-include(Platform/Android/abi-${CMAKE_ANDROID_ARCH_ABI}-Clang)
+if(_INCLUDED_FLAGS)
+  # NDK provides the flags.
+  set(_ANDROID_ABI_INIT_CFLAGS "${_ANDROID_NDK_INIT_CFLAGS}")
+  set(_ANDROID_ABI_INIT_CFLAGS_DEBUG "${_ANDROID_NDK_INIT_CFLAGS_DEBUG}")
+  set(_ANDROID_ABI_INIT_CFLAGS_RELEASE "${_ANDROID_NDK_INIT_CFLAGS_RELEASE}")
+  set(_ANDROID_ABI_INIT_LDFLAGS "${_ANDROID_NDK_INIT_LDFLAGS}")
+  set(_ANDROID_ABI_INIT_EXE_LDFLAGS "${_ANDROID_NDK_INIT_LDFLAGS_EXE}")
+else()
+  # The NDK toolchain configuration files at:
+  #
+  #   <ndk>/[build/core/]toolchains/*-clang*/setup.mk
+  #
+  # contain logic to set LLVM_TRIPLE for Clang-based toolchains for each target.
+  # We need to produce the same target here to produce compatible binaries.
+  include(Platform/Android/abi-${CMAKE_ANDROID_ARCH_ABI}-Clang)
+endif()
 
 macro(__android_compiler_clang lang)
   if(NOT "x${lang}" STREQUAL "xASM")
     __android_compiler_common(${lang})
   endif()
   if(NOT CMAKE_${lang}_COMPILER_TARGET)
-    set(CMAKE_${lang}_COMPILER_TARGET "${_ANDROID_ABI_CLANG_TARGET}")
+    set(CMAKE_${lang}_COMPILER_TARGET "${CMAKE_ANDROID_ARCH_LLVM_TRIPLE}")
     if(CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED)
       string(APPEND CMAKE_${lang}_COMPILER_TARGET "${CMAKE_SYSTEM_VERSION}")
     endif()
@@ -57,3 +83,9 @@
     set(_ANDROID_STL_NOSTDLIBXX 1)
   endif()
 endmacro()
+
+# Include the NDK hook.
+# It can be used by NDK to inject necessary fixes for an earlier cmake.
+if(CMAKE_ANDROID_NDK)
+  include(${CMAKE_ANDROID_NDK}/build/cmake/hooks/post/Android-Clang.cmake OPTIONAL)
+endif()
diff --git a/Modules/Platform/Android-Common.cmake b/Modules/Platform/Android-Common.cmake
index 581fde4..39da933 100644
--- a/Modules/Platform/Android-Common.cmake
+++ b/Modules/Platform/Android-Common.cmake
@@ -53,6 +53,12 @@
       set(_ANDROID_STL_RTTI 0)
       macro(__android_stl lang)
         string(APPEND CMAKE_${lang}_FLAGS_INIT " -stdlib=libstdc++")
+        if(_ANDROID_STL_EXCEPTIONS OR _ANDROID_STL_RTTI)
+          string(APPEND CMAKE_${lang}_STANDARD_LIBRARIES " -lc++abi")
+          if(CMAKE_SYSTEM_VERSION LESS 21)
+            list(APPEND CMAKE_${lang}_STANDARD_LIBRARIES "-landroid_support")
+          endif()
+        endif()
       endmacro()
     elseif(CMAKE_ANDROID_STL_TYPE STREQUAL "c++_static")
       set(_ANDROID_STL_EXCEPTIONS 1)
@@ -81,6 +87,12 @@
         "Android: STL '${CMAKE_ANDROID_STL_TYPE}' not supported by this NDK."
         )
     endif()
+    if(DEFINED CMAKE_ANDROID_RTTI)
+      set(_ANDROID_STL_RTTI ${CMAKE_ANDROID_RTTI})
+    endif()
+    if(DEFINED CMAKE_ANDROID_EXCEPTIONS)
+      set(_ANDROID_STL_EXCEPTIONS ${CMAKE_ANDROID_EXCEPTIONS})
+    endif()
   elseif(CMAKE_ANDROID_NDK)
 
     macro(__android_stl_inc lang dir req)
diff --git a/Modules/Platform/Android-Determine.cmake b/Modules/Platform/Android-Determine.cmake
index bc66ba1..c279086 100644
--- a/Modules/Platform/Android-Determine.cmake
+++ b/Modules/Platform/Android-Determine.cmake
@@ -5,6 +5,12 @@
 # This module detects platform-wide information about the Android target
 # in order to store it in "CMakeSystem.cmake".
 
+# Include the NDK hook.
+# It can be used by NDK to inject necessary fixes for an earlier cmake.
+if(CMAKE_ANDROID_NDK)
+  include(${CMAKE_ANDROID_NDK}/build/cmake/hooks/pre/Android-Determine.cmake OPTIONAL)
+endif()
+
 # Support for NVIDIA Nsight Tegra Visual Studio Edition was previously
 # implemented in the CMake VS IDE generators.  Avoid interfering with
 # that functionality for now.
@@ -209,6 +215,14 @@
   # NDK >= 18 has abis.cmake. It provides:
   #   NDK_KNOWN_DEVICE_ABI32S
   #   NDK_KNOWN_DEVICE_ABI64S
+  # NDK >= 23 also provides:
+  #   NDK_KNOWN_DEVICE_ABIS
+  #   NDK_ABI_<abi>_PROC
+  #   NDK_ABI_<abi>_ARCH
+  #   NDK_ABI_<abi>_TRIPLE
+  #   NDK_ABI_<abi>_LLVM_TRIPLE
+  #   NDK_PROC_<processor>_ABI
+  #   NDK_ARCH_<arch>_ABI
   include("${CMAKE_ANDROID_NDK}/build/cmake/abis.cmake" OPTIONAL RESULT_VARIABLE _INCLUDED_ABIS)
 endif()
 
@@ -247,60 +261,75 @@
 endif()
 
 if(_INCLUDED_ABIS)
-  set(_ANDROID_KNOWN_ABIS ${NDK_KNOWN_DEVICE_ABI32S} ${NDK_KNOWN_DEVICE_ABI64S})
+  if(NDK_KNOWN_DEVICE_ABIS)
+    set(_ANDROID_KNOWN_ABIS ${NDK_KNOWN_DEVICE_ABIS})
+  else()
+    set(_ANDROID_KNOWN_ABIS ${NDK_KNOWN_DEVICE_ABI32S} ${NDK_KNOWN_DEVICE_ABI64S})
+  endif()
 endif()
 
-# https://developer.android.com/ndk/guides/abis.html
+if(NOT DEFINED NDK_KNOWN_DEVICE_ABIS)
+  # The NDK is not new enough to provide ABI information.
+  # https://developer.android.com/ndk/guides/abis.html
 
-set(_ANDROID_ABI_arm64-v8a_PROC     "aarch64")
-set(_ANDROID_ABI_arm64-v8a_ARCH     "arm64")
-set(_ANDROID_ABI_arm64-v8a_TRIPLE   "aarch64-linux-android")
-set(_ANDROID_ABI_armeabi-v7a_PROC   "armv7-a")
-set(_ANDROID_ABI_armeabi-v7a_ARCH   "arm")
-set(_ANDROID_ABI_armeabi-v7a_TRIPLE "arm-linux-androideabi")
-set(_ANDROID_ABI_armeabi-v6_PROC    "armv6")
-set(_ANDROID_ABI_armeabi-v6_ARCH    "arm")
-set(_ANDROID_ABI_armeabi-v6_TRIPLE  "arm-linux-androideabi")
-set(_ANDROID_ABI_armeabi_PROC       "armv5te")
-set(_ANDROID_ABI_armeabi_ARCH       "arm")
-set(_ANDROID_ABI_armeabi_TRIPLE     "arm-linux-androideabi")
-set(_ANDROID_ABI_mips_PROC          "mips")
-set(_ANDROID_ABI_mips_ARCH          "mips")
-set(_ANDROID_ABI_mips_TRIPLE        "mipsel-linux-android")
-set(_ANDROID_ABI_mips64_PROC        "mips64")
-set(_ANDROID_ABI_mips64_ARCH        "mips64")
-set(_ANDROID_ABI_mips64_TRIPLE      "mips64el-linux-android")
-set(_ANDROID_ABI_x86_PROC           "i686")
-set(_ANDROID_ABI_x86_ARCH           "x86")
-set(_ANDROID_ABI_x86_TRIPLE         "i686-linux-android")
-set(_ANDROID_ABI_x86_64_PROC        "x86_64")
-set(_ANDROID_ABI_x86_64_ARCH        "x86_64")
-set(_ANDROID_ABI_x86_64_TRIPLE      "x86_64-linux-android")
+  set(NDK_ABI_arm64-v8a_PROC           "aarch64")
+  set(NDK_ABI_arm64-v8a_ARCH           "arm64")
+  set(NDK_ABI_arm64-v8a_TRIPLE         "aarch64-linux-android")
+  set(NDK_ABI_arm64-v8a_LLVM_TRIPLE    "aarch64-none-linux-android")
+  set(NDK_ABI_armeabi-v7a_PROC         "armv7-a")
+  set(NDK_ABI_armeabi-v7a_ARCH         "arm")
+  set(NDK_ABI_armeabi-v7a_TRIPLE       "arm-linux-androideabi")
+  set(NDK_ABI_armeabi-v7a_LLVM_TRIPLE  "armv7-none-linux-androideabi")
+  set(NDK_ABI_armeabi-v6_PROC          "armv6")
+  set(NDK_ABI_armeabi-v6_ARCH          "arm")
+  set(NDK_ABI_armeabi-v6_TRIPLE        "arm-linux-androideabi")
+  set(NDK_ABI_armeabi-v6_LLVM_TRIPLE   "armv6-none-linux-androideabi")
+  set(NDK_ABI_armeabi_PROC             "armv5te")
+  set(NDK_ABI_armeabi_ARCH             "arm")
+  set(NDK_ABI_armeabi_TRIPLE           "arm-linux-androideabi")
+  set(NDK_ABI_armeabi_LLVM_TRIPLE      "armv5te-none-linux-androideabi")
+  set(NDK_ABI_mips_PROC                "mips")
+  set(NDK_ABI_mips_ARCH                "mips")
+  set(NDK_ABI_mips_TRIPLE              "mipsel-linux-android")
+  set(NDK_ABI_mips_LLVM_TRIPLE         "mipsel-none-linux-android")
+  set(NDK_ABI_mips64_PROC              "mips64")
+  set(NDK_ABI_mips64_ARCH              "mips64")
+  set(NDK_ABI_mips64_TRIPLE            "mips64el-linux-android")
+  set(NDK_ABI_mips64_LLVM_TRIPLE       "mips64el-none-linux-android")
+  set(NDK_ABI_x86_PROC                 "i686")
+  set(NDK_ABI_x86_ARCH                 "x86")
+  set(NDK_ABI_x86_TRIPLE               "i686-linux-android")
+  set(NDK_ABI_x86_LLVM_TRIPLE          "i686-none-linux-android")
+  set(NDK_ABI_x86_64_PROC              "x86_64")
+  set(NDK_ABI_x86_64_ARCH              "x86_64")
+  set(NDK_ABI_x86_64_TRIPLE            "x86_64-linux-android")
+  set(NDK_ABI_x86_64_LLVM_TRIPLE       "x86_64-none-linux-android")
 
-set(_ANDROID_PROC_aarch64_ARCH_ABI "arm64-v8a")
-set(_ANDROID_PROC_armv7-a_ARCH_ABI "armeabi-v7a")
-set(_ANDROID_PROC_armv6_ARCH_ABI   "armeabi-v6")
-set(_ANDROID_PROC_armv5te_ARCH_ABI "armeabi")
-set(_ANDROID_PROC_i686_ARCH_ABI    "x86")
-set(_ANDROID_PROC_mips_ARCH_ABI    "mips")
-set(_ANDROID_PROC_mips64_ARCH_ABI  "mips64")
-set(_ANDROID_PROC_x86_64_ARCH_ABI  "x86_64")
+  set(NDK_PROC_aarch64_ABI "arm64-v8a")
+  set(NDK_PROC_armv7-a_ABI "armeabi-v7a")
+  set(NDK_PROC_armv6_ABI   "armeabi-v6")
+  set(NDK_PROC_armv5te_ABI "armeabi")
+  set(NDK_PROC_i686_ABI    "x86")
+  set(NDK_PROC_mips_ABI    "mips")
+  set(NDK_PROC_mips64_ABI  "mips64")
+  set(NDK_PROC_x86_64_ABI  "x86_64")
 
-set(_ANDROID_ARCH_arm64_ABI  "arm64-v8a")
-set(_ANDROID_ARCH_arm_ABI    "armeabi")
-set(_ANDROID_ARCH_mips_ABI   "mips")
-set(_ANDROID_ARCH_mips64_ABI "mips64")
-set(_ANDROID_ARCH_x86_ABI    "x86")
-set(_ANDROID_ARCH_x86_64_ABI "x86_64")
+  set(NDK_ARCH_arm64_ABI  "arm64-v8a")
+  set(NDK_ARCH_arm_ABI    "armeabi")
+  set(NDK_ARCH_mips_ABI   "mips")
+  set(NDK_ARCH_mips64_ABI "mips64")
+  set(NDK_ARCH_x86_ABI    "x86")
+  set(NDK_ARCH_x86_64_ABI "x86_64")
+endif()
 
 # Validate inputs.
-if(CMAKE_ANDROID_ARCH_ABI AND NOT DEFINED "_ANDROID_ABI_${CMAKE_ANDROID_ARCH_ABI}_PROC")
+if(CMAKE_ANDROID_ARCH_ABI AND NOT DEFINED "NDK_ABI_${CMAKE_ANDROID_ARCH_ABI}_PROC")
   message(FATAL_ERROR "Android: Unknown ABI CMAKE_ANDROID_ARCH_ABI='${CMAKE_ANDROID_ARCH_ABI}'.")
 endif()
-if(CMAKE_SYSTEM_PROCESSOR AND NOT DEFINED "_ANDROID_PROC_${CMAKE_SYSTEM_PROCESSOR}_ARCH_ABI")
+if(CMAKE_SYSTEM_PROCESSOR AND NOT DEFINED "NDK_PROC_${CMAKE_SYSTEM_PROCESSOR}_ABI")
   message(FATAL_ERROR "Android: Unknown processor CMAKE_SYSTEM_PROCESSOR='${CMAKE_SYSTEM_PROCESSOR}'.")
 endif()
-if(_ANDROID_SYSROOT_ARCH AND NOT DEFINED "_ANDROID_ARCH_${_ANDROID_SYSROOT_ARCH}_ABI")
+if(_ANDROID_SYSROOT_ARCH AND NOT DEFINED "NDK_ARCH_${_ANDROID_SYSROOT_ARCH}_ABI")
   message(FATAL_ERROR
     "Android: Unknown architecture '${_ANDROID_SYSROOT_ARCH}' specified in CMAKE_SYSROOT:\n"
     "  ${CMAKE_SYSROOT}"
@@ -310,9 +339,9 @@
 # Select an ABI.
 if(NOT CMAKE_ANDROID_ARCH_ABI)
   if(CMAKE_SYSTEM_PROCESSOR)
-    set(CMAKE_ANDROID_ARCH_ABI "${_ANDROID_PROC_${CMAKE_SYSTEM_PROCESSOR}_ARCH_ABI}")
+    set(CMAKE_ANDROID_ARCH_ABI "${NDK_PROC_${CMAKE_SYSTEM_PROCESSOR}_ABI}")
   elseif(_ANDROID_SYSROOT_ARCH)
-    set(CMAKE_ANDROID_ARCH_ABI "${_ANDROID_ARCH_${_ANDROID_SYSROOT_ARCH}_ABI}")
+    set(CMAKE_ANDROID_ARCH_ABI "${NDK_ARCH_${_ANDROID_SYSROOT_ARCH}_ABI}")
   elseif(_INCLUDED_ABIS)
     # Default to the oldest ARM ABI.
     foreach(abi armeabi armeabi-v7a arm64-v8a)
@@ -368,7 +397,7 @@
     "Supported ABIS: ${_ANDROID_KNOWN_ABIS}."
   )
 endif()
-set(CMAKE_ANDROID_ARCH "${_ANDROID_ABI_${CMAKE_ANDROID_ARCH_ABI}_ARCH}")
+set(CMAKE_ANDROID_ARCH "${NDK_ABI_${CMAKE_ANDROID_ARCH_ABI}_ARCH}")
 if(_ANDROID_SYSROOT_ARCH AND NOT "x${_ANDROID_SYSROOT_ARCH}" STREQUAL "x${CMAKE_ANDROID_ARCH}")
   message(FATAL_ERROR
     "Android: Architecture '${_ANDROID_SYSROOT_ARCH}' specified in CMAKE_SYSROOT:\n"
@@ -376,15 +405,17 @@
     "does not match architecture '${CMAKE_ANDROID_ARCH}' for the ABI '${CMAKE_ANDROID_ARCH_ABI}'."
     )
 endif()
-set(CMAKE_ANDROID_ARCH_TRIPLE "${_ANDROID_ABI_${CMAKE_ANDROID_ARCH_ABI}_TRIPLE}")
+set(CMAKE_ANDROID_ARCH_TRIPLE "${NDK_ABI_${CMAKE_ANDROID_ARCH_ABI}_TRIPLE}")
+set(CMAKE_ANDROID_ARCH_LLVM_TRIPLE
+    "${NDK_ABI_${CMAKE_ANDROID_ARCH_ABI}_LLVM_TRIPLE}")
 
 # Select a processor.
 if(NOT CMAKE_SYSTEM_PROCESSOR)
-  set(CMAKE_SYSTEM_PROCESSOR "${_ANDROID_ABI_${CMAKE_ANDROID_ARCH_ABI}_PROC}")
+  set(CMAKE_SYSTEM_PROCESSOR "${NDK_ABI_${CMAKE_ANDROID_ARCH_ABI}_PROC}")
 endif()
 
 # If the user specified both an ABI and a processor then they might not match.
-if(NOT _ANDROID_ABI_${CMAKE_ANDROID_ARCH_ABI}_PROC STREQUAL CMAKE_SYSTEM_PROCESSOR)
+if(NOT NDK_ABI_${CMAKE_ANDROID_ARCH_ABI}_PROC STREQUAL CMAKE_SYSTEM_PROCESSOR)
   message(FATAL_ERROR "Android: The specified CMAKE_ANDROID_ARCH_ABI='${CMAKE_ANDROID_ARCH_ABI}' and CMAKE_SYSTEM_PROCESSOR='${CMAKE_SYSTEM_PROCESSOR}' is not a valid combination.")
 endif()
 
@@ -491,6 +522,7 @@
 if(CMAKE_ANDROID_NDK)
   string(APPEND CMAKE_SYSTEM_CUSTOM_CODE
     "set(CMAKE_ANDROID_ARCH_TRIPLE \"${CMAKE_ANDROID_ARCH_TRIPLE}\")\n"
+    "set(CMAKE_ANDROID_ARCH_LLVM_TRIPLE \"${CMAKE_ANDROID_ARCH_LLVM_TRIPLE}\")\n"
     "set(CMAKE_ANDROID_NDK_DEPRECATED_HEADERS \"${CMAKE_ANDROID_NDK_DEPRECATED_HEADERS}\")\n"
     "set(CMAKE_ANDROID_NDK_TOOLCHAIN_HOST_TAG \"${CMAKE_ANDROID_NDK_TOOLCHAIN_HOST_TAG}\")\n"
     "set(CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED \"${CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED}\")\n"
@@ -528,3 +560,9 @@
 message(STATUS "Android: Targeting API '${CMAKE_SYSTEM_VERSION}' with architecture '${CMAKE_ANDROID_ARCH}', ABI '${CMAKE_ANDROID_ARCH_ABI}', and processor '${CMAKE_SYSTEM_PROCESSOR}'")
 
 cmake_policy(POP)
+
+# Include the NDK hook.
+# It can be used by NDK to inject necessary fixes for an earlier cmake.
+if(CMAKE_ANDROID_NDK)
+  include(${CMAKE_ANDROID_NDK}/build/cmake/hooks/post/Android-Determine.cmake OPTIONAL)
+endif()
diff --git a/Modules/Platform/Android-Initialize.cmake b/Modules/Platform/Android-Initialize.cmake
index 5019c28..6116ae1 100644
--- a/Modules/Platform/Android-Initialize.cmake
+++ b/Modules/Platform/Android-Initialize.cmake
@@ -4,6 +4,12 @@
 # When CMAKE_SYSTEM_NAME is "Android", CMakeSystemSpecificInitialize loads this
 # module.
 
+# Include the NDK hook.
+# It can be used by NDK to inject necessary fixes for an earlier cmake.
+if(CMAKE_ANDROID_NDK)
+  include(${CMAKE_ANDROID_NDK}/build/cmake/hooks/pre/Android-Initialize.cmake OPTIONAL)
+endif()
+
 # Support for NVIDIA Nsight Tegra Visual Studio Edition was previously
 # implemented in the CMake VS IDE generators.  Avoid interfering with
 # that functionality for now.
@@ -17,7 +23,7 @@
   return()
 endif()
 
-set(CMAKE_BUILD_TYPE_INIT Debug)
+set(CMAKE_BUILD_TYPE_INIT "RelWithDebInfo")
 
 # Skip sysroot selection if the NDK has a unified toolchain.
 if(CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED)
@@ -53,3 +59,9 @@
     "Android: No CMAKE_SYSROOT was selected."
     )
 endif()
+
+# Include the NDK hook.
+# It can be used by NDK to inject necessary fixes for an earlier cmake.
+if(CMAKE_ANDROID_NDK)
+  include(${CMAKE_ANDROID_NDK}/build/cmake/hooks/post/Android-Initialize.cmake OPTIONAL)
+endif()
diff --git a/Modules/Platform/Android.cmake b/Modules/Platform/Android.cmake
index 8ffa1b2..e4b9a09 100644
--- a/Modules/Platform/Android.cmake
+++ b/Modules/Platform/Android.cmake
@@ -1,3 +1,9 @@
+# Include the NDK hook.
+# It can be used by NDK to inject necessary fixes for an earlier cmake.
+if(CMAKE_ANDROID_NDK)
+  include(${CMAKE_ANDROID_NDK}/build/cmake/hooks/pre/Android.cmake OPTIONAL)
+endif()
+
 include(Platform/Linux)
 
 set(ANDROID 1)
@@ -22,3 +28,65 @@
 if(CMAKE_VS_PLATFORM_NAME STREQUAL "Tegra-Android")
   set(CMAKE_LINK_LIBRARY_FLAG "")
 endif()
+
+# Commonly used Android toolchain files that pre-date CMake upstream support
+# set CMAKE_SYSTEM_VERSION to 1.  Avoid interfering with them.
+if(CMAKE_SYSTEM_VERSION EQUAL 1)
+  return()
+endif()
+
+if(CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED)
+  # Tell CMake not to search host sysroots for headers/libraries.
+
+  # All paths added to CMAKE_SYSTEM_*_PATH below will be rerooted under
+  # CMAKE_FIND_ROOT_PATH. This is set because:
+  # 1. Users may structure their libraries in a way similar to NDK. When they do that,
+  #    they can simply append another path to CMAKE_FIND_ROOT_PATH.
+  # 2. CMAKE_FIND_ROOT_PATH must be non-empty for CMAKE_FIND_ROOT_PATH_MODE_* == ONLY
+  #    to be meaningful. https://github.com/android-ndk/ndk/issues/890
+  list(APPEND CMAKE_FIND_ROOT_PATH "${CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED}/sysroot")
+
+  # Allow users to override these values in case they want more strict behaviors.
+  # For example, they may want to prevent the NDK's libz from being picked up so
+  # they can use their own.
+  # https://github.com/android-ndk/ndk/issues/517
+  if(NOT DEFINED CMAKE_FIND_ROOT_PATH_MODE_PROGRAM)
+    set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+  endif()
+
+  if(NOT DEFINED CMAKE_FIND_ROOT_PATH_MODE_LIBRARY)
+    set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+  endif()
+
+  if(NOT DEFINED CMAKE_FIND_ROOT_PATH_MODE_INCLUDE)
+    set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+  endif()
+
+  if(NOT DEFINED CMAKE_FIND_ROOT_PATH_MODE_PACKAGE)
+    set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
+  endif()
+
+  # Don't search paths in PATH environment variable.
+  if(NOT DEFINED CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH)
+    set(CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH OFF)
+  endif()
+
+  # Allows CMake to find headers in the architecture-specific include directories.
+  set(CMAKE_LIBRARY_ARCHITECTURE "${CMAKE_ANDROID_ARCH_TRIPLE}")
+
+  # Instructs CMake to search the correct API level for libraries.
+  # Besides the paths like <root>/<prefix>/lib/<arch>, cmake also searches <root>/<prefix>.
+  # So we can add the API level specific directory directly.
+  # https://github.com/android/ndk/issues/929
+  list(PREPEND CMAKE_SYSTEM_PREFIX_PATH
+    "/usr/lib/${CMAKE_LIBRARY_ARCHITECTURE}/${CMAKE_SYSTEM_VERSION}"
+    )
+
+  list(APPEND CMAKE_SYSTEM_PROGRAM_PATH "${CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED}/bin")
+endif()
+
+# Include the NDK hook.
+# It can be used by NDK to inject necessary fixes for an earlier cmake.
+if(CMAKE_ANDROID_NDK)
+  include(${CMAKE_ANDROID_NDK}/build/cmake/hooks/post/Android.cmake OPTIONAL)
+endif()
diff --git a/Modules/Platform/Android/Determine-Compiler.cmake b/Modules/Platform/Android/Determine-Compiler.cmake
index f9c2d89..f8eae62 100644
--- a/Modules/Platform/Android/Determine-Compiler.cmake
+++ b/Modules/Platform/Android/Determine-Compiler.cmake
@@ -7,6 +7,12 @@
 endif()
 set(__ANDROID_DETERMINE_COMPILER 1)
 
+# Include the NDK hook.
+# It can be used by NDK to inject necessary fixes for an earlier cmake.
+if(CMAKE_ANDROID_NDK)
+  include(${CMAKE_ANDROID_NDK}/build/cmake/hooks/pre/Determine-Compiler.cmake OPTIONAL)
+endif()
+
 # Support for NVIDIA Nsight Tegra Visual Studio Edition was previously
 # implemented in the CMake VS IDE generators.  Avoid interfering with
 # that functionality for now.  Later we may try to integrate this.
@@ -83,3 +89,9 @@
 ")
   endif()
 endmacro()
+
+# Include the NDK hook.
+# It can be used by NDK to inject necessary fixes for an earlier cmake.
+if(CMAKE_ANDROID_NDK)
+  include(${CMAKE_ANDROID_NDK}/build/cmake/hooks/post/Determine-Compiler.cmake OPTIONAL)
+endif()
diff --git a/Modules/Platform/Android/abi-arm64-v8a-Clang.cmake b/Modules/Platform/Android/abi-arm64-v8a-Clang.cmake
index f4717d5..c18c0a2 100644
--- a/Modules/Platform/Android/abi-arm64-v8a-Clang.cmake
+++ b/Modules/Platform/Android/abi-arm64-v8a-Clang.cmake
@@ -1,6 +1,3 @@
-# <ndk>/build/core/toolchains/aarch64-linux-android-clang/setup.mk
-set(_ANDROID_ABI_CLANG_TARGET "aarch64-none-linux-android")
-
 # Suppress -Wl,-z,nocopyreloc flag on arm64-v8a
 set(_ANDROID_ABI_INIT_EXE_LDFLAGS_NO_nocopyreloc 1)
 
diff --git a/Modules/Platform/Android/abi-armeabi-Clang.cmake b/Modules/Platform/Android/abi-armeabi-Clang.cmake
index b857bd3..2b1de03 100644
--- a/Modules/Platform/Android/abi-armeabi-Clang.cmake
+++ b/Modules/Platform/Android/abi-armeabi-Clang.cmake
@@ -1,6 +1,3 @@
-# <ndk>/build/core/toolchains/arm-linux-androideabi-clang/setup.mk
-set(_ANDROID_ABI_CLANG_TARGET "armv5te-none-linux-androideabi")
-
 string(APPEND _ANDROID_ABI_INIT_CFLAGS
   " -march=armv5te"
   )
diff --git a/Modules/Platform/Android/abi-armeabi-v6-Clang.cmake b/Modules/Platform/Android/abi-armeabi-v6-Clang.cmake
index a7412f5..bb176ae 100644
--- a/Modules/Platform/Android/abi-armeabi-v6-Clang.cmake
+++ b/Modules/Platform/Android/abi-armeabi-v6-Clang.cmake
@@ -1,6 +1,3 @@
-# <ndk>/build/core/toolchains/arm-linux-androideabi-clang/setup.mk
-set(_ANDROID_ABI_CLANG_TARGET "armv6-none-linux-androideabi")
-
 string(APPEND _ANDROID_ABI_INIT_CFLAGS
   " -march=armv6"
   )
diff --git a/Modules/Platform/Android/abi-armeabi-v7a-Clang.cmake b/Modules/Platform/Android/abi-armeabi-v7a-Clang.cmake
index e2ab58b..6feeef6 100644
--- a/Modules/Platform/Android/abi-armeabi-v7a-Clang.cmake
+++ b/Modules/Platform/Android/abi-armeabi-v7a-Clang.cmake
@@ -1,6 +1,3 @@
-# <ndk>/build/core/toolchains/arm-linux-androideabi-clang/setup.mk
-set(_ANDROID_ABI_CLANG_TARGET "armv7-none-linux-androideabi")
-
 string(APPEND _ANDROID_ABI_INIT_CFLAGS
   " -march=armv7-a"
   )
diff --git a/Modules/Platform/Android/abi-mips-Clang.cmake b/Modules/Platform/Android/abi-mips-Clang.cmake
index 73addde..7df6a36 100644
--- a/Modules/Platform/Android/abi-mips-Clang.cmake
+++ b/Modules/Platform/Android/abi-mips-Clang.cmake
@@ -1,4 +1 @@
-# <ndk>/build/core/toolchains/mipsel-linux-android-clang/setup.mk
-set(_ANDROID_ABI_CLANG_TARGET "mipsel-none-linux-android")
-
 include(Platform/Android/abi-common-Clang)
diff --git a/Modules/Platform/Android/abi-mips64-Clang.cmake b/Modules/Platform/Android/abi-mips64-Clang.cmake
index 603f1b2..7df6a36 100644
--- a/Modules/Platform/Android/abi-mips64-Clang.cmake
+++ b/Modules/Platform/Android/abi-mips64-Clang.cmake
@@ -1,4 +1 @@
-# <ndk>/build/core/toolchains/mips64el-linux-android-clang/setup.mk
-set(_ANDROID_ABI_CLANG_TARGET "mips64el-none-linux-android")
-
 include(Platform/Android/abi-common-Clang)
diff --git a/Modules/Platform/Android/abi-x86-Clang.cmake b/Modules/Platform/Android/abi-x86-Clang.cmake
index fe7eace..7df6a36 100644
--- a/Modules/Platform/Android/abi-x86-Clang.cmake
+++ b/Modules/Platform/Android/abi-x86-Clang.cmake
@@ -1,4 +1 @@
-# <ndk>/build/core/toolchains/x86-clang/setup.mk
-set(_ANDROID_ABI_CLANG_TARGET "i686-none-linux-android")
-
 include(Platform/Android/abi-common-Clang)
diff --git a/Modules/Platform/Android/abi-x86_64-Clang.cmake b/Modules/Platform/Android/abi-x86_64-Clang.cmake
index 3cbcd49..7df6a36 100644
--- a/Modules/Platform/Android/abi-x86_64-Clang.cmake
+++ b/Modules/Platform/Android/abi-x86_64-Clang.cmake
@@ -1,4 +1 @@
-# <ndk>/build/core/toolchains/x86_64-clang/setup.mk
-set(_ANDROID_ABI_CLANG_TARGET "x86_64-none-linux-android")
-
 include(Platform/Android/abi-common-Clang)
diff --git a/Modules/Platform/Windows-Clang.cmake b/Modules/Platform/Windows-Clang.cmake
index 2261c90..6275043 100644
--- a/Modules/Platform/Windows-Clang.cmake
+++ b/Modules/Platform/Windows-Clang.cmake
@@ -112,7 +112,9 @@
     endif()
     if(DEFINED CMAKE_RC_PREPROCESSOR)
       set(CMAKE_DEPFILE_FLAGS_RC "${clang_option_prefix}-MD ${clang_option_prefix}-MF ${clang_option_prefix}<DEPFILE>")
-      set(CMAKE_RC_COMPILE_OBJECT "<CMAKE_COMMAND> -E cmake_llvm_rc <SOURCE> <OBJECT>.pp <${CMAKE_RC_PREPROCESSOR}> <DEFINES> -DRC_INVOKED <INCLUDES> <FLAGS> -E -- <SOURCE> ++ <CMAKE_RC_COMPILER> <DEFINES> -I <SOURCE_DIR> <INCLUDES> /fo <OBJECT> <OBJECT>.pp")
+      # 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> -E -- <SOURCE> ++ <CMAKE_RC_COMPILER> <DEFINES> -I <SOURCE_DIR> <INCLUDES> <FLAGS> /fo <OBJECT> <OBJECT>.pp")
       if(CMAKE_GENERATOR MATCHES "Ninja")
         set(CMAKE_NINJA_CMCLDEPS_RC 0)
         set(CMAKE_NINJA_DEP_TYPE_RC gcc)
diff --git a/Modules/Platform/Windows-MSVC.cmake b/Modules/Platform/Windows-MSVC.cmake
index bd08718..3f65475 100644
--- a/Modules/Platform/Windows-MSVC.cmake
+++ b/Modules/Platform/Windows-MSVC.cmake
@@ -163,6 +163,14 @@
   endif()
 endforeach()
 
+cmake_policy(GET CMP0117 __WINDOWS_MSVC_CMP0117)
+if(__WINDOWS_MSVC_CMP0117 STREQUAL "NEW")
+  set(_GR "")
+else()
+  set(_GR " /GR")
+endif()
+unset(__WINDOWS_MSVC_CMP0117)
+
 if(WINCE)
   foreach(lang C CXX)
     string(TOUPPER "${_MSVC_${lang}_ARCHITECTURE_FAMILY}" _MSVC_${lang}_ARCHITECTURE_FAMILY_UPPER)
@@ -182,7 +190,7 @@
 
   set(_RTC1 "")
   set(_FLAGS_C "")
-  set(_FLAGS_CXX " /GR /EHsc")
+  set(_FLAGS_CXX "${_GR} /EHsc")
 
   foreach(lang C CXX)
     if(_MSVC_${lang}_ARCHITECTURE_FAMILY STREQUAL "ARM")
@@ -204,7 +212,7 @@
 elseif(WINDOWS_PHONE OR WINDOWS_STORE)
   set(_PLATFORM_DEFINES "/DWIN32")
   set(_FLAGS_C " /DUNICODE /D_UNICODE")
-  set(_FLAGS_CXX " /DUNICODE /D_UNICODE /GR /EHsc")
+  set(_FLAGS_CXX " /DUNICODE /D_UNICODE${_GR} /EHsc")
   if(WINDOWS_STORE AND MSVC_VERSION GREATER 1899)
     set(CMAKE_C_STANDARD_LIBRARIES_INIT "WindowsApp.lib")
   elseif(WINDOWS_PHONE)
@@ -226,12 +234,12 @@
       set(_FLAGS_CXX " -frtti -fexceptions")
     else()
       set(_RTC1 "/RTC1")
-      set(_FLAGS_CXX " /GR /EHsc")
+      set(_FLAGS_CXX "${_GR} /EHsc")
     endif()
     set(CMAKE_C_STANDARD_LIBRARIES_INIT "kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib")
   else()
     set(_RTC1 "/GZ")
-    set(_FLAGS_CXX " /GR /GX")
+    set(_FLAGS_CXX "${_GR} /GX")
     set(CMAKE_C_STANDARD_LIBRARIES_INIT "kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib")
   endif()
 
@@ -241,6 +249,8 @@
   endif()
 endif()
 
+unset(_GR)
+
 set(CMAKE_CXX_STANDARD_LIBRARIES_INIT "${CMAKE_C_STANDARD_LIBRARIES_INIT}")
 
 # executable linker flags
diff --git a/Modules/TestBigEndian.cmake b/Modules/TestBigEndian.cmake
index 8a769b7..ea8ca73 100644
--- a/Modules/TestBigEndian.cmake
+++ b/Modules/TestBigEndian.cmake
@@ -5,19 +5,41 @@
 TestBigEndian
 -------------
 
-Define macro to determine endian type
+.. deprecated:: 3.20
 
-Check if the system is big endian or little endian
+  Supserseded by the :variable:`CMAKE_<LANG>_BYTE_ORDER` variable.
 
-::
+Check if the target architecture is big endian or little endian.
 
-  TEST_BIG_ENDIAN(VARIABLE)
-  VARIABLE - variable to store the result to
+.. command:: test_big_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.
+
 #]=======================================================================]
+include_guard()
 
 include(CheckTypeSize)
 
-macro(TEST_BIG_ENDIAN VARIABLE)
+function(TEST_BIG_ENDIAN VARIABLE)
+  if(";${CMAKE_C_BYTE_ORDER};${CMAKE_CXX_BYTE_ORDER};${CMAKE_CUDA_BYTE_ORDER};${CMAKE_OBJC_BYTE_ORDER};${CMAKE_OBJCXX_BYTE_ORDER};" MATCHES ";(BIG_ENDIAN|LITTLE_ENDIAN);")
+    set(order "${CMAKE_MATCH_1}")
+    if(order STREQUAL "BIG_ENDIAN")
+      set("${VARIABLE}" 1 PARENT_SCOPE)
+    else()
+      set("${VARIABLE}" 0 PARENT_SCOPE)
+    endif()
+  else()
+    __TEST_BIG_ENDIAN_LEGACY_IMPL(is_big)
+    set("${VARIABLE}" "${is_big}" PARENT_SCOPE)
+  endif()
+endfunction()
+
+macro(__TEST_BIG_ENDIAN_LEGACY_IMPL VARIABLE)
   if(NOT DEFINED HAVE_${VARIABLE})
     message(CHECK_START "Check if the system is big endian")
     message(CHECK_START "Searching 16 bit integer")
@@ -119,5 +141,3 @@
       endif()
   endif()
 endmacro()
-
-
diff --git a/Modules/UseJava.cmake b/Modules/UseJava.cmake
index db3fb95..bbd469e 100644
--- a/Modules/UseJava.cmake
+++ b/Modules/UseJava.cmake
@@ -406,8 +406,8 @@
 endfunction()
 
 # define helper scripts
-set(_JAVA_EXPORT_TARGETS_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/javaTargets.cmake.in)
-set(_JAVA_SYMLINK_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/UseJavaSymlinks.cmake)
+set(_JAVA_EXPORT_TARGETS_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/UseJava/javaTargets.cmake.in)
+set(_JAVA_SYMLINK_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/UseJava/Symlinks.cmake)
 
 if (CMAKE_HOST_WIN32 AND NOT CYGWIN AND CMAKE_HOST_SYSTEM_NAME MATCHES "Windows")
     set(_UseJava_PATH_SEP "$<SEMICOLON>")
@@ -636,7 +636,7 @@
             COMMAND ${CMAKE_COMMAND}
                 -DCMAKE_JAVA_CLASS_OUTPUT_PATH=${CMAKE_JAVA_CLASS_OUTPUT_PATH}
                 -DCMAKE_JAR_CLASSES_PREFIX=${CMAKE_JAR_CLASSES_PREFIX}
-                -P ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/UseJavaClassFilelist.cmake
+                -P ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/UseJava/ClassFilelist.cmake
             DEPENDS ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_compiled_${_TARGET_NAME}
             WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
             VERBATIM
diff --git a/Modules/UseJavaClassFilelist.cmake b/Modules/UseJava/ClassFilelist.cmake
similarity index 80%
rename from Modules/UseJavaClassFilelist.cmake
rename to Modules/UseJava/ClassFilelist.cmake
index 1c4baa9..aa9e35d 100644
--- a/Modules/UseJavaClassFilelist.cmake
+++ b/Modules/UseJava/ClassFilelist.cmake
@@ -1,18 +1,9 @@
 # Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
 # file Copyright.txt or https://cmake.org/licensing for details.
 
-#[=======================================================================[.rst:
-UseJavaClassFilelist
---------------------
-
-
-
-
-
-This script create a list of compiled Java class files to be added to
-a jar file.  This avoids including cmake files which get created in
-the binary directory.
-#]=======================================================================]
+# This script creates a list of compiled Java class files to be added to
+# a jar file.  This avoids including cmake files which get created in
+# the binary directory.
 
 if (CMAKE_JAVA_CLASS_OUTPUT_PATH)
     if (EXISTS "${CMAKE_JAVA_CLASS_OUTPUT_PATH}")
diff --git a/Modules/UseJavaSymlinks.cmake b/Modules/UseJava/Symlinks.cmake
similarity index 72%
rename from Modules/UseJavaSymlinks.cmake
rename to Modules/UseJava/Symlinks.cmake
index 3969f54..2788195 100644
--- a/Modules/UseJavaSymlinks.cmake
+++ b/Modules/UseJava/Symlinks.cmake
@@ -1,16 +1,7 @@
 # Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
 # file Copyright.txt or https://cmake.org/licensing for details.
 
-#[=======================================================================[.rst:
-UseJavaSymlinks
----------------
-
-
-
-
-
-Helper script for UseJava.cmake
-#]=======================================================================]
+# Helper script for UseJava.cmake
 
 if (UNIX AND _JAVA_TARGET_OUTPUT_LINK)
     if (_JAVA_TARGET_OUTPUT_NAME)
diff --git a/Modules/javaTargets.cmake.in b/Modules/UseJava/javaTargets.cmake.in
similarity index 100%
rename from Modules/javaTargets.cmake.in
rename to Modules/UseJava/javaTargets.cmake.in
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index ba378fb..d1616ad 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -441,6 +441,8 @@
   cmTest.h
   cmTestGenerator.cxx
   cmTestGenerator.h
+  cmTransformDepfile.cxx
+  cmTransformDepfile.h
   cmUuid.cxx
   cmUVHandlePtr.cxx
   cmUVHandlePtr.h
@@ -505,6 +507,8 @@
   cmCMakeLanguageCommand.h
   cmCMakeMinimumRequired.cxx
   cmCMakeMinimumRequired.h
+  cmCMakePathCommand.h
+  cmCMakePathCommand.cxx
   cmCMakePolicyCommand.cxx
   cmCMakePolicyCommand.h
   cmConditionEvaluator.cxx
@@ -830,6 +834,7 @@
 
 # Ninja support
 set(SRCS ${SRCS}
+  cmScanDepFormat.cxx
   cmGlobalNinjaGenerator.cxx
   cmGlobalNinjaGenerator.h
   cmNinjaTypes.h
@@ -1154,20 +1159,6 @@
 list(APPEND _tools cmake)
 target_link_libraries(cmake CMakeLib)
 
-add_library(CMakeServerLib
-  cmConnection.h cmConnection.cxx
-  cmFileMonitor.cxx cmFileMonitor.h
-  cmJsonObjectDictionary.h
-  cmJsonObjects.h
-  cmJsonObjects.cxx
-  cmPipeConnection.cxx cmPipeConnection.h
-  cmServer.cxx cmServer.h
-  cmServerConnection.cxx cmServerConnection.h
-  cmServerProtocol.cxx cmServerProtocol.h
-  )
-target_link_libraries(CMakeServerLib CMakeLib)
-target_link_libraries(cmake CMakeServerLib)
-
 # Build CTest executable
 add_executable(ctest ctest.cxx ${MANIFEST_FILE})
 list(APPEND _tools ctest)
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index bc0a66f..54b66ff 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,7 +1,7 @@
 # CMake version number components.
 set(CMake_VERSION_MAJOR 3)
 set(CMake_VERSION_MINOR 19)
-set(CMake_VERSION_PATCH 0)
+set(CMake_VERSION_PATCH 20201120)
 #set(CMake_VERSION_RC 0)
 set(CMake_VERSION_IS_DIRTY 0)
 
diff --git a/Source/CPack/cmCPackDebGenerator.cxx b/Source/CPack/cmCPackDebGenerator.cxx
index 560e5c1..6f21d87 100644
--- a/Source/CPack/cmCPackDebGenerator.cxx
+++ b/Source/CPack/cmCPackDebGenerator.cxx
@@ -507,7 +507,8 @@
                              this->GetOption("GEN_CPACK_OUTPUT_FILE_NAME"));
   packageFileNames.push_back(std::move(packageFileName));
 
-  if (this->IsOn("GEN_CPACK_DEBIAN_DEBUGINFO_PACKAGE")) {
+  if (this->IsOn("GEN_CPACK_DEBIAN_DEBUGINFO_PACKAGE") &&
+      this->GetOption("GEN_DBGSYMDIR")) {
     cmsys::Glob gl;
     std::string findExpr(this->GetOption("GEN_DBGSYMDIR"));
     findExpr += "/*";
diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx
index a9fe91c..8b544b4 100644
--- a/Source/CPack/cmCPackGenerator.cxx
+++ b/Source/CPack/cmCPackGenerator.cxx
@@ -1329,7 +1329,7 @@
                                      bool copyOnly /* = false */)
 {
   return this->MakefileMap->ConfigureFile(inName, outName, copyOnly, true,
-                                          false, true) == 1;
+                                          false) == 1;
 }
 
 int cmCPackGenerator::CleanTemporaryDirectory()
diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx
index 4d1a589..84bb791 100644
--- a/Source/CTest/cmCTestTestHandler.cxx
+++ b/Source/CTest/cmCTestTestHandler.cxx
@@ -122,7 +122,7 @@
       readit = status.GetMakefile().ReadDependentFile(fname);
     }
     if (!readit) {
-      status.SetError(cmStrCat("Could not find include file: ", fname));
+      status.SetError(cmStrCat("Could not load include file: ", fname));
       return false;
     }
   }
diff --git a/Source/CTest/cmCTestUpdateCommand.cxx b/Source/CTest/cmCTestUpdateCommand.cxx
index 6fef90a..0ba2c41 100644
--- a/Source/CTest/cmCTestUpdateCommand.cxx
+++ b/Source/CTest/cmCTestUpdateCommand.cxx
@@ -5,7 +5,6 @@
 #include "cmCTest.h"
 #include "cmCTestUpdateHandler.h"
 #include "cmMakefile.h"
-#include "cmProperty.h"
 #include "cmSystemTools.h"
 
 cmCTestGenericHandler* cmCTestUpdateCommand::InitializeHandler()
@@ -18,7 +17,7 @@
     this->CTest->SetCTestConfiguration(
       "SourceDirectory",
       cmSystemTools::CollapseFullPath(
-        cmToCStrSafe(this->Makefile->GetDefinition("CTEST_SOURCE_DIRECTORY"))),
+        this->Makefile->GetSafeDefinition("CTEST_SOURCE_DIRECTORY")),
       this->Quiet);
   }
   std::string source_dir =
diff --git a/Source/LexerParser/cmGccDepfileLexer.cxx b/Source/LexerParser/cmGccDepfileLexer.cxx
index a98969d..3630f4e 100644
--- a/Source/LexerParser/cmGccDepfileLexer.cxx
+++ b/Source/LexerParser/cmGccDepfileLexer.cxx
@@ -994,7 +994,7 @@
 YY_RULE_SETUP
 {
                          // A line continuation ends the current file name.
-                         yyextra->newDependency();
+                         yyextra->newRuleOrDependency();
                        }
 	YY_BREAK
 case 6:
diff --git a/Source/LexerParser/cmGccDepfileLexer.in.l b/Source/LexerParser/cmGccDepfileLexer.in.l
index 08f8577..c83cb75 100644
--- a/Source/LexerParser/cmGccDepfileLexer.in.l
+++ b/Source/LexerParser/cmGccDepfileLexer.in.l
@@ -42,7 +42,7 @@
                        }
 {WSPACE}*\\{NEWLINE}   {
                          // A line continuation ends the current file name.
-                         yyextra->newDependency();
+                         yyextra->newRuleOrDependency();
                        }
 {NEWLINE}              {
                          // A newline ends the current file name and the current rule.
diff --git a/Source/cmAddCustomCommandCommand.cxx b/Source/cmAddCustomCommandCommand.cxx
index 231a2d6..c1f98fa 100644
--- a/Source/cmAddCustomCommandCommand.cxx
+++ b/Source/cmAddCustomCommandCommand.cxx
@@ -190,15 +190,7 @@
         case doing_byproducts:
           if (!cmSystemTools::FileIsFullPath(copy)) {
             // This is an output to be generated, so it should be
-            // under the build tree.  CMake 2.4 placed this under the
-            // source tree.  However the only case that this change
-            // will break is when someone writes
-            //
-            //   add_custom_command(OUTPUT out.txt ...)
-            //
-            // and later references "${CMAKE_CURRENT_SOURCE_DIR}/out.txt".
-            // This is fairly obscure so we can wait for someone to
-            // complain.
+            // under the build tree.
             filename = cmStrCat(mf.GetCurrentBinaryDirectory(), '/');
           }
           filename += copy;
@@ -215,8 +207,7 @@
       }
 
       if (cmSystemTools::FileIsFullPath(filename)) {
-        filename = cmSystemTools::CollapseFullPath(
-          filename, status.GetMakefile().GetHomeOutputDirectory());
+        filename = cmSystemTools::CollapseFullPath(filename);
       }
       switch (doing) {
         case doing_depfile:
@@ -314,16 +305,9 @@
 
   // Check for an append request.
   if (append) {
-    if (mf.AppendCustomCommandToOutput(output[0], depends, implicit_depends,
-                                       commandLines)) {
-      return true;
-    }
-
-    // No command for this output exists.
-    status.SetError(
-      cmStrCat("given APPEND option with output\n  ", output[0],
-               "\nwhich is not already a custom command output."));
-    return false;
+    mf.AppendCustomCommandToOutput(output[0], depends, implicit_depends,
+                                   commandLines);
+    return true;
   }
 
   if (uses_terminal && !job_pool.empty()) {
diff --git a/Source/cmCMakePathCommand.cxx b/Source/cmCMakePathCommand.cxx
index 720f582..85e7d9e 100644
--- a/Source/cmCMakePathCommand.cxx
+++ b/Source/cmCMakePathCommand.cxx
@@ -250,9 +250,48 @@
   return true;
 }
 
+bool HandleSetCommand(std::vector<std::string> const& args,
+                      cmExecutionStatus& status)
+{
+  if (args.size() < 3 || args.size() > 4) {
+    status.SetError("SET must be called with two or three arguments.");
+    return false;
+  }
+
+  if (args[1].empty()) {
+    status.SetError("Invalid name for path variable.");
+    return false;
+  }
+
+  static NormalizeParser const parser;
+
+  const auto arguments = parser.Parse(args);
+
+  if (parser.GetInputs().size() != 1) {
+    status.SetError("SET called with unexpected arguments.");
+    return false;
+  }
+
+  auto path =
+    cmCMakePath(parser.GetInputs().front(), cmCMakePath::native_format);
+
+  if (arguments.Normalize) {
+    path = path.Normal();
+  }
+
+  status.GetMakefile().AddDefinition(args[1], path.GenericString());
+
+  return true;
+}
+
 bool HandleAppendCommand(std::vector<std::string> const& args,
                          cmExecutionStatus& status)
 {
+  if (args[1].empty()) {
+    status.SetError("Invalid name for path variable.");
+    return false;
+  }
+
   static OutputVariableParser const parser{};
 
   const auto arguments = parser.Parse(args);
@@ -272,8 +311,8 @@
   return true;
 }
 
-bool HandleConcatCommand(std::vector<std::string> const& args,
-                         cmExecutionStatus& status)
+bool HandleAppendStringCommand(std::vector<std::string> const& args,
+                               cmExecutionStatus& status)
 {
   static OutputVariableParser const parser{};
 
@@ -546,16 +585,6 @@
     });
 }
 
-bool HandleProximatePathCommand(std::vector<std::string> const& args,
-                                cmExecutionStatus& status)
-{
-  return HandleTransformPathCommand(
-    args, status,
-    [](const cmCMakePath& path, const std::string& base) -> cmCMakePath {
-      return path.Proximate(base);
-    });
-}
-
 bool HandleAbsolutePathCommand(std::vector<std::string> const& args,
                                cmExecutionStatus& status)
 {
@@ -567,40 +596,6 @@
     true);
 }
 
-bool HandleCMakePathCommand(std::vector<std::string> const& args,
-                            cmExecutionStatus& status)
-{
-  if (args.size() < 3 || args.size() > 4) {
-    status.SetError("CMAKE_PATH must be called with two or three arguments.");
-    return false;
-  }
-
-  static NormalizeParser const parser;
-
-  const auto arguments = parser.Parse(args);
-
-  if (parser.GetInputs().size() != 1) {
-    status.SetError("CMAKE_PATH called with unexpected arguments.");
-    return false;
-  }
-
-  if (args[1].empty()) {
-    status.SetError("Invalid name for output variable.");
-    return false;
-  }
-
-  auto path =
-    cmCMakePath(parser.GetInputs().front(), cmCMakePath::native_format);
-
-  if (arguments.Normalize) {
-    path = path.Normal();
-  }
-
-  status.GetMakefile().AddDefinition(args[1], path.GenericString());
-
-  return true;
-}
-
 bool HandleNativePathCommand(std::vector<std::string> const& args,
                              cmExecutionStatus& status)
 {
@@ -737,12 +732,7 @@
     return false;
   }
 
-  std::string inputPath;
-  if (!getInputPath(args[1], status, inputPath)) {
-    return false;
-  }
-
-  cmCMakePath path1(inputPath);
+  cmCMakePath path1(args[1]);
   cmCMakePath path2(args[3]);
   auto result = op->second(path1, path2);
 
@@ -987,17 +977,16 @@
 
   static cmSubcommandTable const subcommand{
     { "GET"_s, HandleGetCommand },
+    { "SET"_s, HandleSetCommand },
     { "APPEND"_s, HandleAppendCommand },
-    { "CONCAT"_s, HandleConcatCommand },
+    { "APPEND_STRING"_s, HandleAppendStringCommand },
     { "REMOVE_FILENAME"_s, HandleRemoveFilenameCommand },
     { "REPLACE_FILENAME"_s, HandleReplaceFilenameCommand },
     { "REMOVE_EXTENSION"_s, HandleRemoveExtensionCommand },
     { "REPLACE_EXTENSION"_s, HandleReplaceExtensionCommand },
     { "NORMAL_PATH"_s, HandleNormalPathCommand },
     { "RELATIVE_PATH"_s, HandleRelativePathCommand },
-    { "PROXIMATE_PATH"_s, HandleProximatePathCommand },
     { "ABSOLUTE_PATH"_s, HandleAbsolutePathCommand },
-    { "CMAKE_PATH"_s, HandleCMakePathCommand },
     { "NATIVE_PATH"_s, HandleNativePathCommand },
     { "CONVERT"_s, HandleConvertCommand },
     { "COMPARE"_s, HandleCompareCommand },
diff --git a/Source/cmCPluginAPI.cxx b/Source/cmCPluginAPI.cxx
index 8ebf6d2..968fa54 100644
--- a/Source/cmCPluginAPI.cxx
+++ b/Source/cmCPluginAPI.cxx
@@ -583,14 +583,12 @@
 {
   cmCPluginAPISourceFile* sf = static_cast<cmCPluginAPISourceFile*>(arg);
   if (cmSourceFile* rsf = sf->RealSourceFile) {
-    cmProp p = rsf->GetProperty(prop);
-    return cmToCStr(p);
+    return cmToCStr(rsf->GetProperty(prop));
   }
   if (!strcmp(prop, "LOCATION")) {
     return sf->FullPath.c_str();
   }
-  cmProp retVal = sf->Properties.GetPropertyValue(prop);
-  return cmToCStr(retVal);
+  return cmToCStr(sf->Properties.GetPropertyValue(prop));
 }
 
 int CCONV cmSourceFileGetPropertyAsBool(void* arg, const char* prop)
diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx
index c94f128..9e5b783 100644
--- a/Source/cmCommands.cxx
+++ b/Source/cmCommands.cxx
@@ -17,6 +17,7 @@
 #include "cmBreakCommand.h"
 #include "cmBuildCommand.h"
 #include "cmCMakeMinimumRequired.h"
+#include "cmCMakePathCommand.h"
 #include "cmCMakePolicyCommand.h"
 #include "cmCommand.h"
 #include "cmConfigureFileCommand.h"
@@ -118,11 +119,19 @@
 
 void GetScriptingCommands(cmState* state)
 {
-  state->AddBuiltinCommand("break", cmBreakCommand);
+  state->AddFlowControlCommand("break", cmBreakCommand);
+  state->AddFlowControlCommand("continue", cmContinueCommand);
+  state->AddFlowControlCommand("foreach", cmForEachCommand);
+  state->AddFlowControlCommand("function", cmFunctionCommand);
+  state->AddFlowControlCommand("if", cmIfCommand);
+  state->AddFlowControlCommand("macro", cmMacroCommand);
+  state->AddFlowControlCommand("return", cmReturnCommand);
+  state->AddFlowControlCommand("while", cmWhileCommand);
+
   state->AddBuiltinCommand("cmake_minimum_required", cmCMakeMinimumRequired);
+  state->AddBuiltinCommand("cmake_path", cmCMakePathCommand);
   state->AddBuiltinCommand("cmake_policy", cmCMakePolicyCommand);
   state->AddBuiltinCommand("configure_file", cmConfigureFileCommand);
-  state->AddBuiltinCommand("continue", cmContinueCommand);
   state->AddBuiltinCommand("exec_program", cmExecProgramCommand);
   state->AddBuiltinCommand("execute_process", cmExecuteProcessCommand);
   state->AddBuiltinCommand("file", cmFileCommand);
@@ -131,26 +140,21 @@
   state->AddBuiltinCommand("find_package", cmFindPackage);
   state->AddBuiltinCommand("find_path", cmFindPath);
   state->AddBuiltinCommand("find_program", cmFindProgram);
-  state->AddBuiltinCommand("foreach", cmForEachCommand);
-  state->AddBuiltinCommand("function", cmFunctionCommand);
   state->AddBuiltinCommand("get_cmake_property", cmGetCMakePropertyCommand);
   state->AddBuiltinCommand("get_directory_property",
                            cmGetDirectoryPropertyCommand);
   state->AddBuiltinCommand("get_filename_component",
                            cmGetFilenameComponentCommand);
   state->AddBuiltinCommand("get_property", cmGetPropertyCommand);
-  state->AddBuiltinCommand("if", cmIfCommand);
   state->AddBuiltinCommand("include", cmIncludeCommand);
   state->AddBuiltinCommand("include_guard", cmIncludeGuardCommand);
   state->AddBuiltinCommand("list", cmListCommand);
-  state->AddBuiltinCommand("macro", cmMacroCommand);
   state->AddBuiltinCommand("make_directory", cmMakeDirectoryCommand);
   state->AddBuiltinCommand("mark_as_advanced", cmMarkAsAdvancedCommand);
   state->AddBuiltinCommand("math", cmMathCommand);
   state->AddBuiltinCommand("message", cmMessageCommand);
   state->AddBuiltinCommand("option", cmOptionCommand);
   state->AddBuiltinCommand("cmake_parse_arguments", cmParseArgumentsCommand);
-  state->AddBuiltinCommand("return", cmReturnCommand);
   state->AddBuiltinCommand("separate_arguments", cmSeparateArgumentsCommand);
   state->AddBuiltinCommand("set", cmSetCommand);
   state->AddBuiltinCommand("set_directory_properties",
@@ -159,7 +163,6 @@
   state->AddBuiltinCommand("site_name", cmSiteNameCommand);
   state->AddBuiltinCommand("string", cmStringCommand);
   state->AddBuiltinCommand("unset", cmUnsetCommand);
-  state->AddBuiltinCommand("while", cmWhileCommand);
 
   state->AddUnexpectedCommand(
     "else",
diff --git a/Source/cmConfigureFileCommand.cxx b/Source/cmConfigureFileCommand.cxx
index 68322cc..edd261d 100644
--- a/Source/cmConfigureFileCommand.cxx
+++ b/Source/cmConfigureFileCommand.cxx
@@ -3,11 +3,15 @@
 #include "cmConfigureFileCommand.h"
 
 #include <set>
+#include <sstream>
 
 #include <cm/string_view>
 #include <cmext/string_view>
 
+#include <sys/types.h>
+
 #include "cmExecutionStatus.h"
+#include "cmFSPermissions.h"
 #include "cmMakefile.h"
 #include "cmMessageType.h"
 #include "cmNewLineStyle.h"
@@ -60,7 +64,19 @@
   }
   bool copyOnly = false;
   bool escapeQuotes = false;
-  bool use_source_permissions = true;
+  bool useSourcePermissions = false;
+  bool noSourcePermissions = false;
+  bool filePermissions = false;
+  std::vector<std::string> filePermissionOptions;
+
+  enum class Doing
+  {
+    DoingNone,
+    DoingFilePermissions,
+    DoneFilePermissions
+  };
+
+  Doing doing = Doing::DoingNone;
 
   static std::set<cm::string_view> noopOptions = {
     /* Legacy.  */
@@ -78,6 +94,9 @@
   bool atOnly = false;
   for (unsigned int i = 2; i < args.size(); ++i) {
     if (args[i] == "COPYONLY") {
+      if (doing == Doing::DoingFilePermissions) {
+        doing = Doing::DoneFilePermissions;
+      }
       copyOnly = true;
       if (newLineStyle.IsValid()) {
         status.SetError("COPYONLY could not be used in combination "
@@ -85,13 +104,49 @@
         return false;
       }
     } else if (args[i] == "ESCAPE_QUOTES") {
+      if (doing == Doing::DoingFilePermissions) {
+        doing = Doing::DoneFilePermissions;
+      }
       escapeQuotes = true;
     } else if (args[i] == "@ONLY") {
+      if (doing == Doing::DoingFilePermissions) {
+        doing = Doing::DoneFilePermissions;
+      }
       atOnly = true;
     } else if (args[i] == "NO_SOURCE_PERMISSIONS") {
-      use_source_permissions = false;
+      if (doing == Doing::DoingFilePermissions) {
+        status.SetError(" given both FILE_PERMISSIONS and "
+                        "NO_SOURCE_PERMISSIONS. Only one option allowed.");
+        return false;
+      }
+      noSourcePermissions = true;
+    } else if (args[i] == "USE_SOURCE_PERMISSIONS") {
+      if (doing == Doing::DoingFilePermissions) {
+        status.SetError(" given both FILE_PERMISSIONS and "
+                        "USE_SOURCE_PERMISSIONS. Only one option allowed.");
+        return false;
+      }
+      useSourcePermissions = true;
+    } else if (args[i] == "FILE_PERMISSIONS") {
+      if (useSourcePermissions) {
+        status.SetError(" given both FILE_PERMISSIONS and "
+                        "USE_SOURCE_PERMISSIONS. Only one option allowed.");
+        return false;
+      }
+      if (noSourcePermissions) {
+        status.SetError(" given both FILE_PERMISSIONS and "
+                        "NO_SOURCE_PERMISSIONS. Only one option allowed.");
+        return false;
+      }
+
+      if (doing == Doing::DoingNone) {
+        doing = Doing::DoingFilePermissions;
+        filePermissions = true;
+      }
     } else if (noopOptions.find(args[i]) != noopOptions.end()) {
       /* Ignore no-op options.  */
+    } else if (doing == Doing::DoingFilePermissions) {
+      filePermissionOptions.push_back(args[i]);
     } else {
       unknown_args += " ";
       unknown_args += args[i];
@@ -104,9 +159,53 @@
     status.GetMakefile().IssueMessage(MessageType::AUTHOR_WARNING, msg);
   }
 
-  if (!status.GetMakefile().ConfigureFile(
-        inputFile, outputFile, copyOnly, atOnly, escapeQuotes,
-        use_source_permissions, newLineStyle)) {
+  if (useSourcePermissions && noSourcePermissions) {
+    status.SetError(" given both USE_SOURCE_PERMISSIONS and "
+                    "NO_SOURCE_PERMISSIONS. Only one option allowed.");
+    return false;
+  }
+
+  mode_t permisiions = 0;
+
+  if (filePermissions) {
+    if (filePermissionOptions.empty()) {
+      status.SetError(" given FILE_PERMISSIONS without any options.");
+      return false;
+    }
+
+    std::vector<std::string> invalidOptions;
+    for (auto const& e : filePermissionOptions) {
+      if (!cmFSPermissions::stringToModeT(e, permisiions)) {
+        invalidOptions.push_back(e);
+      }
+    }
+
+    if (!invalidOptions.empty()) {
+      std::ostringstream oss;
+      oss << " given invalid permission ";
+      for (auto i = 0u; i < invalidOptions.size(); i++) {
+        if (i == 0u) {
+          oss << "\"" << invalidOptions[i] << "\"";
+        } else {
+          oss << ",\"" << invalidOptions[i] << "\"";
+        }
+      }
+      oss << ".";
+      status.SetError(oss.str());
+      return false;
+    }
+  }
+
+  if (noSourcePermissions) {
+    permisiions |= cmFSPermissions::mode_owner_read;
+    permisiions |= cmFSPermissions::mode_owner_write;
+    permisiions |= cmFSPermissions::mode_group_read;
+    permisiions |= cmFSPermissions::mode_world_read;
+  }
+
+  if (!status.GetMakefile().ConfigureFile(inputFile, outputFile, copyOnly,
+                                          atOnly, escapeQuotes, permisiions,
+                                          newLineStyle)) {
     status.SetError("Problem configuring file");
     return false;
   }
diff --git a/Source/cmConnection.cxx b/Source/cmConnection.cxx
deleted file mode 100644
index e4d0cf1..0000000
--- a/Source/cmConnection.cxx
+++ /dev/null
@@ -1,173 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
-   file Copyright.txt or https://cmake.org/licensing for details.  */
-#include "cmConnection.h"
-
-#include <cassert>
-#include <cstring>
-
-#include <cm3p/uv.h>
-
-#include "cmServer.h"
-
-struct write_req_t
-{
-  uv_write_t req;
-  uv_buf_t buf;
-};
-
-void cmEventBasedConnection::on_alloc_buffer(uv_handle_t* handle,
-                                             size_t suggested_size,
-                                             uv_buf_t* buf)
-{
-  (void)(handle);
-#ifndef __clang_analyzer__
-  char* rawBuffer = new char[suggested_size];
-  *buf = uv_buf_init(rawBuffer, static_cast<unsigned int>(suggested_size));
-#else
-  (void)(suggested_size);
-  (void)(buf);
-#endif /* __clang_analyzer__ */
-}
-
-void cmEventBasedConnection::on_read(uv_stream_t* stream, ssize_t nread,
-                                     const uv_buf_t* buf)
-{
-  auto conn = static_cast<cmEventBasedConnection*>(stream->data);
-  if (conn) {
-    if (nread >= 0) {
-      conn->ReadData(std::string(buf->base, buf->base + nread));
-    } else {
-      conn->OnDisconnect(static_cast<int>(nread));
-    }
-  }
-
-  delete[](buf->base);
-}
-
-void cmEventBasedConnection::on_close(uv_handle_t* /*handle*/)
-{
-}
-
-void cmEventBasedConnection::on_write(uv_write_t* req, int status)
-{
-  (void)(status);
-
-  // Free req and buffer
-  write_req_t* wr = reinterpret_cast<write_req_t*>(req);
-  delete[](wr->buf.base);
-  delete wr;
-}
-
-void cmEventBasedConnection::on_new_connection(uv_stream_t* stream, int status)
-{
-  (void)(status);
-  auto conn = static_cast<cmEventBasedConnection*>(stream->data);
-
-  if (conn) {
-    conn->Connect(stream);
-  }
-}
-
-bool cmEventBasedConnection::IsOpen() const
-{
-  return this->WriteStream != nullptr;
-}
-
-void cmEventBasedConnection::WriteData(const std::string& _data)
-{
-#ifndef NDEBUG
-  auto curr_thread_id = uv_thread_self();
-  assert(this->Server);
-  assert(uv_thread_equal(&curr_thread_id, &this->Server->ServeThreadId));
-#endif
-
-#ifndef __clang_analyzer__
-  auto data = _data;
-  assert(this->WriteStream.get());
-  if (BufferStrategy) {
-    data = BufferStrategy->BufferOutMessage(data);
-  }
-
-  auto ds = data.size();
-
-  write_req_t* req = new write_req_t;
-  req->req.data = this;
-  req->buf = uv_buf_init(new char[ds], static_cast<unsigned int>(ds));
-  memcpy(req->buf.base, data.c_str(), ds);
-  uv_write(reinterpret_cast<uv_write_t*>(req), this->WriteStream, &req->buf, 1,
-           on_write);
-#else
-  (void)(_data);
-#endif /* __clang_analyzer__ */
-}
-
-void cmEventBasedConnection::ReadData(const std::string& data)
-{
-  this->RawReadBuffer += data;
-  if (BufferStrategy) {
-    std::string packet = BufferStrategy->BufferMessage(this->RawReadBuffer);
-    while (!packet.empty()) {
-      ProcessRequest(packet);
-      packet = BufferStrategy->BufferMessage(this->RawReadBuffer);
-    }
-  } else {
-    ProcessRequest(this->RawReadBuffer);
-    this->RawReadBuffer.clear();
-  }
-}
-
-cmEventBasedConnection::cmEventBasedConnection(
-  cmConnectionBufferStrategy* bufferStrategy)
-  : BufferStrategy(bufferStrategy)
-{
-}
-
-void cmEventBasedConnection::Connect(uv_stream_t* server)
-{
-  (void)server;
-  Server->OnConnected(nullptr);
-}
-
-void cmEventBasedConnection::OnDisconnect(int onerror)
-{
-  (void)onerror;
-  this->OnConnectionShuttingDown();
-  if (this->Server) {
-    this->Server->OnDisconnect(this);
-  }
-}
-
-cmConnection::~cmConnection() = default;
-
-bool cmConnection::OnConnectionShuttingDown()
-{
-  this->Server = nullptr;
-  return true;
-}
-
-void cmConnection::SetServer(cmServerBase* s)
-{
-  Server = s;
-}
-
-void cmConnection::ProcessRequest(const std::string& request)
-{
-  Server->ProcessRequest(this, request);
-}
-
-bool cmConnection::OnServeStart(std::string* errString)
-{
-  (void)errString;
-  return true;
-}
-
-bool cmEventBasedConnection::OnConnectionShuttingDown()
-{
-  if (this->WriteStream.get()) {
-    this->WriteStream->data = nullptr;
-  }
-
-  WriteStream.reset();
-
-  return true;
-}
diff --git a/Source/cmConnection.h b/Source/cmConnection.h
deleted file mode 100644
index 5335a7f..0000000
--- a/Source/cmConnection.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
-   file Copyright.txt or https://cmake.org/licensing for details.  */
-
-#pragma once
-
-#include "cmConfigure.h" // IWYU pragma: keep
-
-#include <cstddef>
-#include <memory>
-#include <string>
-
-#include <cm3p/uv.h>
-
-#include "cmUVHandlePtr.h"
-
-class cmServerBase;
-
-/***
- * Given a sequence of bytes with any kind of buffering, instances of this
- * class arrange logical chunks according to whatever the use case is for
- * the connection.
- */
-class cmConnectionBufferStrategy
-{
-public:
-  virtual ~cmConnectionBufferStrategy();
-
-  /***
-   * Called whenever with an active raw buffer. If a logical chunk
-   * becomes available, that chunk is returned and that portion is
-   * removed from the rawBuffer
-   *
-   * @param rawBuffer in/out parameter. Receive buffer; the buffer strategy is
-   * free to manipulate this buffer anyway it needs to.
-   *
-   * @return Next chunk from the stream. Returns the empty string if a chunk
-   * isn't ready yet. Users of this interface should repeatedly call this
-   * function until an empty string is returned since its entirely possible
-   * multiple chunks come in a single raw buffer.
-   */
-  virtual std::string BufferMessage(std::string& rawBuffer) = 0;
-
-  /***
-   * Called to properly buffer an outgoing message.
-   *
-   * @param rawBuffer Message to format in the correct way
-   *
-   * @return Formatted message
-   */
-  virtual std::string BufferOutMessage(const std::string& rawBuffer) const
-  {
-    return rawBuffer;
-  };
-  /***
-   * Resets the internal state of the buffering
-   */
-  virtual void clear();
-
-  // TODO: There should be a callback / flag set for errors
-};
-
-class cmConnection
-{
-public:
-  cmConnection() = default;
-
-  cmConnection(cmConnection const&) = delete;
-  cmConnection& operator=(cmConnection const&) = delete;
-
-  virtual void WriteData(const std::string& data) = 0;
-
-  virtual ~cmConnection();
-
-  virtual bool OnConnectionShuttingDown();
-
-  virtual bool IsOpen() const = 0;
-
-  virtual void SetServer(cmServerBase* s);
-
-  virtual void ProcessRequest(const std::string& request);
-
-  virtual bool OnServeStart(std::string* pString);
-
-protected:
-  cmServerBase* Server = nullptr;
-};
-
-/***
- * Abstraction of a connection; ties in event callbacks from libuv and notifies
- * the server when appropriate
- */
-class cmEventBasedConnection : public cmConnection
-{
-
-public:
-  /***
-   * @param bufferStrategy If no strategy is given, it will process the raw
-   * chunks as they come in. The connection
-   * owns the pointer given.
-   */
-  cmEventBasedConnection(cmConnectionBufferStrategy* bufferStrategy = nullptr);
-
-  virtual void Connect(uv_stream_t* server);
-
-  virtual void ReadData(const std::string& data);
-
-  bool IsOpen() const override;
-
-  void WriteData(const std::string& data) override;
-  bool OnConnectionShuttingDown() override;
-
-  virtual void OnDisconnect(int errorCode);
-
-  static void on_close(uv_handle_t* handle);
-
-  template <typename T>
-  static void on_close_delete(uv_handle_t* handle)
-  {
-    delete reinterpret_cast<T*>(handle);
-  }
-
-protected:
-  cm::uv_stream_ptr WriteStream;
-
-  std::string RawReadBuffer;
-
-  std::unique_ptr<cmConnectionBufferStrategy> BufferStrategy;
-
-  static void on_read(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf);
-
-  static void on_write(uv_write_t* req, int status);
-
-  static void on_new_connection(uv_stream_t* stream, int status);
-
-  static void on_alloc_buffer(uv_handle_t* handle, size_t suggested_size,
-                              uv_buf_t* buf);
-};
diff --git a/Source/cmCreateTestSourceList.cxx b/Source/cmCreateTestSourceList.cxx
index 9c4deea..9d492ba 100644
--- a/Source/cmCreateTestSourceList.cxx
+++ b/Source/cmCreateTestSourceList.cxx
@@ -127,7 +127,7 @@
   mf.AddDefinition("CMAKE_FORWARD_DECLARE_TESTS", forwardDeclareCode);
   mf.AddDefinition("CMAKE_FUNCTION_TABLE_ENTIRES", functionMapCode);
   bool res = true;
-  if (!mf.ConfigureFile(configFile, driver, false, true, false, true)) {
+  if (!mf.ConfigureFile(configFile, driver, false, true, false)) {
     res = false;
   }
 
diff --git a/Source/cmCustomCommandGenerator.cxx b/Source/cmCustomCommandGenerator.cxx
index 60504ba..08a0574 100644
--- a/Source/cmCustomCommandGenerator.cxx
+++ b/Source/cmCustomCommandGenerator.cxx
@@ -6,18 +6,22 @@
 #include <memory>
 #include <utility>
 
+#include <cm/optional>
 #include <cmext/algorithm>
 
+#include "cmCryptoHash.h"
 #include "cmCustomCommand.h"
 #include "cmCustomCommandLines.h"
 #include "cmGeneratorExpression.h"
 #include "cmGeneratorTarget.h"
+#include "cmGlobalGenerator.h"
 #include "cmLocalGenerator.h"
 #include "cmMakefile.h"
 #include "cmProperty.h"
 #include "cmStateTypes.h"
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
+#include "cmTransformDepfile.h"
 
 namespace {
 void AppendPaths(const std::vector<std::string>& inputs,
@@ -31,8 +35,7 @@
     for (std::string& it : result) {
       cmSystemTools::ConvertToUnixSlashes(it);
       if (cmSystemTools::FileIsFullPath(it)) {
-        it = cmSystemTools::CollapseFullPath(
-          it, lg->GetMakefile()->GetHomeOutputDirectory());
+        it = cmSystemTools::CollapseFullPath(it);
       }
     }
     cm::append(output, result);
@@ -42,8 +45,9 @@
 
 cmCustomCommandGenerator::cmCustomCommandGenerator(cmCustomCommand const& cc,
                                                    std::string config,
-                                                   cmLocalGenerator* lg)
-  : CC(cc)
+                                                   cmLocalGenerator* lg,
+                                                   bool transformDepfile)
+  : CC(&cc)
   , Config(std::move(config))
   , LG(lg)
   , OldStyle(cc.GetEscapeOldStyle())
@@ -52,34 +56,76 @@
 {
   cmGeneratorExpression ge(cc.GetBacktrace());
 
-  const cmCustomCommandLines& cmdlines = this->CC.GetCommandLines();
+  const cmCustomCommandLines& cmdlines = this->CC->GetCommandLines();
   for (cmCustomCommandLine const& cmdline : cmdlines) {
     cmCustomCommandLine argv;
     for (std::string const& clarg : cmdline) {
       std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(clarg);
       std::string parsed_arg = cge->Evaluate(this->LG, this->Config);
-      if (this->CC.GetCommandExpandLists()) {
+      for (cmGeneratorTarget* gt : cge->GetTargets()) {
+        this->Utilities.emplace(BT<std::pair<std::string, bool>>(
+          { gt->GetName(), true }, cge->GetBacktrace()));
+      }
+      if (this->CC->GetCommandExpandLists()) {
         cm::append(argv, cmExpandedList(parsed_arg));
       } else {
         argv.push_back(std::move(parsed_arg));
       }
     }
 
-    // Later code assumes at least one entry exists, but expanding
-    // lists on an empty command may have left this empty.
-    // FIXME: Should we define behavior for removing empty commands?
-    if (argv.empty()) {
+    if (!argv.empty()) {
+      // If the command references an executable target by name,
+      // collect the target to add a target-level dependency on it.
+      cmGeneratorTarget* gt = this->LG->FindGeneratorTargetToUse(argv.front());
+      if (gt && gt->GetType() == cmStateEnums::EXECUTABLE) {
+        this->Utilities.emplace(BT<std::pair<std::string, bool>>(
+          { gt->GetName(), true }, cc.GetBacktrace()));
+      }
+    } else {
+      // Later code assumes at least one entry exists, but expanding
+      // lists on an empty command may have left this empty.
+      // FIXME: Should we define behavior for removing empty commands?
       argv.emplace_back();
     }
 
     this->CommandLines.push_back(std::move(argv));
   }
 
+  if (transformDepfile && !this->CommandLines.empty() &&
+      !cc.GetDepfile().empty() &&
+      this->LG->GetGlobalGenerator()->DepfileFormat()) {
+    cmCustomCommandLine argv;
+    argv.push_back(cmSystemTools::GetCMakeCommand());
+    argv.emplace_back("-E");
+    argv.emplace_back("cmake_transform_depfile");
+    switch (*this->LG->GetGlobalGenerator()->DepfileFormat()) {
+      case cmDepfileFormat::GccDepfile:
+        argv.emplace_back("gccdepfile");
+        break;
+      case cmDepfileFormat::VsTlog:
+        argv.emplace_back("vstlog");
+        break;
+    }
+    if (this->LG->GetCurrentBinaryDirectory() ==
+        this->LG->GetBinaryDirectory()) {
+      argv.emplace_back("./");
+    } else {
+      argv.push_back(cmStrCat(this->LG->MaybeConvertToRelativePath(
+                                this->LG->GetBinaryDirectory(),
+                                this->LG->GetCurrentBinaryDirectory()),
+                              '/'));
+    }
+    argv.push_back(this->GetFullDepfile());
+    argv.push_back(this->GetInternalDepfile());
+
+    this->CommandLines.push_back(std::move(argv));
+  }
+
   AppendPaths(cc.GetByproducts(), ge, this->LG, this->Config,
               this->Byproducts);
   AppendPaths(cc.GetDepends(), ge, this->LG, this->Config, this->Depends);
 
-  const std::string& workingdirectory = this->CC.GetWorkingDirectory();
+  const std::string& workingdirectory = this->CC->GetWorkingDirectory();
   if (!workingdirectory.empty()) {
     std::unique_ptr<cmCompiledGeneratorExpression> cge =
       ge.Parse(workingdirectory);
@@ -97,7 +143,7 @@
 
 unsigned int cmCustomCommandGenerator::GetNumberOfCommands() const
 {
-  return static_cast<unsigned int>(this->CC.GetCommandLines().size());
+  return static_cast<unsigned int>(this->CommandLines.size());
 }
 
 void cmCustomCommandGenerator::FillEmulatorsWithArguments()
@@ -234,9 +280,43 @@
   }
 }
 
+std::string cmCustomCommandGenerator::GetFullDepfile() const
+{
+  std::string depfile = this->CC->GetDepfile();
+  if (depfile.empty()) {
+    return "";
+  }
+
+  if (!cmSystemTools::FileIsFullPath(depfile)) {
+    depfile = cmStrCat(this->LG->GetCurrentBinaryDirectory(), '/', depfile);
+  }
+  return cmSystemTools::CollapseFullPath(depfile);
+}
+
+std::string cmCustomCommandGenerator::GetInternalDepfile() const
+{
+  std::string depfile = this->GetFullDepfile();
+  if (depfile.empty()) {
+    return "";
+  }
+
+  cmCryptoHash hash(cmCryptoHash::AlgoSHA256);
+  std::string extension;
+  switch (*this->LG->GetGlobalGenerator()->DepfileFormat()) {
+    case cmDepfileFormat::GccDepfile:
+      extension = ".d";
+      break;
+    case cmDepfileFormat::VsTlog:
+      extension = ".tlog";
+      break;
+  }
+  return cmStrCat(this->LG->GetBinaryDirectory(), "/CMakeFiles/d/",
+                  hash.HashString(depfile), extension);
+}
+
 const char* cmCustomCommandGenerator::GetComment() const
 {
-  return this->CC.GetComment();
+  return this->CC->GetComment();
 }
 
 std::string cmCustomCommandGenerator::GetWorkingDirectory() const
@@ -246,7 +326,7 @@
 
 std::vector<std::string> const& cmCustomCommandGenerator::GetOutputs() const
 {
-  return this->CC.GetOutputs();
+  return this->CC->GetOutputs();
 }
 
 std::vector<std::string> const& cmCustomCommandGenerator::GetByproducts() const
@@ -258,3 +338,9 @@
 {
   return this->Depends;
 }
+
+std::set<BT<std::pair<std::string, bool>>> const&
+cmCustomCommandGenerator::GetUtilities() const
+{
+  return this->Utilities;
+}
diff --git a/Source/cmCustomCommandGenerator.h b/Source/cmCustomCommandGenerator.h
index 412eba8..cb0d7df 100644
--- a/Source/cmCustomCommandGenerator.h
+++ b/Source/cmCustomCommandGenerator.h
@@ -4,17 +4,20 @@
 
 #include "cmConfigure.h" // IWYU pragma: keep
 
+#include <set>
 #include <string>
+#include <utility>
 #include <vector>
 
 #include "cmCustomCommandLines.h"
+#include "cmListFileCache.h"
 
 class cmCustomCommand;
 class cmLocalGenerator;
 
 class cmCustomCommandGenerator
 {
-  cmCustomCommand const& CC;
+  cmCustomCommand const* CC;
   std::string Config;
   cmLocalGenerator* LG;
   bool OldStyle;
@@ -24,6 +27,7 @@
   std::vector<std::string> Byproducts;
   std::vector<std::string> Depends;
   std::string WorkingDirectory;
+  std::set<BT<std::pair<std::string, bool>>> Utilities;
 
   void FillEmulatorsWithArguments();
   std::vector<std::string> GetCrossCompilingEmulator(unsigned int c) const;
@@ -31,11 +35,13 @@
 
 public:
   cmCustomCommandGenerator(cmCustomCommand const& cc, std::string config,
-                           cmLocalGenerator* lg);
+                           cmLocalGenerator* lg, bool transformDepfile = true);
   cmCustomCommandGenerator(const cmCustomCommandGenerator&) = delete;
+  cmCustomCommandGenerator(cmCustomCommandGenerator&&) = default;
   cmCustomCommandGenerator& operator=(const cmCustomCommandGenerator&) =
     delete;
-  cmCustomCommand const& GetCC() const { return this->CC; }
+  cmCustomCommandGenerator& operator=(cmCustomCommandGenerator&&) = default;
+  cmCustomCommand const& GetCC() const { return *(this->CC); }
   unsigned int GetNumberOfCommands() const;
   std::string GetCommand(unsigned int c) const;
   void AppendArguments(unsigned int c, std::string& cmd) const;
@@ -44,5 +50,8 @@
   std::vector<std::string> const& GetOutputs() const;
   std::vector<std::string> const& GetByproducts() const;
   std::vector<std::string> const& GetDepends() const;
+  std::set<BT<std::pair<std::string, bool>>> const& GetUtilities() const;
   bool HasOnlyEmptyCommandLines() const;
+  std::string GetFullDepfile() const;
+  std::string GetInternalDepfile() const;
 };
diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx
index cbae4e5..a853bb1 100644
--- a/Source/cmExportFileGenerator.cxx
+++ b/Source/cmExportFileGenerator.cxx
@@ -924,13 +924,13 @@
 
   // Isolate the file policy level.
   // Support CMake versions as far back as 2.6 but also support using NEW
-  // policy settings for up to CMake 3.17 (this upper limit may be reviewed
+  // policy settings for up to CMake 3.18 (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.
   /* clang-format off */
   os << "cmake_policy(PUSH)\n"
-     << "cmake_policy(VERSION 2.6...3.17)\n";
+     << "cmake_policy(VERSION 2.6...3.18)\n";
   /* clang-format on */
 }
 
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index 8a3aad2..cd440ad 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -15,6 +15,7 @@
 #include <vector>
 
 #include <cm/memory>
+#include <cm/string_view>
 #include <cmext/algorithm>
 #include <cmext/string_view>
 
@@ -2314,49 +2315,92 @@
     status.SetError("Incorrect arguments to GENERATE subcommand.");
     return false;
   }
-  if (args[1] != "OUTPUT") {
+
+  struct Arguments
+  {
+    std::string Output;
+    std::string Input;
+    std::string Content;
+    std::string Condition;
+    std::string Target;
+  };
+
+  static auto const parser = cmArgumentParser<Arguments>{}
+                               .Bind("OUTPUT"_s, &Arguments::Output)
+                               .Bind("INPUT"_s, &Arguments::Input)
+                               .Bind("CONTENT"_s, &Arguments::Content)
+                               .Bind("CONDITION"_s, &Arguments::Condition)
+                               .Bind("TARGET"_s, &Arguments::Target);
+
+  std::vector<std::string> unparsedArguments;
+  std::vector<std::string> keywordsMissingValues;
+  std::vector<std::string> parsedKeywords;
+  Arguments const arguments =
+    parser.Parse(cmMakeRange(args).advance(1), &unparsedArguments,
+                 &keywordsMissingValues, &parsedKeywords);
+
+  if (!keywordsMissingValues.empty()) {
     status.SetError("Incorrect arguments to GENERATE subcommand.");
     return false;
   }
 
-  std::string condition;
-  std::string target;
-
-  for (std::size_t i = 5; i < args.size();) {
-    const std::string& arg = args[i++];
-
-    if (args.size() - i == 0) {
-      status.SetError("Incorrect arguments to GENERATE subcommand.");
-      return false;
-    }
-
-    const std::string& value = args[i++];
-
-    if (value.empty()) {
-      status.SetError(
-        arg + " of sub-command GENERATE must not be empty if specified.");
-      return false;
-    }
-
-    if (arg == "CONDITION") {
-      condition = value;
-    } else if (arg == "TARGET") {
-      target = value;
-    } else {
-      status.SetError("Unknown argument to GENERATE subcommand.");
-      return false;
-    }
+  if (!unparsedArguments.empty()) {
+    status.SetError("Unknown argument to GENERATE subcommand.");
+    return false;
   }
 
-  std::string output = args[2];
-  const bool inputIsContent = args[3] != "INPUT";
-  if (inputIsContent && args[3] != "CONTENT") {
+  bool mandatoryOptionsSpecified = false;
+  if (parsedKeywords.size() > 1) {
+    const bool outputOprionSpecified = parsedKeywords[0] == "OUTPUT"_s;
+    const bool inputOrContentSpecified =
+      parsedKeywords[1] == "INPUT"_s || parsedKeywords[1] == "CONTENT"_s;
+    if (outputOprionSpecified && inputOrContentSpecified) {
+      mandatoryOptionsSpecified = true;
+    }
+  }
+  if (!mandatoryOptionsSpecified) {
     status.SetError("Incorrect arguments to GENERATE subcommand.");
     return false;
   }
-  std::string input = args[4];
 
-  AddEvaluationFile(input, target, output, condition, inputIsContent, status);
+  const bool conditionOptionSpecified =
+    std::find(parsedKeywords.begin(), parsedKeywords.end(), "CONDITION"_s) !=
+    parsedKeywords.end();
+  if (conditionOptionSpecified && arguments.Condition.empty()) {
+    status.SetError("CONDITION of sub-command GENERATE must not be empty "
+                    "if specified.");
+    return false;
+  }
+
+  const bool targetOptionSpecified =
+    std::find(parsedKeywords.begin(), parsedKeywords.end(), "TARGET"_s) !=
+    parsedKeywords.end();
+  if (targetOptionSpecified && arguments.Target.empty()) {
+    status.SetError("TARGET of sub-command GENERATE must not be empty "
+                    "if specified.");
+    return false;
+  }
+
+  const bool outputOptionSpecified =
+    std::find(parsedKeywords.begin(), parsedKeywords.end(), "OUTPUT"_s) !=
+    parsedKeywords.end();
+  if (outputOptionSpecified && parsedKeywords[0] != "OUTPUT"_s) {
+    status.SetError("Incorrect arguments to GENERATE subcommand.");
+    return false;
+  }
+
+  const bool inputIsContent = parsedKeywords[1] != "INPUT"_s;
+  if (inputIsContent && parsedKeywords[1] != "CONTENT") {
+    status.SetError("Unknown argument to GENERATE subcommand.");
+  }
+
+  std::string input = arguments.Input;
+  if (inputIsContent) {
+    input = arguments.Content;
+  }
+
+  AddEvaluationFile(input, arguments.Target, arguments.Output,
+                    arguments.Condition, inputIsContent, status);
   return true;
 }
 
diff --git a/Source/cmFileMonitor.cxx b/Source/cmFileMonitor.cxx
deleted file mode 100644
index 8cfdb2d..0000000
--- a/Source/cmFileMonitor.cxx
+++ /dev/null
@@ -1,383 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
-   file Copyright.txt or https://cmake.org/licensing for details.  */
-#include "cmFileMonitor.h"
-
-#include <cassert>
-#include <cstddef>
-#include <unordered_map>
-#include <utility>
-
-#include <cm/memory>
-
-#include "cmsys/SystemTools.hxx"
-
-namespace {
-void on_directory_change(uv_fs_event_t* handle, const char* filename,
-                         int events, int status);
-void on_fs_close(uv_handle_t* handle);
-} // namespace
-
-class cmIBaseWatcher
-{
-public:
-  virtual ~cmIBaseWatcher() = default;
-
-  virtual void Trigger(const std::string& pathSegment, int events,
-                       int status) const = 0;
-  virtual std::string Path() const = 0;
-  virtual uv_loop_t* Loop() const = 0;
-
-  virtual void StartWatching() = 0;
-  virtual void StopWatching() = 0;
-
-  virtual std::vector<std::string> WatchedFiles() const = 0;
-  virtual std::vector<std::string> WatchedDirectories() const = 0;
-};
-
-class cmVirtualDirectoryWatcher : public cmIBaseWatcher
-{
-public:
-  ~cmVirtualDirectoryWatcher() override = default;
-
-  cmIBaseWatcher* Find(const std::string& ps)
-  {
-    const auto i = this->Children.find(ps);
-    return (i == this->Children.end()) ? nullptr : i->second.get();
-  }
-
-  void Trigger(const std::string& pathSegment, int events,
-               int status) const final
-  {
-    if (pathSegment.empty()) {
-      for (auto const& child : this->Children) {
-        child.second->Trigger(std::string(), events, status);
-      }
-    } else {
-      const auto i = this->Children.find(pathSegment);
-      if (i != this->Children.end()) {
-        i->second->Trigger(std::string(), events, status);
-      }
-    }
-  }
-
-  void StartWatching() override
-  {
-    for (auto const& child : this->Children) {
-      child.second->StartWatching();
-    }
-  }
-
-  void StopWatching() override
-  {
-    for (auto const& child : this->Children) {
-      child.second->StopWatching();
-    }
-  }
-
-  std::vector<std::string> WatchedFiles() const final
-  {
-    std::vector<std::string> result;
-    for (auto const& child : this->Children) {
-      for (std::string const& f : child.second->WatchedFiles()) {
-        result.push_back(f);
-      }
-    }
-    return result;
-  }
-
-  std::vector<std::string> WatchedDirectories() const override
-  {
-    std::vector<std::string> result;
-    for (auto const& child : this->Children) {
-      for (std::string const& dir : child.second->WatchedDirectories()) {
-        result.push_back(dir);
-      }
-    }
-    return result;
-  }
-
-  void Reset() { this->Children.clear(); }
-
-  void AddChildWatcher(const std::string& ps, cmIBaseWatcher* watcher)
-  {
-    assert(!ps.empty());
-    assert(this->Children.find(ps) == this->Children.end());
-    assert(watcher);
-
-    this->Children.emplace(ps, std::unique_ptr<cmIBaseWatcher>(watcher));
-  }
-
-private:
-  std::unordered_map<std::string, std::unique_ptr<cmIBaseWatcher>>
-    Children; // owned!
-};
-
-// Root of all the different (on windows!) root directories:
-class cmRootWatcher : public cmVirtualDirectoryWatcher
-{
-public:
-  cmRootWatcher(uv_loop_t* loop)
-    : mLoop(loop)
-  {
-    assert(loop);
-  }
-
-  std::string Path() const final
-  {
-    assert(false);
-    return std::string();
-  }
-  uv_loop_t* Loop() const final { return this->mLoop; }
-
-private:
-  uv_loop_t* const mLoop; // no ownership!
-};
-
-// Real directories:
-class cmRealDirectoryWatcher : public cmVirtualDirectoryWatcher
-{
-public:
-  cmRealDirectoryWatcher(cmVirtualDirectoryWatcher* p, const std::string& ps)
-    : Parent(p)
-    , PathSegment(ps)
-  {
-    assert(p);
-    assert(!ps.empty());
-
-    p->AddChildWatcher(ps, this);
-  }
-
-  void StartWatching() final
-  {
-    if (!this->Handle) {
-      this->Handle = new uv_fs_event_t;
-
-      uv_fs_event_init(this->Loop(), this->Handle);
-      this->Handle->data = this;
-      uv_fs_event_start(this->Handle, &on_directory_change, Path().c_str(), 0);
-    }
-    cmVirtualDirectoryWatcher::StartWatching();
-  }
-
-  void StopWatching() final
-  {
-    if (this->Handle) {
-      uv_fs_event_stop(this->Handle);
-      if (!uv_is_closing(reinterpret_cast<uv_handle_t*>(this->Handle))) {
-        uv_close(reinterpret_cast<uv_handle_t*>(this->Handle), &on_fs_close);
-      }
-      this->Handle = nullptr;
-    }
-    cmVirtualDirectoryWatcher::StopWatching();
-  }
-
-  uv_loop_t* Loop() const final { return this->Parent->Loop(); }
-
-  std::vector<std::string> WatchedDirectories() const override
-  {
-    std::vector<std::string> result = { Path() };
-    for (std::string const& dir :
-         cmVirtualDirectoryWatcher::WatchedDirectories()) {
-      result.push_back(dir);
-    }
-    return result;
-  }
-
-protected:
-  cmVirtualDirectoryWatcher* const Parent;
-  const std::string PathSegment;
-
-private:
-  uv_fs_event_t* Handle = nullptr; // owner!
-};
-
-// Root directories:
-class cmRootDirectoryWatcher : public cmRealDirectoryWatcher
-{
-public:
-  cmRootDirectoryWatcher(cmRootWatcher* p, const std::string& ps)
-    : cmRealDirectoryWatcher(p, ps)
-  {
-  }
-
-  std::string Path() const final { return this->PathSegment; }
-};
-
-// Normal directories below root:
-class cmDirectoryWatcher : public cmRealDirectoryWatcher
-{
-public:
-  cmDirectoryWatcher(cmRealDirectoryWatcher* p, const std::string& ps)
-    : cmRealDirectoryWatcher(p, ps)
-  {
-  }
-
-  std::string Path() const final
-  {
-    return this->Parent->Path() + this->PathSegment + "/";
-  }
-};
-
-class cmFileWatcher : public cmIBaseWatcher
-{
-public:
-  cmFileWatcher(cmRealDirectoryWatcher* p, const std::string& ps,
-                cmFileMonitor::Callback cb)
-    : Parent(p)
-    , PathSegment(ps)
-    , CbList({ std::move(cb) })
-  {
-    assert(p);
-    assert(!ps.empty());
-    p->AddChildWatcher(ps, this);
-  }
-
-  void StartWatching() final {}
-
-  void StopWatching() final {}
-
-  void AppendCallback(cmFileMonitor::Callback const& cb)
-  {
-    this->CbList.push_back(cb);
-  }
-
-  std::string Path() const final
-  {
-    return this->Parent->Path() + this->PathSegment;
-  }
-
-  std::vector<std::string> WatchedDirectories() const final { return {}; }
-
-  std::vector<std::string> WatchedFiles() const final
-  {
-    return { this->Path() };
-  }
-
-  void Trigger(const std::string& ps, int events, int status) const final
-  {
-    assert(ps.empty());
-    assert(status == 0);
-    static_cast<void>(ps);
-
-    const std::string path = this->Path();
-    for (cmFileMonitor::Callback const& cb : this->CbList) {
-      cb(path, events, status);
-    }
-  }
-
-  uv_loop_t* Loop() const final { return this->Parent->Loop(); }
-
-private:
-  cmRealDirectoryWatcher* Parent;
-  const std::string PathSegment;
-  std::vector<cmFileMonitor::Callback> CbList;
-};
-
-namespace {
-
-void on_directory_change(uv_fs_event_t* handle, const char* filename,
-                         int events, int status)
-{
-  const cmIBaseWatcher* const watcher =
-    static_cast<const cmIBaseWatcher*>(handle->data);
-  const std::string pathSegment(filename ? filename : "");
-  watcher->Trigger(pathSegment, events, status);
-}
-
-void on_fs_close(uv_handle_t* handle)
-{
-  delete reinterpret_cast<uv_fs_event_t*>(handle);
-}
-
-} // namespace
-
-cmFileMonitor::cmFileMonitor(uv_loop_t* l)
-  : Root(cm::make_unique<cmRootWatcher>(l))
-{
-}
-
-cmFileMonitor::~cmFileMonitor() = default;
-
-void cmFileMonitor::MonitorPaths(const std::vector<std::string>& paths,
-                                 Callback const& cb)
-{
-  for (std::string const& p : paths) {
-    std::vector<std::string> pathSegments;
-    cmsys::SystemTools::SplitPath(p, pathSegments, true);
-    const bool pathIsFile = !cmsys::SystemTools::FileIsDirectory(p);
-
-    const size_t segmentCount = pathSegments.size();
-    if (segmentCount < 2) { // Expect at least rootdir and filename
-      continue;
-    }
-    cmVirtualDirectoryWatcher* currentWatcher = this->Root.get();
-    for (size_t i = 0; i < segmentCount; ++i) {
-      assert(currentWatcher);
-
-      const bool fileSegment = (i == segmentCount - 1 && pathIsFile);
-      const bool rootSegment = (i == 0);
-      assert(
-        !(fileSegment &&
-          rootSegment)); // Can not be both filename and root part of the path!
-
-      const std::string& currentSegment = pathSegments[i];
-      if (currentSegment.empty()) {
-        continue;
-      }
-
-      cmIBaseWatcher* nextWatcher = currentWatcher->Find(currentSegment);
-      if (!nextWatcher) {
-        if (rootSegment) { // Root part
-          assert(currentWatcher == this->Root.get());
-          nextWatcher =
-            new cmRootDirectoryWatcher(this->Root.get(), currentSegment);
-          assert(currentWatcher->Find(currentSegment) == nextWatcher);
-        } else if (fileSegment) { // File part
-          assert(currentWatcher != this->Root.get());
-          nextWatcher = new cmFileWatcher(
-            dynamic_cast<cmRealDirectoryWatcher*>(currentWatcher),
-            currentSegment, cb);
-          assert(currentWatcher->Find(currentSegment) == nextWatcher);
-        } else { // Any normal directory in between
-          nextWatcher = new cmDirectoryWatcher(
-            dynamic_cast<cmRealDirectoryWatcher*>(currentWatcher),
-            currentSegment);
-          assert(currentWatcher->Find(currentSegment) == nextWatcher);
-        }
-      } else {
-        if (fileSegment) {
-          auto filePtr = dynamic_cast<cmFileWatcher*>(nextWatcher);
-          assert(filePtr);
-          filePtr->AppendCallback(cb);
-          continue;
-        }
-      }
-      currentWatcher = dynamic_cast<cmVirtualDirectoryWatcher*>(nextWatcher);
-    }
-  }
-  this->Root->StartWatching();
-}
-
-void cmFileMonitor::StopMonitoring()
-{
-  this->Root->StopWatching();
-  this->Root->Reset();
-}
-
-std::vector<std::string> cmFileMonitor::WatchedFiles() const
-{
-  std::vector<std::string> result;
-  if (this->Root) {
-    result = this->Root->WatchedFiles();
-  }
-  return result;
-}
-
-std::vector<std::string> cmFileMonitor::WatchedDirectories() const
-{
-  std::vector<std::string> result;
-  if (this->Root) {
-    result = this->Root->WatchedDirectories();
-  }
-  return result;
-}
diff --git a/Source/cmFileMonitor.h b/Source/cmFileMonitor.h
deleted file mode 100644
index fc75b0c..0000000
--- a/Source/cmFileMonitor.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
-   file Copyright.txt or https://cmake.org/licensing for details.  */
-#pragma once
-
-#include "cmConfigure.h" // IWYU pragma: keep
-
-#include <functional>
-#include <memory>
-#include <string>
-#include <vector>
-
-#include <cm3p/uv.h>
-
-class cmRootWatcher;
-
-class cmFileMonitor
-{
-
-public:
-  cmFileMonitor(uv_loop_t* l);
-  ~cmFileMonitor();
-
-  cmFileMonitor(cmFileMonitor const&) = delete;
-  cmFileMonitor& operator=(cmFileMonitor const&) = delete;
-
-  using Callback = std::function<void(const std::string&, int, int)>;
-  void MonitorPaths(const std::vector<std::string>& paths, Callback const& cb);
-  void StopMonitoring();
-
-  std::vector<std::string> WatchedFiles() const;
-  std::vector<std::string> WatchedDirectories() const;
-
-private:
-  std::unique_ptr<cmRootWatcher> Root;
-};
diff --git a/Source/cmFindCommon.cxx b/Source/cmFindCommon.cxx
index dee91d7..7952336 100644
--- a/Source/cmFindCommon.cxx
+++ b/Source/cmFindCommon.cxx
@@ -182,7 +182,7 @@
       { this->NoCMakeSystemPath, "CMAKE_FIND_USE_CMAKE_SYSTEM_PATH" } }
   };
 
-  for (auto& path : search_paths) {
+  for (auto const& path : search_paths) {
     cmProp def = this->Makefile->GetDefinition(path.second);
     if (def) {
       path.first = !cmIsOn(*def);
diff --git a/Source/cmFunctionCommand.cxx b/Source/cmFunctionCommand.cxx
index 71c82d6..1359009 100644
--- a/Source/cmFunctionCommand.cxx
+++ b/Source/cmFunctionCommand.cxx
@@ -163,8 +163,11 @@
   f.FilePath = this->GetStartingContext().FilePath;
   f.Line = this->GetStartingContext().Line;
   mf.RecordPolicies(f.Policies);
-  mf.GetState()->AddScriptedCommand(this->Args.front(), std::move(f));
-  return true;
+  return mf.GetState()->AddScriptedCommand(
+    this->Args.front(),
+    BT<cmState::Command>(std::move(f),
+                         mf.GetBacktrace().Push(this->GetStartingContext())),
+    mf);
 }
 
 } // anonymous namespace
diff --git a/Source/cmGccDepfileLexerHelper.cxx b/Source/cmGccDepfileLexerHelper.cxx
index 957896f..c782bcd 100644
--- a/Source/cmGccDepfileLexerHelper.cxx
+++ b/Source/cmGccDepfileLexerHelper.cxx
@@ -27,23 +27,30 @@
   if (!file) {
     return false;
   }
-  newEntry();
+  this->newEntry();
   yyscan_t scanner;
   cmGccDepfile_yylex_init(&scanner);
   cmGccDepfile_yyset_extra(this, scanner);
   cmGccDepfile_yyrestart(file, scanner);
   cmGccDepfile_yylex(scanner);
   cmGccDepfile_yylex_destroy(scanner);
-  sanitizeContent();
+  this->sanitizeContent();
   fclose(file);
-  return true;
+  return this->HelperState != State::Failed;
 }
 
 void cmGccDepfileLexerHelper::newEntry()
 {
+  if (this->HelperState == State::Rule && !this->Content.empty()) {
+    if (!this->Content.back().rules.empty() &&
+        !this->Content.back().rules.back().empty()) {
+      this->HelperState = State::Failed;
+    }
+    return;
+  }
   this->HelperState = State::Rule;
   this->Content.emplace_back();
-  newRule();
+  this->newRule();
 }
 
 void cmGccDepfileLexerHelper::newRule()
@@ -56,20 +63,22 @@
 
 void cmGccDepfileLexerHelper::newDependency()
 {
-  // printf("NEW DEP\n");
+  if (this->HelperState == State::Failed) {
+    return;
+  }
   this->HelperState = State::Dependency;
-  if (this->Content.back().paths.empty() ||
-      !this->Content.back().paths.back().empty()) {
-    this->Content.back().paths.emplace_back();
+  auto& entry = this->Content.back();
+  if (entry.paths.empty() || !entry.paths.back().empty()) {
+    entry.paths.emplace_back();
   }
 }
 
 void cmGccDepfileLexerHelper::newRuleOrDependency()
 {
   if (this->HelperState == State::Rule) {
-    newRule();
-  } else {
-    newDependency();
+    this->newRule();
+  } else if (this->HelperState == State::Dependency) {
+    this->newDependency();
   }
 }
 
@@ -93,6 +102,8 @@
       }
       dst = &dep->paths.back();
     } break;
+    case State::Failed:
+      return;
   }
   dst->append(s);
 }
diff --git a/Source/cmGccDepfileLexerHelper.h b/Source/cmGccDepfileLexerHelper.h
index 07ca61d..91132f5 100644
--- a/Source/cmGccDepfileLexerHelper.h
+++ b/Source/cmGccDepfileLexerHelper.h
@@ -29,7 +29,8 @@
   enum class State
   {
     Rule,
-    Dependency
+    Dependency,
+    Failed,
   };
   State HelperState = State::Rule;
 };
diff --git a/Source/cmGccDepfileReader.cxx b/Source/cmGccDepfileReader.cxx
index 9d70ede..eb3511a 100644
--- a/Source/cmGccDepfileReader.cxx
+++ b/Source/cmGccDepfileReader.cxx
@@ -5,14 +5,15 @@
 #include <type_traits>
 #include <utility>
 
+#include <cm/optional>
+
 #include "cmGccDepfileLexerHelper.h"
 
-cmGccDepfileContent cmReadGccDepfile(const char* filePath)
+cm::optional<cmGccDepfileContent> cmReadGccDepfile(const char* filePath)
 {
-  cmGccDepfileContent result;
   cmGccDepfileLexerHelper helper;
   if (helper.readFile(filePath)) {
-    result = std::move(helper).extractContent();
+    return cm::make_optional(std::move(helper).extractContent());
   }
-  return result;
+  return cm::nullopt;
 }
diff --git a/Source/cmGccDepfileReader.h b/Source/cmGccDepfileReader.h
index 395dd77..59ed7fd 100644
--- a/Source/cmGccDepfileReader.h
+++ b/Source/cmGccDepfileReader.h
@@ -2,6 +2,8 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #pragma once
 
+#include <cm/optional>
+
 #include "cmGccDepfileReaderTypes.h"
 
-cmGccDepfileContent cmReadGccDepfile(const char* filePath);
+cm::optional<cmGccDepfileContent> cmReadGccDepfile(const char* filePath);
diff --git a/Source/cmGeneratorExpressionEvaluator.h b/Source/cmGeneratorExpressionEvaluator.h
index 3e7737e..af2afd6 100644
--- a/Source/cmGeneratorExpressionEvaluator.h
+++ b/Source/cmGeneratorExpressionEvaluator.h
@@ -60,7 +60,7 @@
 
   void Extend(size_t length) { this->Length += length; }
 
-  size_t GetLength() { return this->Length; }
+  size_t GetLength() const { return this->Length; }
 
 private:
   const char* Content;
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index 4ca7405..e40316e 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -677,7 +677,7 @@
     }
     static cmsys::RegularExpression compilerIdValidator("^[A-Za-z0-9_]*$");
 
-    for (auto& param : parameters) {
+    for (auto const& param : parameters) {
 
       if (!compilerIdValidator.find(param)) {
         reportError(context, content->GetOriginalExpression(),
@@ -805,7 +805,7 @@
       return parameters.front().empty() ? "1" : "0";
     }
 
-    for (auto& param : parameters) {
+    for (auto const& param : parameters) {
       if (param == platformId) {
         return "1";
       }
@@ -901,7 +901,7 @@
       return std::string();
     }
     context->HadContextSensitiveCondition = true;
-    for (auto& param : parameters) {
+    for (auto const& param : parameters) {
       if (context->Config.empty()) {
         if (param.empty()) {
           return "1";
@@ -927,7 +927,7 @@
         if (cmProp mapValue = context->CurrentTarget->GetProperty(mapProp)) {
           cmExpandList(cmSystemTools::UpperCase(*mapValue), mappedConfigs);
 
-          for (auto& param : parameters) {
+          for (auto const& param : parameters) {
             if (cm::contains(mappedConfigs, cmSystemTools::UpperCase(param))) {
               return "1";
             }
@@ -995,7 +995,7 @@
       return context->Language;
     }
 
-    for (auto& param : parameters) {
+    for (auto const& param : parameters) {
       if (context->Language == param) {
         return "1";
       }
@@ -1101,7 +1101,7 @@
       return context->Language;
     }
 
-    for (auto& param : parameters) {
+    for (auto const& param : parameters) {
       if (context->Language == param) {
         return "1";
       }
@@ -1129,7 +1129,7 @@
     }
     static cmsys::RegularExpression linkerIdValidator("^[A-Za-z0-9_]*$");
 
-    for (auto& param : parameters) {
+    for (auto const& param : parameters) {
       if (!linkerIdValidator.find(param)) {
         reportError(context, content->GetOriginalExpression(),
                     "Expression syntax not recognized.");
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index e735897..4a79a3d 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -24,9 +24,7 @@
 
 #include "cmAlgorithms.h"
 #include "cmComputeLinkInformation.h"
-#include "cmCustomCommand.h"
 #include "cmCustomCommandGenerator.h"
-#include "cmCustomCommandLines.h"
 #include "cmFileTimes.h"
 #include "cmGeneratedFileStream.h"
 #include "cmGeneratorExpression.h"
@@ -254,7 +252,7 @@
 {
   EvaluatedTargetPropertyEntries out;
   out.Entries.reserve(in.size());
-  for (auto& entry : in) {
+  for (auto const& entry : in) {
     out.Entries.emplace_back(EvaluateTargetPropertyEntry(
       thisTarget, config, lang, dagChecker, *entry));
   }
@@ -332,7 +330,7 @@
 const std::string& cmGeneratorTarget::GetSourcesProperty() const
 {
   std::vector<std::string> values;
-  for (auto& se : this->SourceEntries) {
+  for (auto const& se : this->SourceEntries) {
     values.push_back(se->GetInput());
   }
   static std::string value;
@@ -992,9 +990,8 @@
 bool cmGeneratorTarget::GetLanguageStandardRequired(
   std::string const& lang) const
 {
-  cmProp p =
-    this->GetPropertyWithPairedLanguageSupport(lang, "_STANDARD_REQUIRED");
-  return cmIsOn(p);
+  return cmIsOn(
+    this->GetPropertyWithPairedLanguageSupport(lang, "_STANDARD_REQUIRED"));
 }
 
 void cmGeneratorTarget::GetModuleDefinitionSources(
@@ -1539,10 +1536,14 @@
     for (std::string& src : entry.Values) {
       cmSourceFile* sf = mf->GetOrCreateSource(src);
       std::string e;
-      std::string fullPath = sf->ResolveFullPath(&e);
+      std::string w;
+      std::string fullPath = sf->ResolveFullPath(&e, &w);
+      cmake* cm = tgt->GetLocalGenerator()->GetCMakeInstance();
+      if (!w.empty()) {
+        cm->IssueMessage(MessageType::AUTHOR_WARNING, w, tgt->GetBacktrace());
+      }
       if (fullPath.empty()) {
         if (!e.empty()) {
-          cmake* cm = tgt->GetLocalGenerator()->GetCMakeInstance();
           cm->IssueMessage(MessageType::FATAL_ERROR, e, tgt->GetBacktrace());
         }
         return contextDependent;
@@ -2500,7 +2501,7 @@
     }
   }
 
-  bool GetHadLinkLanguageSensitiveCondition()
+  bool GetHadLinkLanguageSensitiveCondition() const
   {
     return HadLinkLanguageSensitiveCondition;
   }
@@ -2888,9 +2889,6 @@
   bool IsUtility(std::string const& dep);
   void CheckCustomCommand(cmCustomCommand const& cc);
   void CheckCustomCommands(const std::vector<cmCustomCommand>& commands);
-  void FollowCommandDepends(cmCustomCommand const& cc,
-                            const std::string& config,
-                            std::set<std::string>& emitted);
 };
 
 cmTargetTraceDependencies::cmTargetTraceDependencies(cmGeneratorTarget* target)
@@ -2986,7 +2984,8 @@
   auto i = this->NameMap.lower_bound(name);
   if (i == this->NameMap.end() || i->first != name) {
     // Check if we know how to generate this file.
-    cmSourcesWithOutput sources = this->Makefile->GetSourcesWithOutput(name);
+    cmSourcesWithOutput sources =
+      this->LocalGenerator->GetSourcesWithOutput(name);
     // If we failed to find a target or source and we have a relative path, it
     // might be a valid source if made relative to the current binary
     // directory.
@@ -2996,7 +2995,7 @@
         cmStrCat(this->Makefile->GetCurrentBinaryDirectory(), '/', name);
       fullname = cmSystemTools::CollapseFullPath(
         fullname, this->Makefile->GetHomeOutputDirectory());
-      sources = this->Makefile->GetSourcesWithOutput(fullname);
+      sources = this->LocalGenerator->GetSourcesWithOutput(fullname);
     }
     i = this->NameMap.emplace_hint(i, name, sources);
   }
@@ -3076,71 +3075,27 @@
 
 void cmTargetTraceDependencies::CheckCustomCommand(cmCustomCommand const& cc)
 {
-  // Transform command names that reference targets built in this
-  // project to corresponding target-level dependencies.
-  cmGeneratorExpression ge(cc.GetBacktrace());
+  // Collect dependencies referenced by all configurations.
+  std::set<std::string> depends;
+  for (std::string const& config :
+       this->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig)) {
+    cmCustomCommandGenerator ccg(cc, config, this->LocalGenerator);
 
-  // Add target-level dependencies referenced by generator expressions.
-  std::set<cmGeneratorTarget*> targets;
-
-  for (cmCustomCommandLine const& cCmdLine : cc.GetCommandLines()) {
-    std::string const& command = cCmdLine.front();
-    // Check for a target with this name.
-    if (cmGeneratorTarget* t =
-          this->LocalGenerator->FindGeneratorTargetToUse(command)) {
-      if (t->GetType() == cmStateEnums::EXECUTABLE) {
-        // The command refers to an executable target built in
-        // this project.  Add the target-level dependency to make
-        // sure the executable is up to date before this custom
-        // command possibly runs.
-        this->GeneratorTarget->Target->AddUtility(command, true);
-      }
+    // Collect target-level dependencies referenced in command lines.
+    for (auto const& util : ccg.GetUtilities()) {
+      this->GeneratorTarget->Target->AddUtility(util);
     }
 
-    // Check for target references in generator expressions.
-    std::vector<std::string> const& configs =
-      this->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
-    for (std::string const& c : configs) {
-      for (std::string const& cl : cCmdLine) {
-        const std::unique_ptr<cmCompiledGeneratorExpression> cge =
-          ge.Parse(cl);
-        cge->SetQuiet(true);
-        cge->Evaluate(this->GeneratorTarget->GetLocalGenerator(), c);
-        std::set<cmGeneratorTarget*> geTargets = cge->GetTargets();
-        targets.insert(geTargets.begin(), geTargets.end());
-      }
-    }
+    // Collect file-level dependencies referenced in DEPENDS.
+    depends.insert(ccg.GetDepends().begin(), ccg.GetDepends().end());
   }
 
-  for (cmGeneratorTarget* target : targets) {
-    this->GeneratorTarget->Target->AddUtility(target->GetName(), true);
-  }
-
-  // Queue the custom command dependencies.
-  std::set<std::string> emitted;
-  std::vector<std::string> const& configs =
-    this->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
-  for (std::string const& conf : configs) {
-    this->FollowCommandDepends(cc, conf, emitted);
-  }
-}
-
-void cmTargetTraceDependencies::FollowCommandDepends(
-  cmCustomCommand const& cc, const std::string& config,
-  std::set<std::string>& emitted)
-{
-  cmCustomCommandGenerator ccg(cc, config,
-                               this->GeneratorTarget->LocalGenerator);
-
-  const std::vector<std::string>& depends = ccg.GetDepends();
-
+  // Queue file-level dependencies.
   for (std::string const& dep : depends) {
-    if (emitted.insert(dep).second) {
-      if (!this->IsUtility(dep)) {
-        // The dependency does not name a target and may be a file we
-        // know how to generate.  Queue it.
-        this->FollowName(dep);
-      }
+    if (!this->IsUtility(dep)) {
+      // The dependency does not name a target and may be a file we
+      // know how to generate.  Queue it.
+      this->FollowName(dep);
     }
   }
 }
diff --git a/Source/cmGetPropertyCommand.cxx b/Source/cmGetPropertyCommand.cxx
index 3a5b39d..e755399 100644
--- a/Source/cmGetPropertyCommand.cxx
+++ b/Source/cmGetPropertyCommand.cxx
@@ -280,8 +280,9 @@
 
   // Get the property.
   cmake* cm = status.GetMakefile().GetCMakeInstance();
-  cmProp p = cm->GetState()->GetGlobalProperty(propertyName);
-  return StoreResult(infoType, status.GetMakefile(), variable, cmToCStr(p));
+  return StoreResult(
+    infoType, status.GetMakefile(), variable,
+    cmToCStr(cm->GetState()->GetGlobalProperty(propertyName)));
 }
 
 bool HandleDirectoryMode(cmExecutionStatus& status, const std::string& name,
@@ -327,8 +328,8 @@
   }
 
   // Get the property.
-  cmProp p = mf->GetProperty(propertyName);
-  return StoreResult(infoType, status.GetMakefile(), variable, cmToCStr(p));
+  return StoreResult(infoType, status.GetMakefile(), variable,
+                     cmToCStr(mf->GetProperty(propertyName)));
 }
 
 bool HandleTargetMode(cmExecutionStatus& status, const std::string& name,
@@ -358,15 +359,14 @@
       }
       return StoreResult(infoType, status.GetMakefile(), variable, nullptr);
     }
-    cmProp prop_cstr = nullptr;
     cmListFileBacktrace bt = status.GetMakefile().GetBacktrace();
     cmMessenger* messenger = status.GetMakefile().GetMessenger();
-    prop_cstr = target->GetComputedProperty(propertyName, messenger, bt);
-    if (!prop_cstr) {
-      prop_cstr = target->GetProperty(propertyName);
+    cmProp prop = target->GetComputedProperty(propertyName, messenger, bt);
+    if (!prop) {
+      prop = target->GetProperty(propertyName);
     }
     return StoreResult(infoType, status.GetMakefile(), variable,
-                       prop_cstr ? prop_cstr->c_str() : nullptr);
+                       cmToCStr(prop));
   }
   status.SetError(cmStrCat("could not find TARGET ", name,
                            ".  Perhaps it has not yet been created."));
@@ -391,7 +391,7 @@
   if (cmSourceFile* sf =
         directory_makefile.GetOrCreateSource(source_file_absolute_path)) {
     return StoreResult(infoType, status.GetMakefile(), variable,
-                       sf->GetPropertyForUser(propertyName));
+                       cmToCStr(sf->GetPropertyForUser(propertyName)));
   }
   status.SetError(
     cmStrCat("given SOURCE name that could not be found or created: ",
diff --git a/Source/cmGetSourceFilePropertyCommand.cxx b/Source/cmGetSourceFilePropertyCommand.cxx
index 5395bc8..212a968 100644
--- a/Source/cmGetSourceFilePropertyCommand.cxx
+++ b/Source/cmGetSourceFilePropertyCommand.cxx
@@ -4,6 +4,7 @@
 
 #include "cmExecutionStatus.h"
 #include "cmMakefile.h"
+#include "cmProperty.h"
 #include "cmSetPropertyCommand.h"
 #include "cmSourceFile.h"
 
@@ -57,14 +58,14 @@
   }
 
   if (sf) {
-    const char* prop = nullptr;
+    cmProp prop = nullptr;
     if (!args[property_arg_index].empty()) {
       prop = sf->GetPropertyForUser(args[property_arg_index]);
     }
     if (prop) {
       // Set the value on the original Makefile scope, not the scope of the
       // requested directory.
-      status.GetMakefile().AddDefinition(var, prop);
+      status.GetMakefile().AddDefinition(var, *prop);
       return true;
     }
   }
diff --git a/Source/cmGhsMultiTargetGenerator.cxx b/Source/cmGhsMultiTargetGenerator.cxx
index a8f8f57..aabe43c 100644
--- a/Source/cmGhsMultiTargetGenerator.cxx
+++ b/Source/cmGhsMultiTargetGenerator.cxx
@@ -721,8 +721,7 @@
 
 bool cmGhsMultiTargetGenerator::DetermineIfIntegrityApp()
 {
-  cmProp p = this->GeneratorTarget->GetProperty("ghs_integrity_app");
-  if (p) {
+  if (cmProp p = this->GeneratorTarget->GetProperty("ghs_integrity_app")) {
     return cmIsOn(*p);
   }
   std::vector<cmSourceFile*> sources;
@@ -763,9 +762,9 @@
     /* set temporary mark; check if revisit*/
     if (temp.insert(si).second) {
       for (auto& di : si->GetCustomCommand()->GetDepends()) {
-        cmSourceFile const* sf = this->GeneratorTarget->GetLocalGenerator()
-                                   ->GetMakefile()
-                                   ->GetSourceFileWithOutput(di);
+        cmSourceFile const* sf =
+          this->GeneratorTarget->GetLocalGenerator()->GetSourceFileWithOutput(
+            di);
         /* if sf exists then visit */
         if (sf && this->VisitCustomCommand(temp, perm, order, sf)) {
           return true;
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index 1197db6..52f1d52 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -2601,7 +2601,7 @@
 }
 
 void cmGlobalGenerator::AddGlobalTarget_EditCache(
-  std::vector<GlobalTargetInfo>& targets)
+  std::vector<GlobalTargetInfo>& targets) const
 {
   const char* editCacheTargetName = this->GetEditCacheTargetName();
   if (!editCacheTargetName) {
@@ -2635,7 +2635,7 @@
 }
 
 void cmGlobalGenerator::AddGlobalTarget_RebuildCache(
-  std::vector<GlobalTargetInfo>& targets)
+  std::vector<GlobalTargetInfo>& targets) const
 {
   const char* rebuildCacheTargetName = this->GetRebuildCacheTargetName();
   if (!rebuildCacheTargetName) {
@@ -2758,7 +2758,7 @@
   }
 }
 
-std::string cmGlobalGenerator::GetPredefinedTargetsFolder()
+std::string cmGlobalGenerator::GetPredefinedTargetsFolder() const
 {
   cmProp prop = this->GetCMakeInstance()->GetState()->GetGlobalProperty(
     "PREDEFINED_TARGETS_FOLDER");
diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h
index b532a43..afafba9 100644
--- a/Source/cmGlobalGenerator.h
+++ b/Source/cmGlobalGenerator.h
@@ -14,6 +14,7 @@
 #include <utility>
 #include <vector>
 
+#include <cm/optional>
 #include <cmext/algorithm>
 
 #include "cm_codecvt.hxx"
@@ -26,6 +27,7 @@
 #include "cmSystemTools.h"
 #include "cmTarget.h"
 #include "cmTargetDepend.h"
+#include "cmTransformDepfile.h"
 
 #if !defined(CMAKE_BOOTSTRAP)
 #  include <cm3p/json/value.h>
@@ -452,6 +454,10 @@
   virtual bool ShouldStripResourcePath(cmMakefile*) const;
 
   virtual bool SupportsCustomCommandDepfile() const { return false; }
+  virtual cm::optional<cmDepfileFormat> DepfileFormat() const
+  {
+    return cm::nullopt;
+  }
 
   std::string GetSharedLibFlagsForLanguage(std::string const& lang) const;
 
@@ -568,8 +574,9 @@
   void AddGlobalTarget_Package(std::vector<GlobalTargetInfo>& targets);
   void AddGlobalTarget_PackageSource(std::vector<GlobalTargetInfo>& targets);
   void AddGlobalTarget_Test(std::vector<GlobalTargetInfo>& targets);
-  void AddGlobalTarget_EditCache(std::vector<GlobalTargetInfo>& targets);
-  void AddGlobalTarget_RebuildCache(std::vector<GlobalTargetInfo>& targets);
+  void AddGlobalTarget_EditCache(std::vector<GlobalTargetInfo>& targets) const;
+  void AddGlobalTarget_RebuildCache(
+    std::vector<GlobalTargetInfo>& targets) const;
   void AddGlobalTarget_Install(std::vector<GlobalTargetInfo>& targets);
   cmTarget CreateGlobalTarget(GlobalTargetInfo const& gti, cmMakefile* mf);
 
@@ -595,7 +602,7 @@
 
   cmGeneratorTarget* FindGeneratorTargetImpl(std::string const& name) const;
 
-  std::string GetPredefinedTargetsFolder();
+  std::string GetPredefinedTargetsFolder() const;
 
 private:
   using TargetMap = std::unordered_map<std::string, cmTarget*>;
diff --git a/Source/cmGlobalGhsMultiGenerator.cxx b/Source/cmGlobalGhsMultiGenerator.cxx
index c08c9cf..33bf830 100644
--- a/Source/cmGlobalGhsMultiGenerator.cxx
+++ b/Source/cmGlobalGhsMultiGenerator.cxx
@@ -704,7 +704,7 @@
   std::set<cmGeneratorTarget const*> temp;
   std::set<cmGeneratorTarget const*> perm;
 
-  for (auto ti : tgt) {
+  for (auto const ti : tgt) {
     bool r = VisitTarget(temp, perm, build, ti);
     if (r) {
       return r;
@@ -726,7 +726,7 @@
        * in the same order */
       OrderedTargetDependSet sortedTargets(this->GetTargetDirectDepends(ti),
                                            "");
-      for (auto& di : sortedTargets) {
+      for (auto const& di : sortedTargets) {
         if (this->VisitTarget(temp, perm, order, di)) {
           return true;
         }
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index cf45da9..7ef69f4 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -34,6 +34,7 @@
 #include "cmOutputConverter.h"
 #include "cmProperty.h"
 #include "cmRange.h"
+#include "cmScanDepFormat.h"
 #include "cmState.h"
 #include "cmStateDirectory.h"
 #include "cmStateSnapshot.h"
@@ -1064,7 +1065,7 @@
   }
 }
 
-void cmGlobalNinjaGenerator::WriteDisclaimer(std::ostream& os)
+void cmGlobalNinjaGenerator::WriteDisclaimer(std::ostream& os) const
 {
   os << "# CMAKE generated file: DO NOT EDIT!\n"
      << "# Generated by \"" << this->GetName() << "\""
@@ -1095,7 +1096,7 @@
 
 void cmGlobalNinjaGenerator::AppendTargetOutputs(
   cmGeneratorTarget const* target, cmNinjaDeps& outputs,
-  const std::string& config, cmNinjaTargetDepends depends)
+  const std::string& config, cmNinjaTargetDepends depends) const
 {
   // for frameworks, we want the real name, not smple name
   // frameworks always appear versioned, and the build.ninja
@@ -2024,6 +2025,8 @@
   cmStripSuffixIfExists(path, this->OutputPathPrefix);
 }
 
+#if !defined(CMAKE_BOOTSTRAP)
+
 /*
 
 We use the following approach to support Fortran.  Each target already
@@ -2103,16 +2106,6 @@
    (because the latter consumes the module).
 */
 
-struct cmSourceInfo
-{
-  // Set of provided and required modules.
-  std::set<std::string> Provides;
-  std::set<std::string> Requires;
-
-  // Set of files included in the translation unit.
-  std::set<std::string> Includes;
-};
-
 static std::unique_ptr<cmSourceInfo> cmcmd_cmake_ninja_depends_fortran(
   std::string const& arg_tdi, std::string const& arg_pp);
 
@@ -2120,6 +2113,7 @@
                               std::vector<std::string>::const_iterator argEnd)
 {
   std::string arg_tdi;
+  std::string arg_src;
   std::string arg_pp;
   std::string arg_dep;
   std::string arg_obj;
@@ -2128,6 +2122,8 @@
   for (std::string const& arg : cmMakeRange(argBeg, argEnd)) {
     if (cmHasLiteralPrefix(arg, "--tdi=")) {
       arg_tdi = arg.substr(6);
+    } else if (cmHasLiteralPrefix(arg, "--src=")) {
+      arg_src = arg.substr(6);
     } else if (cmHasLiteralPrefix(arg, "--pp=")) {
       arg_pp = arg.substr(5);
     } else if (cmHasLiteralPrefix(arg, "--dep=")) {
@@ -2168,6 +2164,9 @@
     cmSystemTools::Error("-E cmake_ninja_depends requires value for --lang=");
     return 1;
   }
+  if (arg_src.empty()) {
+    arg_src = cmStrCat("<", arg_obj, " input file>");
+  }
 
   std::unique_ptr<cmSourceInfo> info;
   if (arg_lang == "Fortran") {
@@ -2184,6 +2183,8 @@
     return 1;
   }
 
+  info->PrimaryOutput = arg_obj;
+
   {
     cmGeneratedFileStream depfile(arg_dep);
     depfile << cmSystemTools::ConvertToUnixOutputPath(arg_pp) << ":";
@@ -2193,24 +2194,7 @@
     depfile << "\n";
   }
 
-  Json::Value ddi(Json::objectValue);
-  ddi["object"] = arg_obj;
-
-  Json::Value& ddi_provides = ddi["provides"] = Json::arrayValue;
-  for (std::string const& provide : info->Provides) {
-    ddi_provides.append(provide);
-  }
-  Json::Value& ddi_requires = ddi["requires"] = Json::arrayValue;
-  for (std::string const& r : info->Requires) {
-    // Require modules not provided in the same source.
-    if (!info->Provides.count(r)) {
-      ddi_requires.append(r);
-    }
-  }
-
-  cmGeneratedFileStream ddif(arg_ddi);
-  ddif << ddi;
-  if (!ddif) {
+  if (!cmScanDepFormat_P1689_Write(arg_ddi, arg_src, *info)) {
     cmSystemTools::Error(
       cmStrCat("-E cmake_ninja_depends failed to write ", arg_ddi));
     return 1;
@@ -2268,19 +2252,28 @@
   }
 
   auto info = cm::make_unique<cmSourceInfo>();
-  info->Provides = finfo.Provides;
-  info->Requires = finfo.Requires;
-  info->Includes = finfo.Includes;
+  for (std::string const& provide : finfo.Provides) {
+    cmSourceReqInfo src_info;
+    src_info.LogicalName = provide;
+    src_info.CompiledModulePath = provide;
+    info->Provides.emplace_back(src_info);
+  }
+  for (std::string const& require : finfo.Requires) {
+    // Require modules not provided in the same source.
+    if (finfo.Provides.count(require)) {
+      continue;
+    }
+    cmSourceReqInfo src_info;
+    src_info.LogicalName = require;
+    src_info.CompiledModulePath = require;
+    info->Requires.emplace_back(src_info);
+  }
+  for (std::string const& include : finfo.Includes) {
+    info->Includes.push_back(include);
+  }
   return info;
 }
 
-struct cmDyndepObjectInfo
-{
-  std::string Object;
-  std::vector<std::string> Provides;
-  std::vector<std::string> Requires;
-};
-
 bool cmGlobalNinjaGenerator::WriteDyndepFile(
   std::string const& dir_top_src, std::string const& dir_top_bld,
   std::string const& dir_cur_src, std::string const& dir_cur_bld,
@@ -2302,34 +2295,14 @@
     this->LocalGenerators.push_back(std::move(lgd));
   }
 
-  std::vector<cmDyndepObjectInfo> objects;
+  std::vector<cmSourceInfo> objects;
   for (std::string const& arg_ddi : arg_ddis) {
-    // Load the ddi file and compute the module file paths it provides.
-    Json::Value ddio;
-    Json::Value const& ddi = ddio;
-    cmsys::ifstream ddif(arg_ddi.c_str(), std::ios::in | std::ios::binary);
-    Json::Reader reader;
-    if (!reader.parse(ddif, ddio, false)) {
-      cmSystemTools::Error(cmStrCat("-E cmake_ninja_dyndep failed to parse ",
-                                    arg_ddi,
-                                    reader.getFormattedErrorMessages()));
+    cmSourceInfo info;
+    if (!cmScanDepFormat_P1689_Parse(arg_ddi, &info)) {
+      cmSystemTools::Error(
+        cmStrCat("-E cmake_ninja_dyndep failed to parse ddi file ", arg_ddi));
       return false;
     }
-
-    cmDyndepObjectInfo info;
-    info.Object = ddi["object"].asString();
-    Json::Value const& ddi_provides = ddi["provides"];
-    if (ddi_provides.isArray()) {
-      for (auto const& ddi_provide : ddi_provides) {
-        info.Provides.push_back(ddi_provide.asString());
-      }
-    }
-    Json::Value const& ddi_requires = ddi["requires"];
-    if (ddi_requires.isArray()) {
-      for (auto const& ddi_require : ddi_requires) {
-        info.Requires.push_back(ddi_require.asString());
-      }
-    }
     objects.push_back(std::move(info));
   }
 
@@ -2360,11 +2333,12 @@
   // We do this after loading the modules provided by linked targets
   // in case we have one of the same name that must be preferred.
   Json::Value tm = Json::objectValue;
-  for (cmDyndepObjectInfo const& object : objects) {
-    for (std::string const& p : object.Provides) {
-      std::string const mod = cmStrCat(module_dir, p);
-      mod_files[p] = mod;
-      tm[p] = mod;
+  for (cmSourceInfo const& object : objects) {
+    for (auto const& p : object.Provides) {
+      std::string const mod = cmStrCat(
+        module_dir, cmSystemTools::GetFilenameName(p.CompiledModulePath));
+      mod_files[p.LogicalName] = mod;
+      tm[p.LogicalName] = mod;
     }
   }
 
@@ -2374,15 +2348,16 @@
   {
     cmNinjaBuild build("dyndep");
     build.Outputs.emplace_back("");
-    for (cmDyndepObjectInfo const& object : objects) {
-      build.Outputs[0] = object.Object;
+    for (cmSourceInfo const& object : objects) {
+      build.Outputs[0] = this->ConvertToNinjaPath(object.PrimaryOutput);
       build.ImplicitOuts.clear();
-      for (std::string const& p : object.Provides) {
-        build.ImplicitOuts.push_back(this->ConvertToNinjaPath(mod_files[p]));
+      for (auto const& p : object.Provides) {
+        build.ImplicitOuts.push_back(
+          this->ConvertToNinjaPath(mod_files[p.LogicalName]));
       }
       build.ImplicitDeps.clear();
-      for (std::string const& r : object.Requires) {
-        auto mit = mod_files.find(r);
+      for (auto const& r : object.Requires) {
+        auto mit = mod_files.find(r.LogicalName);
         if (mit != mod_files.end()) {
           build.ImplicitDeps.push_back(this->ConvertToNinjaPath(mit->second));
         }
@@ -2406,11 +2381,6 @@
   return true;
 }
 
-bool cmGlobalNinjaGenerator::EnableCrossConfigBuild() const
-{
-  return !this->CrossConfigs.empty();
-}
-
 int cmcmd_cmake_ninja_dyndep(std::vector<std::string>::const_iterator argBeg,
                              std::vector<std::string>::const_iterator argEnd)
 {
@@ -2492,6 +2462,13 @@
   return 0;
 }
 
+#endif
+
+bool cmGlobalNinjaGenerator::EnableCrossConfigBuild() const
+{
+  return !this->CrossConfigs.empty();
+}
+
 void cmGlobalNinjaGenerator::AppendDirectoryForConfig(
   const std::string& prefix, const std::string& config,
   const std::string& suffix, std::string& dir)
@@ -2659,30 +2636,17 @@
 
 bool cmGlobalNinjaMultiGenerator::InspectConfigTypeVariables()
 {
-  this->GetCMakeInstance()->MarkCliAsUsed("CMAKE_DEFAULT_BUILD_TYPE");
-  this->GetCMakeInstance()->MarkCliAsUsed("CMAKE_CROSS_CONFIGS");
-  this->GetCMakeInstance()->MarkCliAsUsed("CMAKE_DEFAULT_CONFIGS");
-  return this->ReadCacheEntriesForBuild(*this->Makefiles.front()->GetState());
-}
-
-std::string cmGlobalNinjaMultiGenerator::GetDefaultBuildConfig() const
-{
-  return "";
-}
-
-bool cmGlobalNinjaMultiGenerator::ReadCacheEntriesForBuild(
-  const cmState& state)
-{
   std::vector<std::string> configsVec;
-  cmExpandList(state.GetSafeCacheEntryValue("CMAKE_CONFIGURATION_TYPES"),
-               configsVec);
+  cmExpandList(
+    this->Makefiles.front()->GetSafeDefinition("CMAKE_CONFIGURATION_TYPES"),
+    configsVec);
   if (configsVec.empty()) {
     configsVec.emplace_back();
   }
   std::set<std::string> configs(configsVec.cbegin(), configsVec.cend());
 
   this->DefaultFileConfig =
-    state.GetSafeCacheEntryValue("CMAKE_DEFAULT_BUILD_TYPE");
+    this->Makefiles.front()->GetSafeDefinition("CMAKE_DEFAULT_BUILD_TYPE");
   if (this->DefaultFileConfig.empty()) {
     this->DefaultFileConfig = configsVec.front();
   }
@@ -2697,8 +2661,9 @@
   }
 
   std::vector<std::string> crossConfigsVec;
-  cmExpandList(state.GetSafeCacheEntryValue("CMAKE_CROSS_CONFIGS"),
-               crossConfigsVec);
+  cmExpandList(
+    this->Makefiles.front()->GetSafeDefinition("CMAKE_CROSS_CONFIGS"),
+    crossConfigsVec);
   auto crossConfigs = ListSubsetWithAll(configs, configs, crossConfigsVec);
   if (!crossConfigs) {
     std::ostringstream msg;
@@ -2711,7 +2676,7 @@
   this->CrossConfigs = *crossConfigs;
 
   auto defaultConfigsString =
-    state.GetSafeCacheEntryValue("CMAKE_DEFAULT_CONFIGS");
+    this->Makefiles.front()->GetSafeDefinition("CMAKE_DEFAULT_CONFIGS");
   if (defaultConfigsString.empty()) {
     defaultConfigsString = this->DefaultFileConfig;
   }
@@ -2745,6 +2710,11 @@
   return true;
 }
 
+std::string cmGlobalNinjaMultiGenerator::GetDefaultBuildConfig() const
+{
+  return "";
+}
+
 std::string cmGlobalNinjaMultiGenerator::OrderDependsTargetForTarget(
   cmGeneratorTarget const* target, const std::string& config) const
 {
diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h
index a0724ac..40d3cfc 100644
--- a/Source/cmGlobalNinjaGenerator.h
+++ b/Source/cmGlobalNinjaGenerator.h
@@ -24,6 +24,7 @@
 #include "cmNinjaTypes.h"
 #include "cmPolicies.h"
 #include "cmStringAlgorithms.h"
+#include "cmTransformDepfile.h"
 
 class cmCustomCommand;
 class cmGeneratorTarget;
@@ -31,7 +32,6 @@
 class cmLocalGenerator;
 class cmMakefile;
 class cmOutputConverter;
-class cmState;
 class cmStateDirectory;
 class cmake;
 struct cmDocumentationEntry;
@@ -211,6 +211,10 @@
   const char* GetCleanTargetName() const override { return "clean"; }
 
   bool SupportsCustomCommandDepfile() const override { return true; }
+  cm::optional<cmDepfileFormat> DepfileFormat() const override
+  {
+    return cmDepfileFormat::GccDepfile;
+  }
 
   virtual cmGeneratedFileStream* GetImplFileStream(
     const std::string& /*config*/) const
@@ -248,7 +252,7 @@
       : GG(gg)
     {
     }
-    std::string operator()(std::string const& path)
+    std::string operator()(std::string const& path) const
     {
       return this->GG->ConvertToNinjaPath(path);
     }
@@ -319,7 +323,7 @@
 
   void AppendTargetOutputs(cmGeneratorTarget const* target,
                            cmNinjaDeps& outputs, const std::string& config,
-                           cmNinjaTargetDepends depends);
+                           cmNinjaTargetDepends depends) const;
   void AppendTargetDepends(cmGeneratorTarget const* target,
                            cmNinjaDeps& outputs, const std::string& config,
                            const std::string& fileConfig,
@@ -459,7 +463,7 @@
   void CleanMetaData();
 
   /// Write the common disclaimer text at the top of each build file.
-  void WriteDisclaimer(std::ostream& os);
+  void WriteDisclaimer(std::ostream& os) const;
 
   void WriteAssumedSourceDependencies();
 
@@ -648,8 +652,6 @@
 
   std::string GetDefaultBuildConfig() const override;
 
-  bool ReadCacheEntriesForBuild(const cmState& state) override;
-
   bool SupportsDefaultBuildType() const override { return true; }
   bool SupportsCrossConfigs() const override { return true; }
   bool SupportsDefaultConfigs() const override { return true; }
diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx
index 2c934e1..9c3a533 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.cxx
+++ b/Source/cmGlobalUnixMakefileGenerator3.cxx
@@ -589,10 +589,16 @@
   }
   makeCommand.Add(this->SelectMakeProgram(makeProgram));
 
+  // Explicitly tell the make tool to use the Makefile written by
+  // cmLocalUnixMakefileGenerator3::WriteLocalMakefile
+  makeCommand.Add("-f");
+  makeCommand.Add("Makefile");
+
   if (jobs != cmake::NO_BUILD_PARALLEL_LEVEL) {
-    makeCommand.Add("-j");
-    if (jobs != cmake::DEFAULT_BUILD_PARALLEL_LEVEL) {
-      makeCommand.Add(std::to_string(jobs));
+    if (jobs == cmake::DEFAULT_BUILD_PARALLEL_LEVEL) {
+      makeCommand.Add("-j");
+    } else {
+      makeCommand.Add("-j" + std::to_string(jobs));
     }
   }
 
diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx
index 6267205..75cd714 100644
--- a/Source/cmGlobalVisualStudio7Generator.cxx
+++ b/Source/cmGlobalVisualStudio7Generator.cxx
@@ -380,9 +380,10 @@
       std::string project = target->GetName();
       std::string location = *expath;
 
-      cmProp p = target->GetProperty("VS_PROJECT_TYPE");
-      this->WriteExternalProject(fout, project, location, cmToCStr(p),
-                                 target->GetUtilities());
+      this->WriteExternalProject(
+        fout, project, location,
+        cmToCStr(target->GetProperty("VS_PROJECT_TYPE")),
+        target->GetUtilities());
       written = true;
     } else {
       cmProp vcprojName = target->GetProperty("GENERATOR_FILE_NAME");
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index b40d8ea..0d41b98 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -503,16 +503,15 @@
     }
   }
 
-  if (this->XcodeBuildSystem >= BuildSystem::Twelve) {
+  if ((this->XcodeBuildSystem >= BuildSystem::Twelve) ||
+      (jobs != cmake::NO_BUILD_PARALLEL_LEVEL)) {
     makeCommand.Add("-parallelizeTargets");
   }
   makeCommand.Add("-configuration", (config.empty() ? "Debug" : config));
 
-  if (jobs != cmake::NO_BUILD_PARALLEL_LEVEL) {
-    makeCommand.Add("-jobs");
-    if (jobs != cmake::DEFAULT_BUILD_PARALLEL_LEVEL) {
-      makeCommand.Add(std::to_string(jobs));
-    }
+  if ((jobs != cmake::NO_BUILD_PARALLEL_LEVEL) &&
+      (jobs != cmake::DEFAULT_BUILD_PARALLEL_LEVEL)) {
+    makeCommand.Add("-jobs", std::to_string(jobs));
   }
 
   if (this->XcodeVersion >= 70) {
diff --git a/Source/cmIncludeCommand.cxx b/Source/cmIncludeCommand.cxx
index ae801bb..5e3aec5 100644
--- a/Source/cmIncludeCommand.cxx
+++ b/Source/cmIncludeCommand.cxx
@@ -146,11 +146,24 @@
 
   std::string listFile = cmSystemTools::CollapseFullPath(
     fname, status.GetMakefile().GetCurrentSourceDirectory());
-  if (optional && !cmSystemTools::FileExists(listFile)) {
+
+  const bool fileDoesnotExist = !cmSystemTools::FileExists(listFile);
+  const bool fileIsDirectory = cmSystemTools::FileIsDirectory(listFile);
+  if (fileDoesnotExist || fileIsDirectory) {
     if (!resultVarName.empty()) {
       status.GetMakefile().AddDefinition(resultVarName, "NOTFOUND");
     }
-    return true;
+    if (optional) {
+      return true;
+    }
+    if (fileDoesnotExist) {
+      status.SetError(cmStrCat("could not find requested file:\n  ", fname));
+      return false;
+    }
+    if (fileIsDirectory) {
+      status.SetError(cmStrCat("requested file is a directory:\n  ", fname));
+      return false;
+    }
   }
 
   bool readit =
@@ -163,9 +176,7 @@
   }
 
   if (!optional && !readit && !cmSystemTools::GetFatalErrorOccured()) {
-    std::string m = cmStrCat("could not find load file:\n"
-                             "  ",
-                             fname);
+    std::string m = cmStrCat("could not load requested file:\n  ", fname);
     status.SetError(m);
     return false;
   }
diff --git a/Source/cmJsonObjectDictionary.h b/Source/cmJsonObjectDictionary.h
deleted file mode 100644
index 8a2b529..0000000
--- a/Source/cmJsonObjectDictionary.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
-   file Copyright.txt or https://cmake.org/licensing for details.  */
-#pragma once
-
-#include <string>
-
-// Vocabulary:
-
-static const std::string kARTIFACTS_KEY = "artifacts";
-static const std::string kBUILD_DIRECTORY_KEY = "buildDirectory";
-static const std::string kCOMPILE_FLAGS_KEY = "compileFlags";
-static const std::string kCONFIGURATIONS_KEY = "configurations";
-static const std::string kDEFINES_KEY = "defines";
-static const std::string kFILE_GROUPS_KEY = "fileGroups";
-static const std::string kFRAMEWORK_PATH_KEY = "frameworkPath";
-static const std::string kFULL_NAME_KEY = "fullName";
-static const std::string kINCLUDE_PATH_KEY = "includePath";
-static const std::string kIS_CMAKE_KEY = "isCMake";
-static const std::string kIS_GENERATED_KEY = "isGenerated";
-static const std::string kIS_SYSTEM_KEY = "isSystem";
-static const std::string kIS_TEMPORARY_KEY = "isTemporary";
-static const std::string kKEY_KEY = "key";
-static const std::string kLANGUAGE_KEY = "language";
-static const std::string kLINKER_LANGUAGE_KEY = "linkerLanguage";
-static const std::string kLINK_FLAGS_KEY = "linkFlags";
-static const std::string kLINK_LANGUAGE_FLAGS_KEY = "linkLanguageFlags";
-static const std::string kLINK_LIBRARIES_KEY = "linkLibraries";
-static const std::string kLINK_PATH_KEY = "linkPath";
-static const std::string kNAME_KEY = "name";
-static const std::string kPATH_KEY = "path";
-static const std::string kPROJECTS_KEY = "projects";
-static const std::string kPROPERTIES_KEY = "properties";
-static const std::string kSOURCE_DIRECTORY_KEY = "sourceDirectory";
-static const std::string kSOURCES_KEY = "sources";
-static const std::string kSYSROOT_KEY = "sysroot";
-static const std::string kTARGETS_KEY = "targets";
-static const std::string kTYPE_KEY = "type";
-static const std::string kVALUE_KEY = "value";
-static const std::string kHAS_INSTALL_RULE = "hasInstallRule";
-static const std::string kINSTALL_PATHS = "installPaths";
-static const std::string kCTEST_NAME = "ctestName";
-static const std::string kCTEST_COMMAND = "ctestCommand";
-static const std::string kCTEST_INFO = "ctestInfo";
-static const std::string kMINIMUM_CMAKE_VERSION = "minimumCMakeVersion";
-static const std::string kIS_GENERATOR_PROVIDED_KEY = "isGeneratorProvided";
diff --git a/Source/cmJsonObjects.cxx b/Source/cmJsonObjects.cxx
deleted file mode 100644
index 3a7ae0c..0000000
--- a/Source/cmJsonObjects.cxx
+++ /dev/null
@@ -1,692 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
-   file Copyright.txt or https://cmake.org/licensing for details.  */
-#include "cmJsonObjects.h" // IWYU pragma: keep
-
-#include <algorithm>
-#include <cassert>
-#include <cstddef>
-#include <functional>
-#include <limits>
-#include <map>
-#include <memory>
-#include <set>
-#include <string>
-#include <unordered_map>
-#include <utility>
-#include <vector>
-
-#include <cmext/algorithm>
-
-#include "cmGeneratorExpression.h"
-#include "cmGeneratorTarget.h"
-#include "cmGlobalGenerator.h"
-#include "cmInstallGenerator.h"
-#include "cmInstallSubdirectoryGenerator.h"
-#include "cmInstallTargetGenerator.h"
-#include "cmJsonObjectDictionary.h"
-#include "cmJsonObjects.h"
-#include "cmLinkLineComputer.h"
-#include "cmLocalGenerator.h"
-#include "cmMakefile.h"
-#include "cmProperty.h"
-#include "cmPropertyMap.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 "cmTest.h"
-#include "cmake.h"
-
-namespace {
-
-std::vector<std::string> getConfigurations(const cmake* cm)
-{
-  std::vector<std::string> configurations;
-  const auto& makefiles = cm->GetGlobalGenerator()->GetMakefiles();
-  if (makefiles.empty()) {
-    return configurations;
-  }
-
-  return makefiles[0]->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
-}
-
-bool hasString(const Json::Value& v, const std::string& s)
-{
-  return !v.isNull() &&
-    std::any_of(v.begin(), v.end(),
-                [s](const Json::Value& i) { return i.asString() == s; });
-}
-
-template <class T>
-Json::Value fromStringList(const T& in)
-{
-  Json::Value result = Json::arrayValue;
-  for (std::string const& i : in) {
-    result.append(i);
-  }
-  return result;
-}
-
-} // namespace
-
-void cmGetCMakeInputs(const cmGlobalGenerator* gg,
-                      const std::string& sourceDir,
-                      const std::string& buildDir,
-                      std::vector<std::string>* internalFiles,
-                      std::vector<std::string>* explicitFiles,
-                      std::vector<std::string>* tmpFiles)
-{
-  const std::string cmakeRootDir = cmSystemTools::GetCMakeRoot() + '/';
-  auto const& makefiles = gg->GetMakefiles();
-  for (const auto& mf : makefiles) {
-    for (std::string const& lf : mf->GetListFiles()) {
-
-      const std::string startOfFile = lf.substr(0, cmakeRootDir.size());
-      const bool isInternal = (startOfFile == cmakeRootDir);
-      const bool isTemporary =
-        !isInternal && (cmHasPrefix(lf, buildDir + '/'));
-
-      std::string toAdd = lf;
-      if (!sourceDir.empty()) {
-        const std::string& relative =
-          cmSystemTools::RelativePath(sourceDir, lf);
-        if (toAdd.size() > relative.size()) {
-          toAdd = relative;
-        }
-      }
-
-      if (isInternal) {
-        if (internalFiles) {
-          internalFiles->push_back(std::move(toAdd));
-        }
-      } else {
-        if (isTemporary) {
-          if (tmpFiles) {
-            tmpFiles->push_back(std::move(toAdd));
-          }
-        } else {
-          if (explicitFiles) {
-            explicitFiles->push_back(std::move(toAdd));
-          }
-        }
-      }
-    }
-  }
-}
-
-Json::Value cmDumpCMakeInputs(const cmake* cm)
-{
-  const cmGlobalGenerator* gg = cm->GetGlobalGenerator();
-  const std::string& buildDir = cm->GetHomeOutputDirectory();
-  const std::string& sourceDir = cm->GetHomeDirectory();
-
-  std::vector<std::string> internalFiles;
-  std::vector<std::string> explicitFiles;
-  std::vector<std::string> tmpFiles;
-  cmGetCMakeInputs(gg, sourceDir, buildDir, &internalFiles, &explicitFiles,
-                   &tmpFiles);
-
-  Json::Value array = Json::arrayValue;
-
-  Json::Value tmp = Json::objectValue;
-  tmp[kIS_CMAKE_KEY] = true;
-  tmp[kIS_TEMPORARY_KEY] = false;
-  tmp[kSOURCES_KEY] = fromStringList(internalFiles);
-  array.append(tmp);
-
-  tmp = Json::objectValue;
-  tmp[kIS_CMAKE_KEY] = false;
-  tmp[kIS_TEMPORARY_KEY] = false;
-  tmp[kSOURCES_KEY] = fromStringList(explicitFiles);
-  array.append(tmp);
-
-  tmp = Json::objectValue;
-  tmp[kIS_CMAKE_KEY] = false;
-  tmp[kIS_TEMPORARY_KEY] = true;
-  tmp[kSOURCES_KEY] = fromStringList(tmpFiles);
-  array.append(tmp);
-
-  return array;
-}
-
-class LanguageData
-{
-public:
-  bool operator==(const LanguageData& other) const;
-
-  void SetDefines(const std::set<std::string>& defines);
-
-  bool IsGenerated = false;
-  std::string Language;
-  std::string Flags;
-  std::vector<std::string> Defines;
-  std::vector<std::pair<std::string, bool>> IncludePathList;
-};
-
-bool LanguageData::operator==(const LanguageData& other) const
-{
-  return Language == other.Language && Defines == other.Defines &&
-    Flags == other.Flags && IncludePathList == other.IncludePathList &&
-    IsGenerated == other.IsGenerated;
-}
-
-void LanguageData::SetDefines(const std::set<std::string>& defines)
-{
-  std::vector<std::string> result;
-  result.reserve(defines.size());
-  for (std::string const& i : defines) {
-    result.push_back(i);
-  }
-  std::sort(result.begin(), result.end());
-  Defines = std::move(result);
-}
-
-namespace std {
-
-template <>
-struct hash<LanguageData>
-{
-  std::size_t operator()(const LanguageData& in) const
-  {
-    using std::hash;
-    size_t result =
-      hash<std::string>()(in.Language) ^ hash<std::string>()(in.Flags);
-    for (auto const& i : in.IncludePathList) {
-      result = result ^
-        (hash<std::string>()(i.first) ^
-         (i.second ? std::numeric_limits<size_t>::max() : 0));
-    }
-    for (auto const& i : in.Defines) {
-      result = result ^ hash<std::string>()(i);
-    }
-    result =
-      result ^ (in.IsGenerated ? std::numeric_limits<size_t>::max() : 0);
-    return result;
-  }
-};
-
-} // namespace std
-
-static Json::Value DumpSourceFileGroup(const LanguageData& data,
-                                       const std::vector<std::string>& files,
-                                       const std::string& baseDir)
-{
-  Json::Value result = Json::objectValue;
-
-  if (!data.Language.empty()) {
-    result[kLANGUAGE_KEY] = data.Language;
-    if (!data.Flags.empty()) {
-      result[kCOMPILE_FLAGS_KEY] = data.Flags;
-    }
-    if (!data.IncludePathList.empty()) {
-      Json::Value includes = Json::arrayValue;
-      for (auto const& i : data.IncludePathList) {
-        Json::Value tmp = Json::objectValue;
-        tmp[kPATH_KEY] = i.first;
-        if (i.second) {
-          tmp[kIS_SYSTEM_KEY] = i.second;
-        }
-        includes.append(tmp);
-      }
-      result[kINCLUDE_PATH_KEY] = includes;
-    }
-    if (!data.Defines.empty()) {
-      result[kDEFINES_KEY] = fromStringList(data.Defines);
-    }
-  }
-
-  result[kIS_GENERATED_KEY] = data.IsGenerated;
-
-  Json::Value sourcesValue = Json::arrayValue;
-  for (auto const& i : files) {
-    const std::string relPath = cmSystemTools::RelativePath(baseDir, i);
-    sourcesValue.append(relPath.size() < i.size() ? relPath : i);
-  }
-
-  result[kSOURCES_KEY] = sourcesValue;
-  return result;
-}
-
-static Json::Value DumpSourceFilesList(
-  cmGeneratorTarget* target, const std::string& config,
-  const std::map<std::string, LanguageData>& languageDataMap)
-{
-  // Collect sourcefile groups:
-
-  std::vector<cmSourceFile*> files;
-  target->GetSourceFiles(files, config);
-
-  std::unordered_map<LanguageData, std::vector<std::string>> fileGroups;
-  for (cmSourceFile* file : files) {
-    LanguageData fileData;
-    fileData.Language = file->GetOrDetermineLanguage();
-    if (!fileData.Language.empty()) {
-      const LanguageData& ld = languageDataMap.at(fileData.Language);
-      cmLocalGenerator* lg = target->GetLocalGenerator();
-      cmGeneratorExpressionInterpreter genexInterpreter(lg, config, target,
-                                                        fileData.Language);
-
-      std::string compileFlags = ld.Flags;
-      const std::string COMPILE_FLAGS("COMPILE_FLAGS");
-      if (cmProp cflags = file->GetProperty(COMPILE_FLAGS)) {
-        lg->AppendFlags(compileFlags,
-                        genexInterpreter.Evaluate(*cflags, COMPILE_FLAGS));
-      }
-      const std::string COMPILE_OPTIONS("COMPILE_OPTIONS");
-      if (cmProp coptions = file->GetProperty(COMPILE_OPTIONS)) {
-        lg->AppendCompileOptions(
-          compileFlags, genexInterpreter.Evaluate(*coptions, COMPILE_OPTIONS));
-      }
-      fileData.Flags = compileFlags;
-
-      // Add include directories from source file properties.
-      std::vector<std::string> includes;
-
-      const std::string INCLUDE_DIRECTORIES("INCLUDE_DIRECTORIES");
-      if (cmProp cincludes = file->GetProperty(INCLUDE_DIRECTORIES)) {
-        const std::string& evaluatedIncludes =
-          genexInterpreter.Evaluate(*cincludes, INCLUDE_DIRECTORIES);
-        lg->AppendIncludeDirectories(includes, evaluatedIncludes, *file);
-
-        for (const auto& include : includes) {
-          fileData.IncludePathList.emplace_back(
-            include,
-            target->IsSystemIncludeDirectory(include, config,
-                                             fileData.Language));
-        }
-      }
-
-      fileData.IncludePathList.insert(fileData.IncludePathList.end(),
-                                      ld.IncludePathList.begin(),
-                                      ld.IncludePathList.end());
-
-      const std::string COMPILE_DEFINITIONS("COMPILE_DEFINITIONS");
-      std::set<std::string> defines;
-      if (cmProp defs = file->GetProperty(COMPILE_DEFINITIONS)) {
-        lg->AppendDefines(
-          defines, genexInterpreter.Evaluate(*defs, COMPILE_DEFINITIONS));
-      }
-
-      const std::string defPropName =
-        "COMPILE_DEFINITIONS_" + cmSystemTools::UpperCase(config);
-      if (cmProp config_defs = file->GetProperty(defPropName)) {
-        lg->AppendDefines(
-          defines,
-          genexInterpreter.Evaluate(*config_defs, COMPILE_DEFINITIONS));
-      }
-
-      defines.insert(ld.Defines.begin(), ld.Defines.end());
-
-      fileData.SetDefines(defines);
-    }
-
-    fileData.IsGenerated = file->GetIsGenerated();
-    std::vector<std::string>& groupFileList = fileGroups[fileData];
-    groupFileList.push_back(file->ResolveFullPath());
-  }
-
-  const std::string& baseDir = target->Makefile->GetCurrentSourceDirectory();
-  Json::Value result = Json::arrayValue;
-  for (auto const& it : fileGroups) {
-    Json::Value group = DumpSourceFileGroup(it.first, it.second, baseDir);
-    if (!group.isNull()) {
-      result.append(group);
-    }
-  }
-
-  return result;
-}
-
-static Json::Value DumpCTestInfo(cmLocalGenerator* lg, cmTest* testInfo,
-                                 const std::string& config)
-{
-  Json::Value result = Json::objectValue;
-  result[kCTEST_NAME] = testInfo->GetName();
-
-  // Concat command entries together. After the first should be the arguments
-  // for the command
-  std::string command;
-  for (auto const& cmd : testInfo->GetCommand()) {
-    command.append(cmd);
-    command.append(" ");
-  }
-
-  // Remove any config specific variables from the output.
-  result[kCTEST_COMMAND] =
-    cmGeneratorExpression::Evaluate(command, lg, config);
-
-  // Build up the list of properties that may have been specified
-  Json::Value properties = Json::arrayValue;
-  for (auto& prop : testInfo->GetProperties().GetList()) {
-    Json::Value entry = Json::objectValue;
-    entry[kKEY_KEY] = prop.first;
-
-    // Remove config variables from the value too.
-    entry[kVALUE_KEY] =
-      cmGeneratorExpression::Evaluate(prop.second, lg, config);
-    properties.append(entry);
-  }
-  result[kPROPERTIES_KEY] = properties;
-
-  return result;
-}
-
-static void DumpMakefileTests(cmLocalGenerator* lg, const std::string& config,
-                              Json::Value* result)
-{
-  auto mf = lg->GetMakefile();
-  std::vector<cmTest*> tests;
-  mf->GetTests(config, tests);
-  for (auto test : tests) {
-    Json::Value tmp = DumpCTestInfo(lg, test, config);
-    if (!tmp.isNull()) {
-      result->append(tmp);
-    }
-  }
-}
-
-static Json::Value DumpCTestProjectList(const cmake* cm,
-                                        std::string const& config)
-{
-  Json::Value result = Json::arrayValue;
-
-  auto globalGen = cm->GetGlobalGenerator();
-
-  for (const auto& projectIt : globalGen->GetProjectMap()) {
-    Json::Value pObj = Json::objectValue;
-    pObj[kNAME_KEY] = projectIt.first;
-
-    Json::Value tests = Json::arrayValue;
-
-    // Gather tests for every generator
-    for (const auto& lg : projectIt.second) {
-      // Make sure they're generated.
-      lg->GenerateTestFiles();
-      DumpMakefileTests(lg, config, &tests);
-    }
-
-    pObj[kCTEST_INFO] = tests;
-
-    result.append(pObj);
-  }
-
-  return result;
-}
-
-static Json::Value DumpCTestConfiguration(const cmake* cm,
-                                          const std::string& config)
-{
-  Json::Value result = Json::objectValue;
-  result[kNAME_KEY] = config;
-
-  result[kPROJECTS_KEY] = DumpCTestProjectList(cm, config);
-
-  return result;
-}
-
-static Json::Value DumpCTestConfigurationsList(const cmake* cm)
-{
-  Json::Value result = Json::arrayValue;
-
-  for (const std::string& c : getConfigurations(cm)) {
-    result.append(DumpCTestConfiguration(cm, c));
-  }
-
-  return result;
-}
-
-Json::Value cmDumpCTestInfo(const cmake* cm)
-{
-  Json::Value result = Json::objectValue;
-  result[kCONFIGURATIONS_KEY] = DumpCTestConfigurationsList(cm);
-  return result;
-}
-
-static Json::Value DumpTarget(cmGeneratorTarget* target,
-                              const std::string& config)
-{
-  cmLocalGenerator* lg = target->GetLocalGenerator();
-
-  const cmStateEnums::TargetType type = target->GetType();
-  const std::string typeName = cmState::GetTargetTypeName(type);
-
-  Json::Value ttl = Json::arrayValue;
-  ttl.append("EXECUTABLE");
-  ttl.append("STATIC_LIBRARY");
-  ttl.append("SHARED_LIBRARY");
-  ttl.append("MODULE_LIBRARY");
-  ttl.append("OBJECT_LIBRARY");
-  ttl.append("UTILITY");
-  ttl.append("INTERFACE_LIBRARY");
-
-  if (!hasString(ttl, typeName) || target->IsImported()) {
-    return Json::Value();
-  }
-
-  Json::Value result = Json::objectValue;
-  result[kNAME_KEY] = target->GetName();
-  result[kIS_GENERATOR_PROVIDED_KEY] =
-    target->Target->GetIsGeneratorProvided();
-  result[kTYPE_KEY] = typeName;
-  result[kSOURCE_DIRECTORY_KEY] = lg->GetCurrentSourceDirectory();
-  result[kBUILD_DIRECTORY_KEY] = lg->GetCurrentBinaryDirectory();
-
-  if (type == cmStateEnums::INTERFACE_LIBRARY) {
-    return result;
-  }
-
-  result[kFULL_NAME_KEY] = target->GetFullName(config);
-
-  if (target->Target->GetHaveInstallRule()) {
-    result[kHAS_INSTALL_RULE] = true;
-
-    Json::Value installPaths = Json::arrayValue;
-    for (const auto& installGenerator :
-         target->Makefile->GetInstallGenerators()) {
-      auto installTargetGenerator =
-        dynamic_cast<cmInstallTargetGenerator*>(installGenerator.get());
-      if (installTargetGenerator != nullptr &&
-          installTargetGenerator->GetTarget()->Target == target->Target) {
-        auto dest = installTargetGenerator->GetDestination(config);
-
-        std::string installPath;
-        if (!dest.empty() && cmSystemTools::FileIsFullPath(dest)) {
-          installPath = dest;
-        } else {
-          installPath = cmStrCat(
-            target->Makefile->GetSafeDefinition("CMAKE_INSTALL_PREFIX"), '/',
-            dest);
-        }
-
-        installPaths.append(installPath);
-      }
-    }
-
-    result[kINSTALL_PATHS] = installPaths;
-  }
-
-  if (target->HaveWellDefinedOutputFiles()) {
-    Json::Value artifacts = Json::arrayValue;
-    artifacts.append(
-      target->GetFullPath(config, cmStateEnums::RuntimeBinaryArtifact));
-    if (target->HasImportLibrary(config)) {
-      artifacts.append(
-        target->GetFullPath(config, cmStateEnums::ImportLibraryArtifact));
-    }
-    if (target->IsDLLPlatform()) {
-      const cmGeneratorTarget::OutputInfo* output =
-        target->GetOutputInfo(config);
-      if (output && !output->PdbDir.empty()) {
-        artifacts.append(output->PdbDir + '/' + target->GetPDBName(config));
-      }
-    }
-    result[kARTIFACTS_KEY] = artifacts;
-
-    result[kLINKER_LANGUAGE_KEY] = target->GetLinkerLanguage(config);
-
-    std::string linkLibs;
-    std::string linkFlags;
-    std::string linkLanguageFlags;
-    std::string frameworkPath;
-    std::string linkPath;
-    cmLinkLineComputer linkLineComputer(lg,
-                                        lg->GetStateSnapshot().GetDirectory());
-    lg->GetTargetFlags(&linkLineComputer, config, linkLibs, linkLanguageFlags,
-                       linkFlags, frameworkPath, linkPath, target);
-
-    linkLibs = cmTrimWhitespace(linkLibs);
-    linkFlags = cmTrimWhitespace(linkFlags);
-    linkLanguageFlags = cmTrimWhitespace(linkLanguageFlags);
-    frameworkPath = cmTrimWhitespace(frameworkPath);
-    linkPath = cmTrimWhitespace(linkPath);
-
-    if (!cmTrimWhitespace(linkLibs).empty()) {
-      result[kLINK_LIBRARIES_KEY] = linkLibs;
-    }
-    if (!cmTrimWhitespace(linkFlags).empty()) {
-      result[kLINK_FLAGS_KEY] = linkFlags;
-    }
-    if (!cmTrimWhitespace(linkLanguageFlags).empty()) {
-      result[kLINK_LANGUAGE_FLAGS_KEY] = linkLanguageFlags;
-    }
-    if (!frameworkPath.empty()) {
-      result[kFRAMEWORK_PATH_KEY] = frameworkPath;
-    }
-    if (!linkPath.empty()) {
-      result[kLINK_PATH_KEY] = linkPath;
-    }
-    const std::string sysroot =
-      lg->GetMakefile()->GetSafeDefinition("CMAKE_SYSROOT");
-    if (!sysroot.empty()) {
-      result[kSYSROOT_KEY] = sysroot;
-    }
-  }
-
-  std::set<std::string> languages;
-  target->GetLanguages(languages, config);
-  std::map<std::string, LanguageData> languageDataMap;
-
-  for (std::string const& lang : languages) {
-    LanguageData& ld = languageDataMap[lang];
-    ld.Language = lang;
-    lg->GetTargetCompileFlags(target, config, lang, ld.Flags);
-    std::set<std::string> defines;
-    lg->GetTargetDefines(target, config, lang, defines);
-    ld.SetDefines(defines);
-    std::vector<std::string> includePathList;
-    lg->GetIncludeDirectories(includePathList, target, lang, config);
-    for (std::string const& i : includePathList) {
-      ld.IncludePathList.emplace_back(
-        i, target->IsSystemIncludeDirectory(i, config, lang));
-    }
-  }
-
-  Json::Value sourceGroupsValue =
-    DumpSourceFilesList(target, config, languageDataMap);
-  if (!sourceGroupsValue.empty()) {
-    result[kFILE_GROUPS_KEY] = sourceGroupsValue;
-  }
-
-  return result;
-}
-
-static Json::Value DumpTargetsList(
-  const std::vector<cmLocalGenerator*>& generators, const std::string& config)
-{
-  Json::Value result = Json::arrayValue;
-
-  std::vector<cmGeneratorTarget*> targetList;
-  for (auto const& lgIt : generators) {
-    cm::append(targetList, lgIt->GetGeneratorTargets());
-  }
-  std::sort(targetList.begin(), targetList.end());
-
-  for (cmGeneratorTarget* target : targetList) {
-    Json::Value tmp = DumpTarget(target, config);
-    if (!tmp.isNull()) {
-      result.append(tmp);
-    }
-  }
-
-  return result;
-}
-
-static Json::Value DumpProjectList(const cmake* cm, std::string const& config)
-{
-  Json::Value result = Json::arrayValue;
-
-  auto globalGen = cm->GetGlobalGenerator();
-
-  for (auto const& projectIt : globalGen->GetProjectMap()) {
-    Json::Value pObj = Json::objectValue;
-    pObj[kNAME_KEY] = projectIt.first;
-
-    // All Projects must have at least one local generator
-    assert(!projectIt.second.empty());
-    const cmLocalGenerator* lg = projectIt.second.at(0);
-
-    // Project structure information:
-    const cmMakefile* mf = lg->GetMakefile();
-    auto minVersion = mf->GetSafeDefinition("CMAKE_MINIMUM_REQUIRED_VERSION");
-    pObj[kMINIMUM_CMAKE_VERSION] = minVersion;
-    pObj[kSOURCE_DIRECTORY_KEY] = mf->GetCurrentSourceDirectory();
-    pObj[kBUILD_DIRECTORY_KEY] = mf->GetCurrentBinaryDirectory();
-    pObj[kTARGETS_KEY] = DumpTargetsList(projectIt.second, config);
-
-    // For a project-level install rule it might be defined in any of its
-    // associated generators.
-    bool hasInstallRule = false;
-    for (const auto generator : projectIt.second) {
-      for (const auto& installGen :
-           generator->GetMakefile()->GetInstallGenerators()) {
-        if (!dynamic_cast<cmInstallSubdirectoryGenerator*>(installGen.get())) {
-          hasInstallRule = true;
-          break;
-        }
-      }
-
-      if (hasInstallRule) {
-        break;
-      }
-    }
-
-    pObj[kHAS_INSTALL_RULE] = hasInstallRule;
-
-    result.append(pObj);
-  }
-
-  return result;
-}
-
-static Json::Value DumpConfiguration(const cmake* cm,
-                                     const std::string& config)
-{
-  Json::Value result = Json::objectValue;
-  result[kNAME_KEY] = config;
-
-  result[kPROJECTS_KEY] = DumpProjectList(cm, config);
-
-  return result;
-}
-
-static Json::Value DumpConfigurationsList(const cmake* cm)
-{
-  Json::Value result = Json::arrayValue;
-
-  for (std::string const& c : getConfigurations(cm)) {
-    result.append(DumpConfiguration(cm, c));
-  }
-
-  return result;
-}
-
-Json::Value cmDumpCodeModel(const cmake* cm)
-{
-  Json::Value result = Json::objectValue;
-  result[kCONFIGURATIONS_KEY] = DumpConfigurationsList(cm);
-  return result;
-}
diff --git a/Source/cmJsonObjects.h b/Source/cmJsonObjects.h
deleted file mode 100644
index 80a4834..0000000
--- a/Source/cmJsonObjects.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
-   file Copyright.txt or https://cmake.org/licensing for details.  */
-#pragma once
-
-#include "cmConfigure.h" // IWYU pragma: keep
-
-#include <string>
-#include <vector>
-
-#include <cm3p/json/value.h>
-
-class cmake;
-class cmGlobalGenerator;
-
-extern void cmGetCMakeInputs(const cmGlobalGenerator* gg,
-                             const std::string& sourceDir,
-                             const std::string& buildDir,
-                             std::vector<std::string>* internalFiles,
-                             std::vector<std::string>* explicitFiles,
-                             std::vector<std::string>* tmpFiles);
-
-extern Json::Value cmDumpCodeModel(const cmake* cm);
-extern Json::Value cmDumpCTestInfo(const cmake* cm);
-extern Json::Value cmDumpCMakeInputs(const cmake* cm);
diff --git a/Source/cmListFileCache.cxx b/Source/cmListFileCache.cxx
index 70ef5af..3658d11 100644
--- a/Source/cmListFileCache.cxx
+++ b/Source/cmListFileCache.cxx
@@ -30,6 +30,7 @@
   bool ParseFunction(const char* name, long line);
   bool AddArgument(cmListFileLexer_Token* token,
                    cmListFileArgument::Delimiter delim);
+  cm::optional<cmListFileContext> CheckNesting();
   cmListFile* ListFile;
   cmListFileBacktrace Backtrace;
   cmMessenger* Messenger;
@@ -158,6 +159,17 @@
       return false;
     }
   }
+
+  // Check if all functions are nested properly.
+  if (auto badNesting = this->CheckNesting()) {
+    this->Messenger->IssueMessage(
+      MessageType::FATAL_ERROR,
+      "Flow control statements are not properly nested.",
+      this->Backtrace.Push(*badNesting));
+    cmSystemTools::SetFatalErrorOccured();
+    return false;
+  }
+
   return true;
 }
 
@@ -317,6 +329,112 @@
   return true;
 }
 
+namespace {
+enum class NestingStateEnum
+{
+  If,
+  Else,
+  While,
+  Foreach,
+  Function,
+  Macro,
+};
+
+struct NestingState
+{
+  NestingStateEnum State;
+  cmListFileContext Context;
+};
+
+bool TopIs(std::vector<NestingState>& stack, NestingStateEnum state)
+{
+  return !stack.empty() && stack.back().State == state;
+}
+}
+
+cm::optional<cmListFileContext> cmListFileParser::CheckNesting()
+{
+  std::vector<NestingState> stack;
+
+  for (auto const& func : this->ListFile->Functions) {
+    auto const& name = func.LowerCaseName();
+    if (name == "if") {
+      stack.push_back({
+        NestingStateEnum::If,
+        cmListFileContext::FromCommandContext(func, this->FileName),
+      });
+    } else if (name == "elseif") {
+      if (!TopIs(stack, NestingStateEnum::If)) {
+        return cmListFileContext::FromCommandContext(func, this->FileName);
+      }
+      stack.back() = {
+        NestingStateEnum::If,
+        cmListFileContext::FromCommandContext(func, this->FileName),
+      };
+    } else if (name == "else") {
+      if (!TopIs(stack, NestingStateEnum::If)) {
+        return cmListFileContext::FromCommandContext(func, this->FileName);
+      }
+      stack.back() = {
+        NestingStateEnum::Else,
+        cmListFileContext::FromCommandContext(func, this->FileName),
+      };
+    } else if (name == "endif") {
+      if (!TopIs(stack, NestingStateEnum::If) &&
+          !TopIs(stack, NestingStateEnum::Else)) {
+        return cmListFileContext::FromCommandContext(func, this->FileName);
+      }
+      stack.pop_back();
+    } else if (name == "while") {
+      stack.push_back({
+        NestingStateEnum::While,
+        cmListFileContext::FromCommandContext(func, this->FileName),
+      });
+    } else if (name == "endwhile") {
+      if (!TopIs(stack, NestingStateEnum::While)) {
+        return cmListFileContext::FromCommandContext(func, this->FileName);
+      }
+      stack.pop_back();
+    } else if (name == "foreach") {
+      stack.push_back({
+        NestingStateEnum::Foreach,
+        cmListFileContext::FromCommandContext(func, this->FileName),
+      });
+    } else if (name == "endforeach") {
+      if (!TopIs(stack, NestingStateEnum::Foreach)) {
+        return cmListFileContext::FromCommandContext(func, this->FileName);
+      }
+      stack.pop_back();
+    } else if (name == "function") {
+      stack.push_back({
+        NestingStateEnum::Function,
+        cmListFileContext::FromCommandContext(func, this->FileName),
+      });
+    } else if (name == "endfunction") {
+      if (!TopIs(stack, NestingStateEnum::Function)) {
+        return cmListFileContext::FromCommandContext(func, this->FileName);
+      }
+      stack.pop_back();
+    } else if (name == "macro") {
+      stack.push_back({
+        NestingStateEnum::Macro,
+        cmListFileContext::FromCommandContext(func, this->FileName),
+      });
+    } else if (name == "endmacro") {
+      if (!TopIs(stack, NestingStateEnum::Macro)) {
+        return cmListFileContext::FromCommandContext(func, this->FileName);
+      }
+      stack.pop_back();
+    }
+  }
+
+  if (!stack.empty()) {
+    return stack.back().Context;
+  }
+
+  return cm::nullopt;
+}
+
 // We hold either the bottom scope of a directory or a call/file context.
 // Discriminate these cases via the parent pointer.
 struct cmListFileBacktrace::Entry
diff --git a/Source/cmListFileCache.h b/Source/cmListFileCache.h
index 727fc60..ed45c07 100644
--- a/Source/cmListFileCache.h
+++ b/Source/cmListFileCache.h
@@ -89,6 +89,14 @@
   {
   }
 
+#if __cplusplus < 201703L && (!defined(_MSVC_LANG) || _MSVC_LANG < 201703L)
+  cmListFileContext(const cmListFileContext& /*other*/) = default;
+  cmListFileContext(cmListFileContext&& /*other*/) = default;
+
+  cmListFileContext& operator=(const cmListFileContext& /*other*/) = default;
+  cmListFileContext& operator=(cmListFileContext&& /*other*/) = delete;
+#endif
+
   static cmListFileContext FromCommandContext(
     cmCommandContext const& lfcc, std::string const& fileName,
     cm::optional<std::string> deferId = {})
diff --git a/Source/cmLoadCommandCommand.cxx b/Source/cmLoadCommandCommand.cxx
index 5790e16..adebe02 100644
--- a/Source/cmLoadCommandCommand.cxx
+++ b/Source/cmLoadCommandCommand.cxx
@@ -24,6 +24,7 @@
 #include "cmCommand.h"
 #include "cmDynamicLoader.h"
 #include "cmExecutionStatus.h"
+#include "cmListFileCache.h"
 #include "cmLocalGenerator.h"
 #include "cmMakefile.h"
 #include "cmState.h"
@@ -36,8 +37,6 @@
 #  include <malloc.h> /* for malloc/free on QNX */
 #endif
 
-class cmListFileBacktrace;
-
 namespace {
 
 const char* LastName = nullptr;
@@ -256,10 +255,12 @@
   // if the symbol is found call it to set the name on the
   // function blocker
   if (initFunction) {
-    status.GetMakefile().GetState()->AddScriptedCommand(
+    return status.GetMakefile().GetState()->AddScriptedCommand(
       args[0],
-      cmLegacyCommandWrapper(cm::make_unique<cmLoadedCommand>(initFunction)));
-    return true;
+      BT<cmState::Command>(
+        cmLegacyCommandWrapper(cm::make_unique<cmLoadedCommand>(initFunction)),
+        status.GetMakefile().GetBacktrace()),
+      status.GetMakefile());
   }
   status.SetError("Attempt to load command failed. "
                   "No init function found.");
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 4e6010c..8a3f285 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -279,7 +279,7 @@
                    });
 }
 
-void cmLocalGenerator::TraceDependencies()
+void cmLocalGenerator::TraceDependencies() const
 {
   // Generate the rule files for each target.
   const auto& targets = this->GetGeneratorTargets();
@@ -823,16 +823,13 @@
   return this->Makefile->GetStateSnapshot();
 }
 
-const char* cmLocalGenerator::GetRuleLauncher(cmGeneratorTarget* target,
-                                              const std::string& prop)
+cmProp cmLocalGenerator::GetRuleLauncher(cmGeneratorTarget* target,
+                                         const std::string& prop)
 {
-  cmProp p;
   if (target) {
-    p = target->GetProperty(prop);
-  } else {
-    p = this->Makefile->GetProperty(prop);
+    return target->GetProperty(prop);
   }
-  return p ? p->c_str() : nullptr;
+  return this->Makefile->GetProperty(prop);
 }
 
 std::string cmLocalGenerator::ConvertToIncludeReference(
@@ -2610,14 +2607,16 @@
           // Add pchHeader to source files, which will
           // be grouped as "Precompile Header File"
           auto pchHeader_sf = this->Makefile->GetOrCreateSource(
-            pchHeader, true, cmSourceFileLocationKind::Known);
+            pchHeader, false, cmSourceFileLocationKind::Known);
           std::string err;
           pchHeader_sf->ResolveFullPath(&err);
-
-          // The pch file is generated, but mark it as not generated
-          // so that a clean operation will not remove it from disk
-          pchHeader_sf->SetProperty("GENERATED", "0");
-
+          if (!err.empty()) {
+            std::ostringstream msg;
+            msg << "Unable to resolve full path of PCH-header '" << pchHeader
+                << "' assigned to target " << target->GetName()
+                << ", although its path is supposed to be known!";
+            this->IssueMessage(MessageType::FATAL_ERROR, msg.str());
+          }
           target->AddSource(pchHeader);
         }
       }
@@ -3210,7 +3209,7 @@
 }
 
 std::string cmLocalGenerator::ConstructComment(
-  cmCustomCommandGenerator const& ccg, const char* default_comment)
+  cmCustomCommandGenerator const& ccg, const char* default_comment) const
 {
   // Check for a comment provided with the command.
   if (ccg.GetComment()) {
@@ -3526,11 +3525,11 @@
   // we don't end up having:
   // CMakeFiles/<target>.dir/CMakeFiles/<target>.dir/generated_source_file.obj
   cmProp unitySourceFile = source.GetProperty("UNITY_SOURCE_FILE");
-  cmProp psExtension = source.GetProperty("PCH_EXTENSION");
+  cmProp pchExtension = source.GetProperty("PCH_EXTENSION");
   const bool isPchObject = objectName.find("cmake_pch") != std::string::npos;
-  if (unitySourceFile || psExtension || isPchObject) {
-    if (psExtension) {
-      customOutputExtension = psExtension->c_str();
+  if (unitySourceFile || pchExtension || isPchObject) {
+    if (pchExtension) {
+      customOutputExtension = pchExtension->c_str();
     }
 
     cmsys::RegularExpression var("(CMakeFiles/[^/]+.dir/)");
@@ -3768,7 +3767,7 @@
   cmLGInfoProp(mf, target, "MACOSX_BUNDLE_SHORT_VERSION_STRING");
   cmLGInfoProp(mf, target, "MACOSX_BUNDLE_BUNDLE_VERSION");
   cmLGInfoProp(mf, target, "MACOSX_BUNDLE_COPYRIGHT");
-  mf->ConfigureFile(inFile, fname, false, false, false, true);
+  mf->ConfigureFile(inFile, fname, false, false, false);
 }
 
 void cmLocalGenerator::GenerateFrameworkInfoPList(
@@ -3803,7 +3802,7 @@
   cmLGInfoProp(mf, target, "MACOSX_FRAMEWORK_IDENTIFIER");
   cmLGInfoProp(mf, target, "MACOSX_FRAMEWORK_SHORT_VERSION_STRING");
   cmLGInfoProp(mf, target, "MACOSX_FRAMEWORK_BUNDLE_VERSION");
-  mf->ConfigureFile(inFile, fname, false, false, false, true);
+  mf->ConfigureFile(inFile, fname, false, false, false);
 }
 
 namespace {
@@ -3918,10 +3917,35 @@
     cc->SetJobPool(job_pool);
     file->SetCustomCommand(std::move(cc));
 
-    mf->AddSourceOutputs(file, outputs, byproducts);
+    lg.AddSourceOutputs(file, outputs, byproducts);
   }
   return file;
 }
+
+bool AnyOutputMatches(const std::string& name,
+                      const std::vector<std::string>& outputs)
+{
+  for (std::string const& output : outputs) {
+    std::string::size_type pos = output.rfind(name);
+    // If the output matches exactly
+    if (pos != std::string::npos && pos == output.size() - name.size() &&
+        (pos == 0 || output[pos - 1] == '/')) {
+      return true;
+    }
+  }
+  return false;
+}
+
+bool AnyTargetCommandOutputMatches(
+  const std::string& name, const std::vector<cmCustomCommand>& commands)
+{
+  for (cmCustomCommand const& command : commands) {
+    if (AnyOutputMatches(name, command.GetByproducts())) {
+      return true;
+    }
+  }
+  return false;
+}
 }
 
 namespace detail {
@@ -3937,8 +3961,6 @@
                               const std::string& job_pool,
                               bool command_expand_lists, bool stdPipesUTF8)
 {
-  cmMakefile* mf = lg.GetMakefile();
-
   // Always create the byproduct sources and mark them generated.
   CreateGeneratedSources(lg, byproducts, origin, lfbt);
 
@@ -3964,7 +3986,7 @@
       break;
   }
 
-  mf->AddTargetByproducts(target, byproducts);
+  lg.AddTargetByproducts(target, byproducts);
 }
 
 cmSourceFile* AddCustomCommandToOutput(
@@ -3996,7 +4018,7 @@
                                  const cmCustomCommandLines& commandLines)
 {
   // Lookup an existing command.
-  if (cmSourceFile* sf = lg.GetMakefile()->GetSourceFileWithOutput(output)) {
+  if (cmSourceFile* sf = lg.GetSourceFileWithOutput(output)) {
     if (cmCustomCommand* cc = sf->GetCustomCommand()) {
       cc->AppendCommands(commandLines);
       cc->AppendDepends(depends);
@@ -4008,7 +4030,7 @@
   // No existing command found.
   lg.GetCMakeInstance()->IssueMessage(
     MessageType::FATAL_ERROR,
-    cmStrCat("Attempt to append to output\n  ", output,
+    cmStrCat("Attempt to APPEND to custom command with output\n  ", output,
              "\nwhich is not already a custom command output."),
     lfbt);
 }
@@ -4040,7 +4062,7 @@
     /*replace=*/false, escapeOldStyle, uses_terminal, command_expand_lists,
     /*depfile=*/"", job_pool, stdPipesUTF8);
   if (rule) {
-    lg.GetMakefile()->AddTargetByproducts(target, byproducts);
+    lg.AddTargetByproducts(target, byproducts);
   }
 
   if (!force.NameCMP0049.empty()) {
@@ -4088,3 +4110,166 @@
   return computedObjects;
 }
 }
+
+cmSourcesWithOutput cmLocalGenerator::GetSourcesWithOutput(
+  const std::string& name) const
+{
+  // Linear search?  Also see GetSourceFileWithOutput for detail.
+  if (!cmSystemTools::FileIsFullPath(name)) {
+    cmSourcesWithOutput sources;
+    sources.Target = this->LinearGetTargetWithOutput(name);
+    sources.Source = this->LinearGetSourceFileWithOutput(
+      name, cmSourceOutputKind::OutputOrByproduct, sources.SourceIsByproduct);
+    return sources;
+  }
+  // Otherwise we use an efficient lookup map.
+  auto o = this->OutputToSource.find(name);
+  if (o != this->OutputToSource.end()) {
+    return o->second.Sources;
+  }
+  return {};
+}
+
+cmSourceFile* cmLocalGenerator::GetSourceFileWithOutput(
+  const std::string& name, cmSourceOutputKind kind) const
+{
+  // If the queried path is not absolute we use the backward compatible
+  // linear-time search for an output with a matching suffix.
+  if (!cmSystemTools::FileIsFullPath(name)) {
+    bool byproduct = false;
+    return this->LinearGetSourceFileWithOutput(name, kind, byproduct);
+  }
+  // Otherwise we use an efficient lookup map.
+  auto o = this->OutputToSource.find(name);
+  if (o != this->OutputToSource.end() &&
+      (!o->second.Sources.SourceIsByproduct ||
+       kind == cmSourceOutputKind::OutputOrByproduct)) {
+    // Source file could also be null pointer for example if we found the
+    // byproduct of a utility target, a PRE_BUILD, PRE_LINK, or POST_BUILD
+    // command of a target, or a not yet created custom command.
+    return o->second.Sources.Source;
+  }
+  return nullptr;
+}
+
+void cmLocalGenerator::AddTargetByproducts(
+  cmTarget* target, const std::vector<std::string>& byproducts)
+{
+  for (std::string const& o : byproducts) {
+    this->UpdateOutputToSourceMap(o, target);
+  }
+}
+
+void cmLocalGenerator::AddSourceOutputs(
+  cmSourceFile* source, const std::vector<std::string>& outputs,
+  const std::vector<std::string>& byproducts)
+{
+  for (std::string const& o : outputs) {
+    this->UpdateOutputToSourceMap(o, source, false);
+  }
+  for (std::string const& o : byproducts) {
+    this->UpdateOutputToSourceMap(o, source, true);
+  }
+}
+
+void cmLocalGenerator::UpdateOutputToSourceMap(std::string const& byproduct,
+                                               cmTarget* target)
+{
+  SourceEntry entry;
+  entry.Sources.Target = target;
+
+  auto pr = this->OutputToSource.emplace(byproduct, entry);
+  if (!pr.second) {
+    SourceEntry& current = pr.first->second;
+    // Has the target already been set?
+    if (!current.Sources.Target) {
+      current.Sources.Target = target;
+    } else {
+      // Multiple custom commands/targets produce the same output (source file
+      // or target).  See also comment in other UpdateOutputToSourceMap
+      // overload.
+      //
+      // TODO: Warn the user about this case.
+    }
+  }
+}
+
+void cmLocalGenerator::UpdateOutputToSourceMap(std::string const& output,
+                                               cmSourceFile* source,
+                                               bool byproduct)
+{
+  SourceEntry entry;
+  entry.Sources.Source = source;
+  entry.Sources.SourceIsByproduct = byproduct;
+
+  auto pr = this->OutputToSource.emplace(output, entry);
+  if (!pr.second) {
+    SourceEntry& current = pr.first->second;
+    // Outputs take precedence over byproducts
+    if (!current.Sources.Source ||
+        (current.Sources.SourceIsByproduct && !byproduct)) {
+      current.Sources.Source = source;
+      current.Sources.SourceIsByproduct = false;
+    } else {
+      // Multiple custom commands produce the same output but may
+      // be attached to a different source file (MAIN_DEPENDENCY).
+      // LinearGetSourceFileWithOutput would return the first one,
+      // so keep the mapping for the first one.
+      //
+      // TODO: Warn the user about this case.  However, the VS 8 generator
+      // triggers it for separate generate.stamp rules in ZERO_CHECK and
+      // individual targets.
+    }
+  }
+}
+
+cmTarget* cmLocalGenerator::LinearGetTargetWithOutput(
+  const std::string& name) const
+{
+  // We go through the ordered vector of targets to get reproducible results
+  // should multiple names match.
+  for (cmTarget* t : this->Makefile->GetOrderedTargets()) {
+    // Does the output of any command match the source file name?
+    if (AnyTargetCommandOutputMatches(name, t->GetPreBuildCommands())) {
+      return t;
+    }
+    if (AnyTargetCommandOutputMatches(name, t->GetPreLinkCommands())) {
+      return t;
+    }
+    if (AnyTargetCommandOutputMatches(name, t->GetPostBuildCommands())) {
+      return t;
+    }
+  }
+  return nullptr;
+}
+
+cmSourceFile* cmLocalGenerator::LinearGetSourceFileWithOutput(
+  const std::string& name, cmSourceOutputKind kind, bool& byproduct) const
+{
+  // Outputs take precedence over byproducts.
+  byproduct = false;
+  cmSourceFile* fallback = nullptr;
+
+  // Look through all the source files that have custom commands and see if the
+  // custom command has the passed source file as an output.
+  for (const auto& src : this->Makefile->GetSourceFiles()) {
+    // Does this source file have a custom command?
+    if (src->GetCustomCommand()) {
+      // Does the output of the custom command match the source file name?
+      if (AnyOutputMatches(name, src->GetCustomCommand()->GetOutputs())) {
+        // Return the first matching output.
+        return src.get();
+      }
+      if (kind == cmSourceOutputKind::OutputOrByproduct) {
+        if (AnyOutputMatches(name, src->GetCustomCommand()->GetByproducts())) {
+          // Do not return the source yet as there might be a matching output.
+          fallback = src.get();
+        }
+      }
+    }
+  }
+
+  // Did we find a byproduct?
+  byproduct = fallback != nullptr;
+  return fallback;
+}
diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h
index 22d3599..30371c5 100644
--- a/Source/cmLocalGenerator.h
+++ b/Source/cmLocalGenerator.h
@@ -36,6 +36,24 @@
 class cmTarget;
 class cmake;
 
+/** Flag if byproducts shall also be considered.  */
+enum class cmSourceOutputKind
+{
+  OutputOnly,
+  OutputOrByproduct
+};
+
+/** Target and source file which have a specific output.  */
+struct cmSourcesWithOutput
+{
+  /** Target with byproduct.  */
+  cmTarget* Target = nullptr;
+
+  /** Source file with output or byproduct.  */
+  cmSourceFile* Source = nullptr;
+  bool SourceIsByproduct = false;
+};
+
 /** \class cmLocalGenerator
  * \brief Create required build files for a directory.
  *
@@ -59,7 +77,7 @@
   /**
    * Calls TraceVSDependencies() on all targets of this generator.
    */
-  void TraceDependencies();
+  void TraceDependencies() const;
 
   virtual void AddHelperCommands() {}
 
@@ -337,6 +355,34 @@
     bool command_expand_lists = false, const std::string& job_pool = "",
     bool stdPipesUTF8 = false);
 
+  /**
+   * Add target byproducts.
+   */
+  void AddTargetByproducts(cmTarget* target,
+                           const std::vector<std::string>& byproducts);
+
+  /**
+   * Add source file outputs.
+   */
+  void AddSourceOutputs(cmSourceFile* source,
+                        const std::vector<std::string>& outputs,
+                        const std::vector<std::string>& byproducts);
+
+  /**
+   * Return the target if the provided source name is a byproduct of a utility
+   * target or a PRE_BUILD, PRE_LINK, or POST_BUILD command.
+   * Return the source file which has the provided source name as output.
+   */
+  cmSourcesWithOutput GetSourcesWithOutput(const std::string& name) const;
+
+  /**
+   * Is there a source file that has the provided source name as an output?
+   * If so then return it.
+   */
+  cmSourceFile* GetSourceFileWithOutput(
+    const std::string& name,
+    cmSourceOutputKind kind = cmSourceOutputKind::OutputOnly) const;
+
   std::string GetProjectName() const;
 
   /** Compute the language used to compile the given source file.  */
@@ -405,7 +451,7 @@
                                   const std::string& fname);
   /** Construct a comment for a custom command.  */
   std::string ConstructComment(cmCustomCommandGenerator const& ccg,
-                               const char* default_comment = "");
+                               const char* default_comment = "") const;
   // Compute object file names.
   std::string GetObjectFileNameWithoutTarget(
     const cmSourceFile& source, std::string const& dir_max,
@@ -473,8 +519,7 @@
   void CreateEvaluationFileOutputs(const std::string& config);
   void ProcessEvaluationFiles(std::vector<std::string>& generatedFiles);
 
-  const char* GetRuleLauncher(cmGeneratorTarget* target,
-                              const std::string& prop);
+  cmProp GetRuleLauncher(cmGeneratorTarget* target, const std::string& prop);
 
 protected:
   //! put all the libraries for a target on into the given stream
@@ -532,6 +577,33 @@
   bool BackwardsCompatibilityFinal;
 
 private:
+  /**
+   * See LinearGetSourceFileWithOutput for background information
+   */
+  cmTarget* LinearGetTargetWithOutput(const std::string& name) const;
+
+  /**
+   * Generalized old version of GetSourceFileWithOutput kept for
+   * backward-compatibility. It implements a linear search and supports
+   * relative file paths. It is used as a fall back by GetSourceFileWithOutput
+   * and GetSourcesWithOutput.
+   */
+  cmSourceFile* LinearGetSourceFileWithOutput(const std::string& name,
+                                              cmSourceOutputKind kind,
+                                              bool& byproduct) const;
+  struct SourceEntry
+  {
+    cmSourcesWithOutput Sources;
+  };
+
+  // A map for fast output to input look up.
+  using OutputToSourceMap = std::unordered_map<std::string, SourceEntry>;
+  OutputToSourceMap OutputToSource;
+
+  void UpdateOutputToSourceMap(std::string const& byproduct, cmTarget* target);
+  void UpdateOutputToSourceMap(std::string const& output, cmSourceFile* source,
+                               bool byproduct);
+
   void AddSharedFlags(std::string& flags, const std::string& lang,
                       bool shared);
   bool GetShouldUseOldFlags(bool shared, const std::string& lang) const;
diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx
index ad782ee..d90a37b 100644
--- a/Source/cmLocalNinjaGenerator.cxx
+++ b/Source/cmLocalNinjaGenerator.cxx
@@ -22,7 +22,9 @@
 #include "cmGlobalNinjaGenerator.h"
 #include "cmLocalGenerator.h"
 #include "cmMakefile.h"
+#include "cmMessageType.h"
 #include "cmNinjaTargetGenerator.h"
+#include "cmPolicies.h"
 #include "cmProperty.h"
 #include "cmRulePlaceholderExpander.h"
 #include "cmSourceFile.h"
@@ -573,7 +575,20 @@
     return;
   }
 
-  cmCustomCommandGenerator ccg(*cc, config, this);
+  bool transformDepfile = false;
+  auto cmp0116 = this->GetPolicyStatus(cmPolicies::CMP0116);
+  switch (cmp0116) {
+    case cmPolicies::OLD:
+    case cmPolicies::WARN:
+      break;
+    case cmPolicies::REQUIRED_IF_USED:
+    case cmPolicies::REQUIRED_ALWAYS:
+    case cmPolicies::NEW:
+      transformDepfile = true;
+      break;
+  }
+
+  cmCustomCommandGenerator ccg(*cc, config, this, transformDepfile);
 
   const std::vector<std::string>& outputs = ccg.GetOutputs();
   const std::vector<std::string>& byproducts = ccg.GetByproducts();
@@ -588,11 +603,6 @@
     }
   }
 
-#if 0
-#  error TODO: Once CC in an ExternalProject target must provide the \
-    file of each imported target that has an add_dependencies pointing \
-    at us.  How to know which ExternalProject step actually provides it?
-#endif
   cmNinjaDeps ninjaOutputs(outputs.size() + byproducts.size());
   std::transform(outputs.begin(), outputs.end(), ninjaOutputs.begin(),
                  gg->MapToNinjaPath());
@@ -623,10 +633,36 @@
     cmCryptoHash hash(cmCryptoHash::AlgoSHA256);
     customStep += hash.HashString(ninjaOutputs[0]).substr(0, 7);
 
+    std::string depfile = cc->GetDepfile();
+    if (!depfile.empty()) {
+      switch (cmp0116) {
+        case cmPolicies::WARN:
+          if (this->GetCurrentBinaryDirectory() !=
+                this->GetBinaryDirectory() ||
+              this->Makefile->PolicyOptionalWarningEnabled(
+                "CMAKE_POLICY_WARNING_CMP0116")) {
+            this->GetCMakeInstance()->IssueMessage(
+              MessageType::AUTHOR_WARNING,
+              cmPolicies::GetPolicyWarning(cmPolicies::CMP0116),
+              cc->GetBacktrace());
+          }
+          CM_FALLTHROUGH;
+        case cmPolicies::OLD:
+          break;
+        case cmPolicies::REQUIRED_IF_USED:
+        case cmPolicies::REQUIRED_ALWAYS:
+        case cmPolicies::NEW:
+          cmSystemTools::MakeDirectory(
+            cmStrCat(this->GetBinaryDirectory(), "/CMakeFiles/d"));
+          depfile = ccg.GetInternalDepfile();
+          break;
+      }
+    }
+
     gg->WriteCustomCommandBuild(
       this->BuildCommandLine(cmdLines, customStep),
       this->ConstructComment(ccg), "Custom command for " + ninjaOutputs[0],
-      cc->GetDepfile(), cc->GetJobPool(), cc->GetUsesTerminal(),
+      depfile, cc->GetJobPool(), cc->GetUsesTerminal(),
       /*restat*/ !symbolic || !byproducts.empty(), ninjaOutputs, config,
       ninjaDeps, orderOnlyDeps);
   }
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index c877cf8..dd27084 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -960,7 +960,7 @@
 
       std::string launcher;
       // Short-circuit if there is no launcher.
-      const char* val = this->GetRuleLauncher(target, "RULE_LAUNCH_CUSTOM");
+      cmProp val = this->GetRuleLauncher(target, "RULE_LAUNCH_CUSTOM");
       if (cmNonempty(val)) {
         // Expand rule variables referenced in the given launcher command.
         cmRulePlaceholderExpander::RuleVariables vars;
@@ -980,7 +980,7 @@
         }
         vars.Output = output.c_str();
 
-        launcher = val;
+        launcher = *val;
         rulePlaceholderExpander->ExpandRuleVariables(this, launcher, vars);
         if (!launcher.empty()) {
           launcher += " ";
diff --git a/Source/cmLocalUnixMakefileGenerator3.h b/Source/cmLocalUnixMakefileGenerator3.h
index 8286d67..5edca2a 100644
--- a/Source/cmLocalUnixMakefileGenerator3.h
+++ b/Source/cmLocalUnixMakefileGenerator3.h
@@ -178,11 +178,11 @@
   /** Get whether to create rules to generate preprocessed and
       assembly sources.  This could be converted to a variable lookup
       later.  */
-  bool GetCreatePreprocessedSourceRules()
+  bool GetCreatePreprocessedSourceRules() const
   {
     return !this->SkipPreprocessedSourceRules;
   }
-  bool GetCreateAssemblySourceRules()
+  bool GetCreateAssemblySourceRules() const
   {
     return !this->SkipAssemblySourceRules;
   }
diff --git a/Source/cmMacroCommand.cxx b/Source/cmMacroCommand.cxx
index 98f88c1..8c4b2a7 100644
--- a/Source/cmMacroCommand.cxx
+++ b/Source/cmMacroCommand.cxx
@@ -171,8 +171,11 @@
   f.Functions = std::move(functions);
   f.FilePath = this->GetStartingContext().FilePath;
   mf.RecordPolicies(f.Policies);
-  mf.GetState()->AddScriptedCommand(this->Args[0], std::move(f));
-  return true;
+  return mf.GetState()->AddScriptedCommand(
+    this->Args[0],
+    BT<cmState::Command>(std::move(f),
+                         mf.GetBacktrace().Push(this->GetStartingContext())),
+    mf);
 }
 }
 
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 0e4f888..50a7d27 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -29,15 +29,12 @@
 #include "cmsys/FStream.hxx"
 #include "cmsys/RegularExpression.hxx"
 
-#include "cm_sys_stat.h"
-
 #include "cmCommandArgumentParserHelper.h"
 #include "cmCustomCommand.h"
 #include "cmCustomCommandLines.h"
 #include "cmExecutionStatus.h"
 #include "cmExpandedCommandArgument.h" // IWYU pragma: keep
 #include "cmExportBuildFileGenerator.h"
-#include "cmFSPermissions.h"
 #include "cmFileLockPool.h"
 #include "cmFunctionBlocker.h"
 #include "cmGeneratedFileStream.h"
@@ -72,8 +69,6 @@
 
 class cmMessenger;
 
-using namespace cmFSPermissions;
-
 cmDirectoryId::cmDirectoryId(std::string s)
   : String(std::move(s))
 {
@@ -939,8 +934,6 @@
     action.Value(lg, action.Backtrace);
   }
   this->GeneratorActionsInvoked = true;
-  this->DelayedOutputFiles.clear();
-  this->DelayedOutputFilesHaveGenex = false;
 
   // go through all configured files and see which ones still exist.
   // we don't want cmake to re-run if a configured file is created and deleted
@@ -1104,7 +1097,7 @@
   }
 
   // Always create the byproduct sources and mark them generated.
-  this->CreateGeneratedByproducts(byproducts);
+  this->CreateGeneratedOutputs(byproducts);
 
   // Strings could be moved into the callback function with C++14.
   cm::optional<std::string> commentStr = MakeOptionalString(comment);
@@ -1163,7 +1156,7 @@
 
   // Always create the output sources and mark them generated.
   this->CreateGeneratedOutputs(outputs);
-  this->CreateGeneratedByproducts(byproducts);
+  this->CreateGeneratedOutputs(byproducts);
 
   // Strings could be moved into the callback function with C++14.
   cm::optional<std::string> commentStr = MakeOptionalString(comment);
@@ -1247,16 +1240,11 @@
   }
 }
 
-bool cmMakefile::AppendCustomCommandToOutput(
+void cmMakefile::AppendCustomCommandToOutput(
   const std::string& output, const std::vector<std::string>& depends,
   const cmImplicitDependsList& implicit_depends,
   const cmCustomCommandLines& commandLines)
 {
-  // Check as good as we can if there will be a command for this output.
-  if (!this->MightHaveCustomCommand(output)) {
-    return false;
-  }
-
   // Validate custom commands.
   if (this->ValidateCustomCommand(commandLines)) {
     // Dispatch command creation to allow generator expressions in outputs.
@@ -1267,8 +1255,6 @@
                                             implicit_depends, commandLines);
       });
   }
-
-  return true;
 }
 
 cmUtilityOutput cmMakefile::GetUtilityOutput(cmTarget* target)
@@ -1313,7 +1299,7 @@
   this->GetOrCreateGeneratedSource(force.Name);
 
   // Always create the byproduct sources and mark them generated.
-  this->CreateGeneratedByproducts(byproducts);
+  this->CreateGeneratedOutputs(byproducts);
 
   // Strings could be moved into the callback function with C++14.
   cm::optional<std::string> commentStr = MakeOptionalString(comment);
@@ -1496,15 +1482,14 @@
   // Include transform property.  There is no per-config version.
   {
     const char* prop = "IMPLICIT_DEPENDS_INCLUDE_TRANSFORM";
-    cmProp p = parent->GetProperty(prop);
-    this->SetProperty(prop, cmToCStr(p));
+    this->SetProperty(prop, cmToCStr(parent->GetProperty(prop)));
   }
 
   // compile definitions property and per-config versions
   cmPolicies::PolicyStatus polSt = this->GetPolicyStatus(cmPolicies::CMP0043);
   if (polSt == cmPolicies::WARN || polSt == cmPolicies::OLD) {
-    cmProp p = parent->GetProperty("COMPILE_DEFINITIONS");
-    this->SetProperty("COMPILE_DEFINITIONS", cmToCStr(p));
+    this->SetProperty("COMPILE_DEFINITIONS",
+                      cmToCStr(parent->GetProperty("COMPILE_DEFINITIONS")));
     std::vector<std::string> configs =
       this->GetGeneratorConfigs(cmMakefile::ExcludeEmptyConfig);
     for (std::string const& config : configs) {
@@ -1516,12 +1501,11 @@
   }
 
   // labels
-  cmProp p = parent->GetProperty("LABELS");
-  this->SetProperty("LABELS", cmToCStr(p));
+  this->SetProperty("LABELS", cmToCStr(parent->GetProperty("LABELS")));
 
   // link libraries
-  p = parent->GetProperty("LINK_LIBRARIES");
-  this->SetProperty("LINK_LIBRARIES", cmToCStr(p));
+  this->SetProperty("LINK_LIBRARIES",
+                    cmToCStr(parent->GetProperty("LINK_LIBRARIES")));
 
   // the initial project name
   this->StateSnapshot.SetProjectName(parent->StateSnapshot.GetProjectName());
@@ -2038,7 +2022,7 @@
 #endif
 }
 
-void cmMakefile::RemoveCacheDefinition(const std::string& name)
+void cmMakefile::RemoveCacheDefinition(const std::string& name) const
 {
   this->GetState()->RemoveCacheEntry(name);
 }
@@ -2154,213 +2138,6 @@
 }
 
 namespace {
-bool AnyOutputMatches(const std::string& name,
-                      const std::vector<std::string>& outputs)
-{
-  for (std::string const& output : outputs) {
-    std::string::size_type pos = output.rfind(name);
-    // If the output matches exactly
-    if (pos != std::string::npos && pos == output.size() - name.size() &&
-        (pos == 0 || output[pos - 1] == '/')) {
-      return true;
-    }
-  }
-  return false;
-}
-
-bool AnyTargetCommandOutputMatches(
-  const std::string& name, const std::vector<cmCustomCommand>& commands)
-{
-  for (cmCustomCommand const& command : commands) {
-    if (AnyOutputMatches(name, command.GetByproducts())) {
-      return true;
-    }
-  }
-  return false;
-}
-}
-
-cmTarget* cmMakefile::LinearGetTargetWithOutput(const std::string& name) const
-{
-  // We go through the ordered vector of targets to get reproducible results
-  // should multiple names match.
-  for (cmTarget* t : this->OrderedTargets) {
-    // Does the output of any command match the source file name?
-    if (AnyTargetCommandOutputMatches(name, t->GetPreBuildCommands())) {
-      return t;
-    }
-    if (AnyTargetCommandOutputMatches(name, t->GetPreLinkCommands())) {
-      return t;
-    }
-    if (AnyTargetCommandOutputMatches(name, t->GetPostBuildCommands())) {
-      return t;
-    }
-  }
-  return nullptr;
-}
-
-cmSourceFile* cmMakefile::LinearGetSourceFileWithOutput(
-  const std::string& name, cmSourceOutputKind kind, bool& byproduct) const
-{
-  // Outputs take precedence over byproducts.
-  byproduct = false;
-  cmSourceFile* fallback = nullptr;
-
-  // Look through all the source files that have custom commands and see if the
-  // custom command has the passed source file as an output.
-  for (const auto& src : this->SourceFiles) {
-    // Does this source file have a custom command?
-    if (src->GetCustomCommand()) {
-      // Does the output of the custom command match the source file name?
-      if (AnyOutputMatches(name, src->GetCustomCommand()->GetOutputs())) {
-        // Return the first matching output.
-        return src.get();
-      }
-      if (kind == cmSourceOutputKind::OutputOrByproduct) {
-        if (AnyOutputMatches(name, src->GetCustomCommand()->GetByproducts())) {
-          // Do not return the source yet as there might be a matching output.
-          fallback = src.get();
-        }
-      }
-    }
-  }
-
-  // Did we find a byproduct?
-  byproduct = fallback != nullptr;
-  return fallback;
-}
-
-cmSourcesWithOutput cmMakefile::GetSourcesWithOutput(
-  const std::string& name) const
-{
-  // Linear search?  Also see GetSourceFileWithOutput for detail.
-  if (!cmSystemTools::FileIsFullPath(name)) {
-    cmSourcesWithOutput sources;
-    sources.Target = this->LinearGetTargetWithOutput(name);
-    sources.Source = this->LinearGetSourceFileWithOutput(
-      name, cmSourceOutputKind::OutputOrByproduct, sources.SourceIsByproduct);
-    return sources;
-  }
-  // Otherwise we use an efficient lookup map.
-  auto o = this->OutputToSource.find(name);
-  if (o != this->OutputToSource.end()) {
-    return o->second.Sources;
-  }
-  return {};
-}
-
-cmSourceFile* cmMakefile::GetSourceFileWithOutput(
-  const std::string& name, cmSourceOutputKind kind) const
-{
-  // If the queried path is not absolute we use the backward compatible
-  // linear-time search for an output with a matching suffix.
-  if (!cmSystemTools::FileIsFullPath(name)) {
-    bool byproduct = false;
-    return this->LinearGetSourceFileWithOutput(name, kind, byproduct);
-  }
-  // Otherwise we use an efficient lookup map.
-  auto o = this->OutputToSource.find(name);
-  if (o != this->OutputToSource.end() &&
-      (!o->second.Sources.SourceIsByproduct ||
-       kind == cmSourceOutputKind::OutputOrByproduct)) {
-    // Source file could also be null pointer for example if we found the
-    // byproduct of a utility target, a PRE_BUILD, PRE_LINK, or POST_BUILD
-    // command of a target, or a not yet created custom command.
-    return o->second.Sources.Source;
-  }
-  return nullptr;
-}
-
-bool cmMakefile::MightHaveCustomCommand(const std::string& name) const
-{
-  if (this->DelayedOutputFilesHaveGenex ||
-      cmGeneratorExpression::Find(name) != std::string::npos) {
-    // Could be more restrictive, but for now we assume that there could always
-    // be a match when generator expressions are involved.
-    return true;
-  }
-  // Also see LinearGetSourceFileWithOutput.
-  if (!cmSystemTools::FileIsFullPath(name)) {
-    return AnyOutputMatches(name, this->DelayedOutputFiles);
-  }
-  // Otherwise we use an efficient lookup map.
-  auto o = this->OutputToSource.find(name);
-  if (o != this->OutputToSource.end()) {
-    return o->second.SourceMightBeOutput;
-  }
-  return false;
-}
-
-void cmMakefile::AddTargetByproducts(
-  cmTarget* target, const std::vector<std::string>& byproducts)
-{
-  for (std::string const& o : byproducts) {
-    this->UpdateOutputToSourceMap(o, target);
-  }
-}
-
-void cmMakefile::AddSourceOutputs(cmSourceFile* source,
-                                  const std::vector<std::string>& outputs,
-                                  const std::vector<std::string>& byproducts)
-{
-  for (std::string const& o : outputs) {
-    this->UpdateOutputToSourceMap(o, source, false);
-  }
-  for (std::string const& o : byproducts) {
-    this->UpdateOutputToSourceMap(o, source, true);
-  }
-}
-
-void cmMakefile::UpdateOutputToSourceMap(std::string const& byproduct,
-                                         cmTarget* target)
-{
-  SourceEntry entry;
-  entry.Sources.Target = target;
-
-  auto pr = this->OutputToSource.emplace(byproduct, entry);
-  if (!pr.second) {
-    SourceEntry& current = pr.first->second;
-    // Has the target already been set?
-    if (!current.Sources.Target) {
-      current.Sources.Target = target;
-    } else {
-      // Multiple custom commands/targets produce the same output (source file
-      // or target).  See also comment in other UpdateOutputToSourceMap
-      // overload.
-      //
-      // TODO: Warn the user about this case.
-    }
-  }
-}
-
-void cmMakefile::UpdateOutputToSourceMap(std::string const& output,
-                                         cmSourceFile* source, bool byproduct)
-{
-  SourceEntry entry;
-  entry.Sources.Source = source;
-  entry.Sources.SourceIsByproduct = byproduct;
-  entry.SourceMightBeOutput = !byproduct;
-
-  auto pr = this->OutputToSource.emplace(output, entry);
-  if (!pr.second) {
-    SourceEntry& current = pr.first->second;
-    // Outputs take precedence over byproducts
-    if (!current.Sources.Source ||
-        (current.Sources.SourceIsByproduct && !byproduct)) {
-      current.Sources.Source = source;
-      current.Sources.SourceIsByproduct = false;
-      current.SourceMightBeOutput = true;
-    } else {
-      // Multiple custom commands produce the same output but may
-      // be attached to a different source file (MAIN_DEPENDENCY).
-      // LinearGetSourceFileWithOutput would return the first one,
-      // so keep the mapping for the first one.
-      //
-      // TODO: Warn the user about this case.  However, the VS 8 generator
-      // triggers it for separate generate.stamp rules in ZERO_CHECK and
-      // individual targets.
-    }
-  }
 }
 
 #if !defined(CMAKE_BOOTSTRAP)
@@ -3055,7 +2832,7 @@
   this->RecursionDepth = recursionDepth;
 }
 
-std::string cmMakefile::NewDeferId()
+std::string cmMakefile::NewDeferId() const
 {
   return this->GetGlobalGenerator()->NewDeferId();
 }
@@ -3675,38 +3452,10 @@
   for (std::string const& o : outputs) {
     if (cmGeneratorExpression::Find(o) == std::string::npos) {
       this->GetOrCreateGeneratedSource(o);
-      this->AddDelayedOutput(o);
-    } else {
-      this->DelayedOutputFilesHaveGenex = true;
     }
   }
 }
 
-void cmMakefile::CreateGeneratedByproducts(
-  const std::vector<std::string>& byproducts)
-{
-  for (std::string const& o : byproducts) {
-    if (cmGeneratorExpression::Find(o) == std::string::npos) {
-      this->GetOrCreateGeneratedSource(o);
-    }
-  }
-}
-
-void cmMakefile::AddDelayedOutput(std::string const& output)
-{
-  // Note that this vector might contain the output names in a different order
-  // than in source file iteration order.
-  this->DelayedOutputFiles.push_back(output);
-
-  SourceEntry entry;
-  entry.SourceMightBeOutput = true;
-
-  auto pr = this->OutputToSource.emplace(output, entry);
-  if (!pr.second) {
-    pr.first->second.SourceMightBeOutput = true;
-  }
-}
-
 void cmMakefile::AddTargetObject(std::string const& tgtName,
                                  std::string const& objFile)
 {
@@ -4094,8 +3843,7 @@
 int cmMakefile::ConfigureFile(const std::string& infile,
                               const std::string& outfile, bool copyonly,
                               bool atOnly, bool escapeQuotes,
-                              bool use_source_permissions,
-                              cmNewLineStyle newLine)
+                              mode_t permissions, cmNewLineStyle newLine)
 {
   int res = 1;
   if (!this->CanIWriteThisFile(outfile)) {
@@ -4117,12 +3865,8 @@
   // output files that now don't exist.
   this->AddCMakeOutputFile(soutfile);
 
-  mode_t perm = 0;
-  if (!use_source_permissions) {
-    perm = perm | mode_owner_read | mode_owner_write | mode_group_read |
-      mode_world_read;
-  } else {
-    cmSystemTools::GetPermissions(sinfile, perm);
+  if (permissions == 0) {
+    cmSystemTools::GetPermissions(sinfile, permissions);
   }
 
   std::string::size_type pos = soutfile.rfind('/');
@@ -4137,7 +3881,7 @@
                          cmSystemTools::GetLastSystemError());
       return 0;
     }
-    if (!cmSystemTools::SetPermissions(soutfile, perm)) {
+    if (!cmSystemTools::SetPermissions(soutfile, permissions)) {
       this->IssueMessage(MessageType::FATAL_ERROR,
                          cmSystemTools::GetLastSystemError());
       return 0;
@@ -4194,7 +3938,7 @@
                          cmSystemTools::GetLastSystemError());
       res = 0;
     } else {
-      if (!cmSystemTools::SetPermissions(soutfile, perm)) {
+      if (!cmSystemTools::SetPermissions(soutfile, permissions)) {
         this->IssueMessage(MessageType::FATAL_ERROR,
                            cmSystemTools::GetLastSystemError());
         res = 0;
@@ -4283,7 +4027,7 @@
 }
 
 void cmMakefile::GetTests(const std::string& config,
-                          std::vector<cmTest*>& tests)
+                          std::vector<cmTest*>& tests) const
 {
   for (const auto& generator : this->GetTestGenerators()) {
     if (generator->TestsForConfig(config)) {
@@ -4633,7 +4377,7 @@
   return this->StateSnapshot.GetPolicy(id, parent_scope);
 }
 
-bool cmMakefile::PolicyOptionalWarningEnabled(std::string const& var)
+bool cmMakefile::PolicyOptionalWarningEnabled(std::string const& var) const
 {
   // Check for an explicit CMAKE_POLICY_WARNING_CMP<NNNN> setting.
   if (cmProp val = this->GetDefinition(var)) {
@@ -4670,7 +4414,7 @@
 
   // Deprecate old policies, especially those that require a lot
   // of code to maintain the old behavior.
-  if (status == cmPolicies::OLD && id <= cmPolicies::CMP0072 &&
+  if (status == cmPolicies::OLD && id <= cmPolicies::CMP0075 &&
       !(this->GetCMakeInstance()->GetIsInTryCompile() &&
         (
           // Policies set by cmCoreTryCompile::TryCompileCode.
@@ -4738,7 +4482,7 @@
   return !this->CMP0054ReportedIds.insert(context).second;
 }
 
-void cmMakefile::RecordPolicies(cmPolicies::PolicyMap& pm)
+void cmMakefile::RecordPolicies(cmPolicies::PolicyMap& pm) const
 {
   /* Record the setting of every policy.  */
   using PolicyID = cmPolicies::PolicyID;
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index c7940fb..a864074 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -20,6 +20,8 @@
 
 #include "cmsys/RegularExpression.hxx"
 
+#include "cm_sys_stat.h"
+
 #include "cmAlgorithms.h"
 #include "cmCustomCommandTypes.h"
 #include "cmListFileCache.h"
@@ -59,24 +61,6 @@
 class cmVariableWatch;
 class cmake;
 
-/** Flag if byproducts shall also be considered.  */
-enum class cmSourceOutputKind
-{
-  OutputOnly,
-  OutputOrByproduct
-};
-
-/** Target and source file which have a specific output.  */
-struct cmSourcesWithOutput
-{
-  /** Target with byproduct.  */
-  cmTarget* Target = nullptr;
-
-  /** Source file with output or byproduct.  */
-  cmSourceFile* Source = nullptr;
-  bool SourceIsByproduct = false;
-};
-
 /** A type-safe wrapper for a string representing a directory id.  */
 class cmDirectoryId
 {
@@ -225,25 +209,12 @@
                                 const std::string& source,
                                 const cmCustomCommandLines& commandLines,
                                 const char* comment);
-  bool AppendCustomCommandToOutput(
+  void AppendCustomCommandToOutput(
     const std::string& output, const std::vector<std::string>& depends,
     const cmImplicitDependsList& implicit_depends,
     const cmCustomCommandLines& commandLines);
 
   /**
-   * Add target byproducts.
-   */
-  void AddTargetByproducts(cmTarget* target,
-                           const std::vector<std::string>& byproducts);
-
-  /**
-   * Add source file outputs.
-   */
-  void AddSourceOutputs(cmSourceFile* source,
-                        const std::vector<std::string>& outputs,
-                        const std::vector<std::string>& byproducts);
-
-  /**
    * Add a define flag to the build.
    */
   void AddDefineFlag(std::string const& definition);
@@ -335,7 +306,7 @@
    */
   void RemoveDefinition(const std::string& name);
   //! Remove a definition from the cache.
-  void RemoveCacheDefinition(const std::string& name);
+  void RemoveCacheDefinition(const std::string& name) const;
 
   /**
    * Specify the name of the project for this build.
@@ -376,7 +347,7 @@
                                            bool parent_scope = false) const;
   bool SetPolicyVersion(std::string const& version_min,
                         std::string const& version_max);
-  void RecordPolicies(cmPolicies::PolicyMap& pm);
+  void RecordPolicies(cmPolicies::PolicyMap& pm) const;
   //@}
 
   /** Helper class to push and pop policies automatically.  */
@@ -430,8 +401,7 @@
   }
   const char* GetIncludeRegularExpression() const
   {
-    cmProp p = this->GetProperty("INCLUDE_REGULAR_EXPRESSION");
-    return p ? p->c_str() : nullptr;
+    return cmToCStr(this->GetProperty("INCLUDE_REGULAR_EXPRESSION"));
   }
 
   /**
@@ -690,8 +660,7 @@
    */
   int ConfigureFile(const std::string& infile, const std::string& outfile,
                     bool copyonly, bool atOnly, bool escapeQuotes,
-                    bool use_source_permissions,
-                    cmNewLineStyle = cmNewLineStyle());
+                    mode_t permissions = 0, cmNewLineStyle = cmNewLineStyle());
 
   /**
    * Print a command's invocation
@@ -753,20 +722,10 @@
     return this->SourceFiles;
   }
 
-  /**
-   * Return the target if the provided source name is a byproduct of a utility
-   * target or a PRE_BUILD, PRE_LINK, or POST_BUILD command.
-   * Return the source file which has the provided source name as output.
-   */
-  cmSourcesWithOutput GetSourcesWithOutput(const std::string& name) const;
-
-  /**
-   * Is there a source file that has the provided source name as an output?
-   * If so then return it.
-   */
-  cmSourceFile* GetSourceFileWithOutput(
-    const std::string& name,
-    cmSourceOutputKind kind = cmSourceOutputKind::OutputOnly) const;
+  std::vector<cmTarget*> const& GetOrderedTargets() const
+  {
+    return this->OrderedTargets;
+  }
 
   //! Add a new cmTest to the list of tests for this makefile.
   cmTest* CreateTest(const std::string& testName);
@@ -779,7 +738,7 @@
   /**
    * Get all tests that run under the given configuration.
    */
-  void GetTests(const std::string& config, std::vector<cmTest*>& tests);
+  void GetTests(const std::string& config, std::vector<cmTest*>& tests) const;
 
   /**
    * Return a location of a file in cmake or custom modules directory
@@ -926,7 +885,7 @@
     return this->SystemIncludeDirectories;
   }
 
-  bool PolicyOptionalWarningEnabled(std::string const& var);
+  bool PolicyOptionalWarningEnabled(std::string const& var) const;
 
   void PushLoopBlock();
   void PopLoopBlock();
@@ -967,7 +926,7 @@
   int GetRecursionDepth() const;
   void SetRecursionDepth(int recursionDepth);
 
-  std::string NewDeferId();
+  std::string NewDeferId() const;
   bool DeferCall(std::string id, std::string fileName, cmListFileFunction lff);
   bool DeferCancelCall(std::string const& id);
   cm::optional<std::string> DeferGetCallIds() const;
@@ -983,8 +942,7 @@
   mutable cmTargetMap Targets;
   std::map<std::string, std::string> AliasTargets;
 
-  using TargetsVec = std::vector<cmTarget*>;
-  TargetsVec OrderedTargets;
+  std::vector<cmTarget*> OrderedTargets;
 
   std::vector<std::unique_ptr<cmSourceFile>> SourceFiles;
 
@@ -1129,48 +1087,9 @@
   bool ValidateCustomCommand(const cmCustomCommandLines& commandLines) const;
 
   void CreateGeneratedOutputs(const std::vector<std::string>& outputs);
-  void CreateGeneratedByproducts(const std::vector<std::string>& byproducts);
 
   std::vector<BT<GeneratorAction>> GeneratorActions;
   bool GeneratorActionsInvoked = false;
-  bool DelayedOutputFilesHaveGenex = false;
-  std::vector<std::string> DelayedOutputFiles;
-
-  void AddDelayedOutput(std::string const& output);
-
-  /**
-   * See LinearGetSourceFileWithOutput for background information
-   */
-  cmTarget* LinearGetTargetWithOutput(const std::string& name) const;
-
-  /**
-   * Generalized old version of GetSourceFileWithOutput kept for
-   * backward-compatibility. It implements a linear search and supports
-   * relative file paths. It is used as a fall back by GetSourceFileWithOutput
-   * and GetSourcesWithOutput.
-   */
-  cmSourceFile* LinearGetSourceFileWithOutput(const std::string& name,
-                                              cmSourceOutputKind kind,
-                                              bool& byproduct) const;
-
-  struct SourceEntry
-  {
-    cmSourcesWithOutput Sources;
-    bool SourceMightBeOutput = false;
-  };
-
-  // A map for fast output to input look up.
-  using OutputToSourceMap = std::unordered_map<std::string, SourceEntry>;
-  OutputToSourceMap OutputToSource;
-
-  void UpdateOutputToSourceMap(std::string const& byproduct, cmTarget* target);
-  void UpdateOutputToSourceMap(std::string const& output, cmSourceFile* source,
-                               bool byproduct);
-
-  /**
-   * Return if the provided source file might have a custom command.
-   */
-  bool MightHaveCustomCommand(const std::string& name) const;
 
   bool CheckSystemVars;
   bool CheckCMP0000;
diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx
index 871878c..1750e37 100644
--- a/Source/cmMakefileExecutableTargetGenerator.cxx
+++ b/Source/cmMakefileExecutableTargetGenerator.cxx
@@ -21,6 +21,7 @@
 #include "cmMakefile.h"
 #include "cmOSXBundleGenerator.h"
 #include "cmOutputConverter.h"
+#include "cmProperty.h"
 #include "cmRulePlaceholderExpander.h"
 #include "cmState.h"
 #include "cmStateDirectory.h"
@@ -232,10 +233,10 @@
 
     std::string launcher;
 
-    const char* val = this->LocalGenerator->GetRuleLauncher(
-      this->GeneratorTarget, "RULE_LAUNCH_LINK");
+    cmProp val = this->LocalGenerator->GetRuleLauncher(this->GeneratorTarget,
+                                                       "RULE_LAUNCH_LINK");
     if (cmNonempty(val)) {
-      launcher = cmStrCat(val, ' ');
+      launcher = cmStrCat(*val, ' ');
     }
 
     std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander(
@@ -591,10 +592,10 @@
 
     std::string launcher;
 
-    const char* val = this->LocalGenerator->GetRuleLauncher(
-      this->GeneratorTarget, "RULE_LAUNCH_LINK");
+    cmProp val = this->LocalGenerator->GetRuleLauncher(this->GeneratorTarget,
+                                                       "RULE_LAUNCH_LINK");
     if (cmNonempty(val)) {
-      launcher = cmStrCat(val, ' ');
+      launcher = cmStrCat(*val, ' ');
     }
 
     std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander(
diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx
index b32ea6a..ce64e2c 100644
--- a/Source/cmMakefileLibraryTargetGenerator.cxx
+++ b/Source/cmMakefileLibraryTargetGenerator.cxx
@@ -21,6 +21,7 @@
 #include "cmMakefile.h"
 #include "cmOSXBundleGenerator.h"
 #include "cmOutputConverter.h"
+#include "cmProperty.h"
 #include "cmRulePlaceholderExpander.h"
 #include "cmState.h"
 #include "cmStateDirectory.h"
@@ -366,10 +367,10 @@
     vars.TargetCompilePDB = targetOutPathCompilePDB.c_str();
 
     std::string launcher;
-    const char* val = this->LocalGenerator->GetRuleLauncher(
-      this->GeneratorTarget, "RULE_LAUNCH_LINK");
+    cmProp val = this->LocalGenerator->GetRuleLauncher(this->GeneratorTarget,
+                                                       "RULE_LAUNCH_LINK");
     if (cmNonempty(val)) {
-      launcher = cmStrCat(val, ' ');
+      launcher = cmStrCat(*val, ' ');
     }
 
     std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander(
@@ -816,10 +817,10 @@
     vars.LanguageCompileFlags = langFlags.c_str();
 
     std::string launcher;
-    const char* val = this->LocalGenerator->GetRuleLauncher(
-      this->GeneratorTarget, "RULE_LAUNCH_LINK");
+    cmProp val = this->LocalGenerator->GetRuleLauncher(this->GeneratorTarget,
+                                                       "RULE_LAUNCH_LINK");
     if (cmNonempty(val)) {
-      launcher = cmStrCat(val, ' ');
+      launcher = cmStrCat(*val, ' ');
     }
 
     std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander(
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index 3c4f68c..f0d464e 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -788,7 +788,7 @@
   bool lang_has_preprocessor =
     ((lang == "C") || (lang == "CXX") || (lang == "OBJC") ||
      (lang == "OBJCXX") || (lang == "Fortran") || (lang == "CUDA") ||
-     lang == "ISPC");
+     lang == "ISPC" || lang == "ASM");
   bool const lang_has_assembly = lang_has_preprocessor;
   bool const lang_can_export_cmds = lang_has_preprocessor;
 
@@ -866,15 +866,21 @@
     }
 
     // Maybe insert an include-what-you-use runner.
-    if (!compileCommands.empty() && (lang == "C" || lang == "CXX")) {
-      std::string const iwyu_prop = lang + "_INCLUDE_WHAT_YOU_USE";
-      cmProp iwyu = this->GeneratorTarget->GetProperty(iwyu_prop);
+    if (!compileCommands.empty() &&
+        (lang == "C" || lang == "CXX" || lang == "OBJC" || lang == "OBJCXX")) {
       std::string const tidy_prop = lang + "_CLANG_TIDY";
       cmProp tidy = this->GeneratorTarget->GetProperty(tidy_prop);
-      std::string const cpplint_prop = lang + "_CPPLINT";
-      cmProp cpplint = this->GeneratorTarget->GetProperty(cpplint_prop);
-      std::string const cppcheck_prop = lang + "_CPPCHECK";
-      cmProp cppcheck = this->GeneratorTarget->GetProperty(cppcheck_prop);
+      cmProp iwyu = nullptr;
+      cmProp cpplint = nullptr;
+      cmProp cppcheck = nullptr;
+      if (lang == "C" || lang == "CXX") {
+        std::string const iwyu_prop = lang + "_INCLUDE_WHAT_YOU_USE";
+        iwyu = this->GeneratorTarget->GetProperty(iwyu_prop);
+        std::string const cpplint_prop = lang + "_CPPLINT";
+        cpplint = this->GeneratorTarget->GetProperty(cpplint_prop);
+        std::string const cppcheck_prop = lang + "_CPPCHECK";
+        cppcheck = this->GeneratorTarget->GetProperty(cppcheck_prop);
+      }
       if (cmNonempty(iwyu) || cmNonempty(tidy) || cmNonempty(cpplint) ||
           cmNonempty(cppcheck)) {
         std::string run_iwyu = "$(CMAKE_COMMAND) -E __run_co_compile";
@@ -936,10 +942,10 @@
 
     std::string launcher;
     {
-      const char* val = this->LocalGenerator->GetRuleLauncher(
+      cmProp val = this->LocalGenerator->GetRuleLauncher(
         this->GeneratorTarget, "RULE_LAUNCH_COMPILE");
       if (cmNonempty(val)) {
-        launcher = cmStrCat(val, ' ');
+        launcher = cmStrCat(*val, ' ');
       }
     }
 
diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx
index ccb959b..a5b9466 100644
--- a/Source/cmNinjaNormalTargetGenerator.cxx
+++ b/Source/cmNinjaNormalTargetGenerator.cxx
@@ -266,10 +266,10 @@
     vars.LanguageCompileFlags = "$LANGUAGE_COMPILE_FLAGS";
 
     std::string launcher;
-    const char* val = this->GetLocalGenerator()->GetRuleLauncher(
+    cmProp val = this->GetLocalGenerator()->GetRuleLauncher(
       this->GetGeneratorTarget(), "RULE_LAUNCH_LINK");
     if (cmNonempty(val)) {
-      launcher = cmStrCat(val, ' ');
+      launcher = cmStrCat(*val, ' ');
     }
 
     std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander(
@@ -452,10 +452,10 @@
     }
 
     std::string launcher;
-    const char* val = this->GetLocalGenerator()->GetRuleLauncher(
+    cmProp val = this->GetLocalGenerator()->GetRuleLauncher(
       this->GetGeneratorTarget(), "RULE_LAUNCH_LINK");
     if (cmNonempty(val)) {
-      launcher = cmStrCat(val, ' ');
+      launcher = cmStrCat(*val, ' ');
     }
 
     std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander(
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index 76df9f2..6085b25 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -105,7 +105,7 @@
     '_', config);
 }
 
-std::string cmNinjaTargetGenerator::LanguagePreprocessRule(
+std::string cmNinjaTargetGenerator::LanguagePreprocessAndScanRule(
   std::string const& lang, const std::string& config) const
 {
   return cmStrCat(
@@ -114,7 +114,7 @@
     '_', config);
 }
 
-std::string cmNinjaTargetGenerator::LanguageDependencyRule(
+std::string cmNinjaTargetGenerator::LanguageScanRule(
   std::string const& lang, const std::string& config) const
 {
   return cmStrCat(
@@ -129,14 +129,7 @@
   return lang == "Fortran";
 }
 
-bool cmNinjaTargetGenerator::UsePreprocessedSource(
-  std::string const& lang) const
-{
-  return lang == "Fortran";
-}
-
-bool cmNinjaTargetGenerator::CompilePreprocessedSourceWithDefines(
-  std::string const& lang) const
+bool cmNinjaTargetGenerator::CompileWithDefines(std::string const& lang) const
 {
   return this->Makefile->IsOn(
     cmStrCat("CMAKE_", lang, "_COMPILE_WITH_DEFINES"));
@@ -527,82 +520,60 @@
 // Create the command to run the dependency scanner
 std::string GetScanCommand(const std::string& cmakeCmd, const std::string& tdi,
                            const std::string& lang, const std::string& ppFile,
-                           bool needDyndep, const std::string& ddiFile)
+                           const std::string& ddiFile)
 {
-  std::string ccmd =
-    cmStrCat(cmakeCmd, " -E cmake_ninja_depends --tdi=", tdi, " --lang=", lang,
-             " --pp=", ppFile, " --dep=$DEP_FILE");
-  if (needDyndep) {
-    ccmd = cmStrCat(ccmd, " --obj=$OBJ_FILE --ddi=", ddiFile);
-  }
-  return ccmd;
+  return cmStrCat(cmakeCmd, " -E cmake_ninja_depends --tdi=", tdi,
+                  " --lang=", lang, " --src=$in", " --pp=", ppFile,
+                  " --dep=$DEP_FILE --obj=$OBJ_FILE --ddi=", ddiFile);
 }
 
-// Helper function to create dependency scanning rule, with optional
-// explicit preprocessing step if preprocessCommand is non-empty
-cmNinjaRule GetPreprocessScanRule(
-  const std::string& ruleName, cmRulePlaceholderExpander::RuleVariables& vars,
+// Helper function to create dependency scanning rule that may or may
+// not perform explicit preprocessing too.
+cmNinjaRule GetScanRule(
+  const std::string& ruleName,
+  cmRulePlaceholderExpander::RuleVariables const& vars,
   const std::string& responseFlag, const std::string& flags,
-  const std::string& launcher,
   cmRulePlaceholderExpander* const rulePlaceholderExpander,
-  std::string scanCommand, cmLocalNinjaGenerator* generator,
-  const std::string& preprocessCommand = "")
+  cmLocalNinjaGenerator* generator, std::vector<std::string> scanCmds)
 {
   cmNinjaRule rule(ruleName);
-  // Explicit preprocessing always uses a depfile.
+  // Scanning always uses a depfile for preprocessor dependencies.
   rule.DepType = ""; // no deps= for multiple outputs
   rule.DepFile = "$DEP_FILE";
 
-  cmRulePlaceholderExpander::RuleVariables ppVars;
-  ppVars.CMTargetName = vars.CMTargetName;
-  ppVars.CMTargetType = vars.CMTargetType;
-  ppVars.Language = vars.Language;
-  ppVars.Object = "$out"; // for RULE_LAUNCH_COMPILE
-  ppVars.PreprocessedSource = "$out";
-  ppVars.DependencyFile = rule.DepFile.c_str();
+  cmRulePlaceholderExpander::RuleVariables scanVars;
+  scanVars.CMTargetName = vars.CMTargetName;
+  scanVars.CMTargetType = vars.CMTargetType;
+  scanVars.Language = vars.Language;
+  scanVars.Object = "$out"; // for RULE_LAUNCH_COMPILE
+  scanVars.PreprocessedSource = "$out";
+  scanVars.DependencyFile = rule.DepFile.c_str();
 
-  // Preprocessing uses the original source, compilation uses
-  // preprocessed output or original source
-  ppVars.Source = vars.Source;
-  vars.Source = "$in";
+  // Scanning needs the same preprocessor settings as direct compilation would.
+  scanVars.Source = vars.Source;
+  scanVars.Defines = vars.Defines;
+  scanVars.Includes = vars.Includes;
 
-  // Copy preprocessor definitions to the preprocessor rule.
-  ppVars.Defines = vars.Defines;
-
-  // Copy include directories to the preprocessor rule.  The Fortran
-  // compilation rule still needs them for the INCLUDE directive.
-  ppVars.Includes = vars.Includes;
-
-  // Preprocessing and compilation use the same flags.
-  std::string ppFlags = flags;
+  // Scanning needs the compilation flags too.
+  std::string scanFlags = flags;
 
   // If using a response file, move defines, includes, and flags into it.
   if (!responseFlag.empty()) {
     rule.RspFile = "$RSP_FILE";
     rule.RspContent =
-      cmStrCat(' ', ppVars.Defines, ' ', ppVars.Includes, ' ', ppFlags);
-    ppFlags = cmStrCat(responseFlag, rule.RspFile);
-    ppVars.Defines = "";
-    ppVars.Includes = "";
+      cmStrCat(' ', scanVars.Defines, ' ', scanVars.Includes, ' ', scanFlags);
+    scanFlags = cmStrCat(responseFlag, rule.RspFile);
+    scanVars.Defines = "";
+    scanVars.Includes = "";
   }
 
-  ppVars.Flags = ppFlags.c_str();
+  scanVars.Flags = scanFlags.c_str();
 
-  // Rule for preprocessing source file.
-  std::vector<std::string> ppCmds;
-
-  if (!preprocessCommand.empty()) {
-    // Lookup the explicit preprocessing rule.
-    cmExpandList(preprocessCommand, ppCmds);
-    for (std::string& i : ppCmds) {
-      i = cmStrCat(launcher, i);
-      rulePlaceholderExpander->ExpandRuleVariables(generator, i, ppVars);
-    }
+  // Rule for scanning a source file.
+  for (std::string& scanCmd : scanCmds) {
+    rulePlaceholderExpander->ExpandRuleVariables(generator, scanCmd, scanVars);
   }
-
-  // Run CMake dependency scanner on either preprocessed output or source file
-  ppCmds.emplace_back(std::move(scanCommand));
-  rule.Command = generator->BuildCommandLine(ppCmds);
+  rule.Command = generator->BuildCommandLine(scanCmds);
 
   return rule;
 }
@@ -628,11 +599,9 @@
 
   cmMakefile* mf = this->GetMakefile();
 
-  // For some cases we do an explicit preprocessor invocation.
-  bool const explicitPP = this->NeedExplicitPreprocessing(lang);
-  bool const compilePPWithDefines = this->UsePreprocessedSource(lang) &&
-    this->CompilePreprocessedSourceWithDefines(lang);
+  // For some cases we scan to dynamically discover dependencies.
   bool const needDyndep = this->NeedDyndep(lang);
+  bool const compilationPreprocesses = !this->NeedExplicitPreprocessing(lang);
 
   std::string flags = "$FLAGS";
 
@@ -655,56 +624,68 @@
     cmLocalGenerator::SHELL);
 
   std::string launcher;
-  const char* val = this->GetLocalGenerator()->GetRuleLauncher(
+  cmProp val = this->GetLocalGenerator()->GetRuleLauncher(
     this->GetGeneratorTarget(), "RULE_LAUNCH_COMPILE");
   if (cmNonempty(val)) {
-    launcher = cmStrCat(val, ' ');
+    launcher = cmStrCat(*val, ' ');
   }
 
   std::string const cmakeCmd =
     this->GetLocalGenerator()->ConvertToOutputFormat(
       cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL);
 
-  if (explicitPP) {
-    // Combined preprocessing and dependency scanning
-    const auto ppScanCommand = GetScanCommand(
-      cmakeCmd, tdi, lang, "$out", needDyndep, "$DYNDEP_INTERMEDIATE_FILE");
-    const auto ppVar = cmStrCat("CMAKE_", lang, "_PREPROCESS_SOURCE");
+  if (needDyndep) {
+    // Rule to scan dependencies of sources that need preprocessing.
+    {
+      std::vector<std::string> scanCommands;
+      std::string const& scanRuleName =
+        this->LanguagePreprocessAndScanRule(lang, config);
+      std::string const& ppCommmand = mf->GetRequiredDefinition(
+        cmStrCat("CMAKE_", lang, "_PREPROCESS_SOURCE"));
+      cmExpandList(ppCommmand, scanCommands);
+      for (std::string& i : scanCommands) {
+        i = cmStrCat(launcher, i);
+      }
+      scanCommands.emplace_back(GetScanCommand(cmakeCmd, tdi, lang, "$out",
+                                               "$DYNDEP_INTERMEDIATE_FILE"));
 
-    auto ppRule = GetPreprocessScanRule(
-      this->LanguagePreprocessRule(lang, config), vars, responseFlag, flags,
-      launcher, rulePlaceholderExpander.get(), ppScanCommand,
-      this->GetLocalGenerator(), mf->GetRequiredDefinition(ppVar));
+      auto scanRule = GetScanRule(
+        scanRuleName, vars, responseFlag, flags, rulePlaceholderExpander.get(),
+        this->GetLocalGenerator(), std::move(scanCommands));
 
-    // Write the rule for preprocessing file of the given language.
-    ppRule.Comment = cmStrCat("Rule for preprocessing ", lang, " files.");
-    ppRule.Description = cmStrCat("Building ", lang, " preprocessed $out");
+      scanRule.Comment =
+        cmStrCat("Rule for generating ", lang, " dependencies.");
+      scanRule.Description = cmStrCat("Building ", lang, " preprocessed $out");
 
-    this->GetGlobalGenerator()->AddRule(ppRule);
-
-    if (!compilePPWithDefines) {
-      // Remove preprocessor definitions from compilation step
-      vars.Defines = "";
+      this->GetGlobalGenerator()->AddRule(scanRule);
     }
 
-    // Just dependency scanning for files that have preprocessing turned off
-    const auto scanCommand =
-      GetScanCommand(cmakeCmd, tdi, lang, "$in", needDyndep, "$out");
+    {
+      // Compilation will not preprocess, so it does not need the defines
+      // unless the compiler wants them for some other purpose.
+      if (!this->CompileWithDefines(lang)) {
+        vars.Defines = "";
+      }
 
-    auto scanRule = GetPreprocessScanRule(
-      this->LanguageDependencyRule(lang, config), vars, "", flags, launcher,
-      rulePlaceholderExpander.get(), scanCommand, this->GetLocalGenerator());
+      // Rule to scan dependencies of sources that do not need preprocessing.
+      std::string const& scanRuleName = this->LanguageScanRule(lang, config);
+      std::vector<std::string> scanCommands;
+      scanCommands.emplace_back(
+        GetScanCommand(cmakeCmd, tdi, lang, "$in", "$out"));
 
-    // Write the rule for generating dependencies for the given language.
-    scanRule.Comment = cmStrCat("Rule for generating ", lang,
-                                " dependencies on non-preprocessed files.");
-    scanRule.Description =
-      cmStrCat("Generating ", lang, " dependencies for $in");
+      auto scanRule = GetScanRule(
+        scanRuleName, vars, "", flags, rulePlaceholderExpander.get(),
+        this->GetLocalGenerator(), std::move(scanCommands));
 
-    this->GetGlobalGenerator()->AddRule(scanRule);
-  }
+      // Write the rule for generating dependencies for the given language.
+      scanRule.Comment = cmStrCat("Rule for generating ", lang,
+                                  " dependencies on non-preprocessed files.");
+      scanRule.Description =
+        cmStrCat("Generating ", lang, " dependencies for $in");
 
-  if (needDyndep) {
+      this->GetGlobalGenerator()->AddRule(scanRule);
+    }
+
     // Write the rule for ninja dyndep file generation.
     cmNinjaRule rule(this->LanguageDyndepRule(lang, config));
     // Command line length is almost always limited -> use response file for
@@ -743,8 +724,8 @@
 
   // Tell ninja dependency format so all deps can be loaded into a database
   std::string cldeps;
-  if (explicitPP) {
-    // The explicit preprocessing step will handle dependency scanning.
+  if (!compilationPreprocesses) {
+    // The compiler will not do preprocessing, so it has no such dependencies.
   } else if (this->NeedDepTypeMSVC(lang)) {
     rule.DepType = "msvc";
     rule.DepFile.clear();
@@ -815,15 +796,21 @@
   }
 
   // Maybe insert an include-what-you-use runner.
-  if (!compileCmds.empty() && (lang == "C" || lang == "CXX")) {
-    std::string const iwyu_prop = cmStrCat(lang, "_INCLUDE_WHAT_YOU_USE");
-    cmProp iwyu = this->GeneratorTarget->GetProperty(iwyu_prop);
+  if (!compileCmds.empty() &&
+      (lang == "C" || lang == "CXX" || lang == "OBJC" || lang == "OBJCXX")) {
     std::string const tidy_prop = cmStrCat(lang, "_CLANG_TIDY");
     cmProp tidy = this->GeneratorTarget->GetProperty(tidy_prop);
-    std::string const cpplint_prop = cmStrCat(lang, "_CPPLINT");
-    cmProp cpplint = this->GeneratorTarget->GetProperty(cpplint_prop);
-    std::string const cppcheck_prop = cmStrCat(lang, "_CPPCHECK");
-    cmProp cppcheck = this->GeneratorTarget->GetProperty(cppcheck_prop);
+    cmProp iwyu = nullptr;
+    cmProp cpplint = nullptr;
+    cmProp cppcheck = nullptr;
+    if (lang == "C" || lang == "CXX") {
+      std::string const iwyu_prop = cmStrCat(lang, "_INCLUDE_WHAT_YOU_USE");
+      iwyu = this->GeneratorTarget->GetProperty(iwyu_prop);
+      std::string const cpplint_prop = cmStrCat(lang, "_CPPLINT");
+      cpplint = this->GeneratorTarget->GetProperty(cpplint_prop);
+      std::string const cppcheck_prop = cmStrCat(lang, "_CPPCHECK");
+      cppcheck = this->GeneratorTarget->GetProperty(cppcheck_prop);
+    }
     if (cmNonempty(iwyu) || cmNonempty(tidy) || cmNonempty(cpplint) ||
         cmNonempty(cppcheck)) {
       std::string run_iwyu = cmStrCat(cmakeCmd, " -E __run_co_compile");
@@ -1062,78 +1049,81 @@
 }
 
 namespace {
-cmNinjaBuild GetPreprocessOrScanBuild(
-  const std::string& ruleName, const std::string& ppFileName, bool compilePP,
-  bool compilePPWithDefines, cmNinjaBuild& objBuild, cmNinjaVars& vars,
-  const std::string& depFileName, bool needDyndep,
-  const std::string& objectFileName)
+cmNinjaBuild GetScanBuildStatement(const std::string& ruleName,
+                                   const std::string& ppFileName,
+                                   bool compilePP, bool compilePPWithDefines,
+                                   cmNinjaBuild& objBuild, cmNinjaVars& vars,
+                                   const std::string& objectFileName,
+                                   cmLocalGenerator* lg)
 {
-  // Explicit preprocessing and dependency
-  cmNinjaBuild ppBuild(ruleName);
+  cmNinjaBuild scanBuild(ruleName);
 
   if (!ppFileName.empty()) {
-    ppBuild.Outputs.push_back(ppFileName);
-    ppBuild.RspFile = cmStrCat(ppFileName, ".rsp");
+    scanBuild.RspFile = cmStrCat(ppFileName, ".rsp");
   } else {
-    ppBuild.RspFile = "$out.rsp";
+    scanBuild.RspFile = "$out.rsp";
   }
 
   if (compilePP) {
-    // Move compilation dependencies to the preprocessing build statement.
-    std::swap(ppBuild.ExplicitDeps, objBuild.ExplicitDeps);
-    std::swap(ppBuild.ImplicitDeps, objBuild.ImplicitDeps);
-    std::swap(ppBuild.OrderOnlyDeps, objBuild.OrderOnlyDeps);
-    std::swap(ppBuild.Variables["IN_ABS"], vars["IN_ABS"]);
+    // Move compilation dependencies to the scan/preprocessing build statement.
+    std::swap(scanBuild.ExplicitDeps, objBuild.ExplicitDeps);
+    std::swap(scanBuild.ImplicitDeps, objBuild.ImplicitDeps);
+    std::swap(scanBuild.OrderOnlyDeps, objBuild.OrderOnlyDeps);
+    std::swap(scanBuild.Variables["IN_ABS"], vars["IN_ABS"]);
 
     // The actual compilation will now use the preprocessed source.
     objBuild.ExplicitDeps.push_back(ppFileName);
   } else {
-    // Copy compilation dependencies to the preprocessing build statement.
-    ppBuild.ExplicitDeps = objBuild.ExplicitDeps;
-    ppBuild.ImplicitDeps = objBuild.ImplicitDeps;
-    ppBuild.OrderOnlyDeps = objBuild.OrderOnlyDeps;
-    ppBuild.Variables["IN_ABS"] = vars["IN_ABS"];
+    // Copy compilation dependencies to the scan/preprocessing build statement.
+    scanBuild.ExplicitDeps = objBuild.ExplicitDeps;
+    scanBuild.ImplicitDeps = objBuild.ImplicitDeps;
+    scanBuild.OrderOnlyDeps = objBuild.OrderOnlyDeps;
+    scanBuild.Variables["IN_ABS"] = vars["IN_ABS"];
   }
 
-  // Preprocessing and compilation generally use the same flags.
-  ppBuild.Variables["FLAGS"] = vars["FLAGS"];
+  // Scanning and compilation generally use the same flags.
+  scanBuild.Variables["FLAGS"] = vars["FLAGS"];
 
   if (compilePP && !compilePPWithDefines) {
-    // Move preprocessor definitions to the preprocessor build statement.
-    std::swap(ppBuild.Variables["DEFINES"], vars["DEFINES"]);
+    // Move preprocessor definitions to the scan/preprocessor build statement.
+    std::swap(scanBuild.Variables["DEFINES"], vars["DEFINES"]);
   } else {
-    // Copy preprocessor definitions to the preprocessor build statement.
-    ppBuild.Variables["DEFINES"] = vars["DEFINES"];
+    // Copy preprocessor definitions to the scan/preprocessor build statement.
+    scanBuild.Variables["DEFINES"] = vars["DEFINES"];
   }
 
   // Copy include directories to the preprocessor build statement.  The
   // Fortran compilation build statement still needs them for the INCLUDE
   // directive.
-  ppBuild.Variables["INCLUDES"] = vars["INCLUDES"];
+  scanBuild.Variables["INCLUDES"] = vars["INCLUDES"];
 
-  // Explicit preprocessing always uses a depfile.
-  ppBuild.Variables["DEP_FILE"] = depFileName;
+  // Tell dependency scanner the object file that will result from
+  // compiling the source.
+  scanBuild.Variables["OBJ_FILE"] = objectFileName;
+
+  // Tell dependency scanner where to store dyndep intermediate results.
+  std::string const& ddiFile = cmStrCat(objectFileName, ".ddi");
+  scanBuild.Variables["DYNDEP_INTERMEDIATE_FILE"] = ddiFile;
+
+  // Outputs of the scan/preprocessor build statement.
+  if (!ppFileName.empty()) {
+    scanBuild.Outputs.push_back(ppFileName);
+    scanBuild.ImplicitOuts.push_back(ddiFile);
+  } else {
+    scanBuild.Outputs.push_back(ddiFile);
+  }
+
+  // Scanning always uses a depfile for preprocessor dependencies.
+  std::string const& depFileName = cmStrCat(scanBuild.Outputs.front(), ".d");
+  scanBuild.Variables["DEP_FILE"] =
+    lg->ConvertToOutputFormat(depFileName, cmOutputConverter::SHELL);
   if (compilePP) {
     // The actual compilation does not need a depfile because it
     // depends on the already-preprocessed source.
     vars.erase("DEP_FILE");
   }
 
-  if (needDyndep) {
-    // Tell dependency scanner the object file that will result from
-    // compiling the source.
-    ppBuild.Variables["OBJ_FILE"] = objectFileName;
-
-    // Tell dependency scanner where to store dyndep intermediate results.
-    std::string const ddiFile = cmStrCat(objectFileName, ".ddi");
-    if (ppFileName.empty()) {
-      ppBuild.Outputs.push_back(ddiFile);
-    } else {
-      ppBuild.Variables["DYNDEP_INTERMEDIATE_FILE"] = ddiFile;
-      ppBuild.ImplicitOuts.push_back(ddiFile);
-    }
-  }
-  return ppBuild;
+  return scanBuild;
 }
 }
 
@@ -1270,13 +1260,12 @@
       sourceFileName, objBuild.OrderOnlyDeps);
   }
 
-  // For some cases we need to generate a ninja dyndep file.
+  // For some cases we scan to dynamically discover dependencies.
   bool const needDyndep = this->NeedDyndep(language);
+  bool const compilationPreprocesses =
+    !this->NeedExplicitPreprocessing(language);
 
-  // For some cases we do an explicit preprocessor invocation.
-  bool const explicitPP = this->NeedExplicitPreprocessing(language);
-  if (explicitPP) {
-
+  if (needDyndep) {
     // If source/target has preprocessing turned off, we still need to
     // generate an explicit dependency step
     const auto srcpp = source->GetSafeProperty("Fortran_PREPROCESS");
@@ -1288,27 +1277,24 @@
       preprocess = cmOutputConverter::GetFortranPreprocess(tgtpp);
     }
 
-    bool const compilePP = this->UsePreprocessedSource(language) &&
+    bool const compilePP = !compilationPreprocesses &&
       (preprocess != cmOutputConverter::FortranPreprocess::NotNeeded);
     bool const compilePPWithDefines =
-      compilePP && this->CompilePreprocessedSourceWithDefines(language);
+      compilePP && this->CompileWithDefines(language);
 
-    std::string const ppFileName = compilePP
-      ? this->ConvertToNinjaPath(this->GetPreprocessedFilePath(source, config))
-      : "";
+    std::string scanRuleName;
+    std::string ppFileName;
+    if (compilePP) {
+      scanRuleName = this->LanguagePreprocessAndScanRule(language, config);
+      ppFileName = this->ConvertToNinjaPath(
+        this->GetPreprocessedFilePath(source, config));
+    } else {
+      scanRuleName = this->LanguageScanRule(language, config);
+    }
 
-    std::string const buildName = compilePP
-      ? this->LanguagePreprocessRule(language, config)
-      : this->LanguageDependencyRule(language, config);
-
-    const auto depExtension = compilePP ? ".pp.d" : ".d";
-    const std::string depFileName =
-      this->GetLocalGenerator()->ConvertToOutputFormat(
-        cmStrCat(objectFileName, depExtension), cmOutputConverter::SHELL);
-
-    cmNinjaBuild ppBuild = GetPreprocessOrScanBuild(
-      buildName, ppFileName, compilePP, compilePPWithDefines, objBuild, vars,
-      depFileName, needDyndep, objectFileName);
+    cmNinjaBuild ppBuild = GetScanBuildStatement(
+      scanRuleName, ppFileName, compilePP, compilePPWithDefines, objBuild,
+      vars, objectFileName, this->LocalGenerator);
 
     if (compilePP) {
       // In case compilation requires flags that are incompatible with
@@ -1330,7 +1316,7 @@
       vars["INCLUDES"] = cmStrCat(sourceDirectoryFlag, ' ', vars["INCLUDES"]);
     }
 
-    if (firstForConfig && needDyndep) {
+    if (firstForConfig) {
       std::string const ddiFile = cmStrCat(objectFileName, ".ddi");
       this->Configs[config].DDIFiles[language].push_back(ddiFile);
     }
@@ -1340,8 +1326,7 @@
 
     this->GetGlobalGenerator()->WriteBuild(this->GetImplFileStream(fileConfig),
                                            ppBuild, commandLineLengthLimit);
-  }
-  if (needDyndep) {
+
     std::string const dyndep = this->GetDyndepFilePath(language, config);
     objBuild.OrderOnlyDeps.push_back(dyndep);
     vars["dyndep"] = dyndep;
diff --git a/Source/cmNinjaTargetGenerator.h b/Source/cmNinjaTargetGenerator.h
index a27c9b4..4ba37ad 100644
--- a/Source/cmNinjaTargetGenerator.h
+++ b/Source/cmNinjaTargetGenerator.h
@@ -67,16 +67,15 @@
 
   std::string LanguageCompilerRule(const std::string& lang,
                                    const std::string& config) const;
-  std::string LanguagePreprocessRule(std::string const& lang,
-                                     const std::string& config) const;
-  std::string LanguageDependencyRule(std::string const& lang,
-                                     const std::string& config) const;
-  bool NeedExplicitPreprocessing(std::string const& lang) const;
+  std::string LanguagePreprocessAndScanRule(std::string const& lang,
+                                            const std::string& config) const;
+  std::string LanguageScanRule(std::string const& lang,
+                               const std::string& config) const;
   std::string LanguageDyndepRule(std::string const& lang,
                                  const std::string& config) const;
   bool NeedDyndep(std::string const& lang) const;
-  bool UsePreprocessedSource(std::string const& lang) const;
-  bool CompilePreprocessedSourceWithDefines(std::string const& lang) const;
+  bool NeedExplicitPreprocessing(std::string const& lang) const;
+  bool CompileWithDefines(std::string const& lang) const;
 
   std::string OrderDependsTargetForTarget(const std::string& config);
 
diff --git a/Source/cmPipeConnection.cxx b/Source/cmPipeConnection.cxx
deleted file mode 100644
index 1eede13..0000000
--- a/Source/cmPipeConnection.cxx
+++ /dev/null
@@ -1,71 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
-   file Copyright.txt or https://cmake.org/licensing for details.  */
-#include "cmPipeConnection.h"
-
-#include <utility>
-
-#include "cmServer.h"
-
-cmPipeConnection::cmPipeConnection(std::string name,
-                                   cmConnectionBufferStrategy* bufferStrategy)
-  : cmEventBasedConnection(bufferStrategy)
-  , PipeName(std::move(name))
-{
-}
-
-void cmPipeConnection::Connect(uv_stream_t* server)
-{
-  if (this->WriteStream.get()) {
-    // Accept and close all pipes but the first:
-    cm::uv_pipe_ptr rejectPipe;
-
-    rejectPipe.init(*this->Server->GetLoop(), 0);
-    uv_accept(server, rejectPipe);
-
-    return;
-  }
-
-  cm::uv_pipe_ptr ClientPipe;
-  ClientPipe.init(*this->Server->GetLoop(), 0,
-                  static_cast<cmEventBasedConnection*>(this));
-
-  if (uv_accept(server, ClientPipe) != 0) {
-    return;
-  }
-
-  uv_read_start(ClientPipe, on_alloc_buffer, on_read);
-  WriteStream = std::move(ClientPipe);
-  Server->OnConnected(this);
-}
-
-bool cmPipeConnection::OnServeStart(std::string* errorMessage)
-{
-  this->ServerPipe.init(*this->Server->GetLoop(), 0,
-                        static_cast<cmEventBasedConnection*>(this));
-
-  int r;
-  if ((r = uv_pipe_bind(this->ServerPipe, this->PipeName.c_str())) != 0) {
-    *errorMessage = std::string("Internal Error with ") + this->PipeName +
-      ": " + uv_err_name(r);
-    return false;
-  }
-
-  if ((r = uv_listen(this->ServerPipe, 1, on_new_connection)) != 0) {
-    *errorMessage = std::string("Internal Error listening on ") +
-      this->PipeName + ": " + uv_err_name(r);
-    return false;
-  }
-
-  return cmConnection::OnServeStart(errorMessage);
-}
-
-bool cmPipeConnection::OnConnectionShuttingDown()
-{
-  if (this->WriteStream.get()) {
-    this->WriteStream->data = nullptr;
-  }
-
-  this->ServerPipe.reset();
-
-  return cmEventBasedConnection::OnConnectionShuttingDown();
-}
diff --git a/Source/cmPipeConnection.h b/Source/cmPipeConnection.h
deleted file mode 100644
index 1215716..0000000
--- a/Source/cmPipeConnection.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
-   file Copyright.txt or https://cmake.org/licensing for details.  */
-#pragma once
-
-#include "cmConfigure.h" // IWYU pragma: keep
-
-#include <string>
-
-#include <cm3p/uv.h>
-
-#include "cmConnection.h"
-#include "cmUVHandlePtr.h"
-
-class cmPipeConnection : public cmEventBasedConnection
-{
-public:
-  cmPipeConnection(std::string name,
-                   cmConnectionBufferStrategy* bufferStrategy = nullptr);
-
-  bool OnServeStart(std::string* pString) override;
-
-  bool OnConnectionShuttingDown() override;
-
-  void Connect(uv_stream_t* server) override;
-
-private:
-  const std::string PipeName;
-  cm::uv_pipe_ptr ServerPipe;
-};
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index 18ce9c3..30cd4b7 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -340,7 +340,15 @@
          3, 19, 0, cmPolicies::WARN)                                          \
   SELECT(POLICY, CMP0114,                                                     \
          "ExternalProject step targets fully adopt their steps.", 3, 19, 0,   \
-         cmPolicies::WARN)
+         cmPolicies::WARN)                                                    \
+  SELECT(POLICY, CMP0115, "Source file extensions must be explicit.", 3, 20,  \
+         0, cmPolicies::WARN)                                                 \
+  SELECT(POLICY, CMP0116,                                                     \
+         "Ninja generators transform DEPFILEs from add_custom_command().", 3, \
+         20, 0, cmPolicies::WARN)                                             \
+  SELECT(POLICY, CMP0117,                                                     \
+         "MSVC RTTI flag /GR is not added to CMAKE_CXX_FLAGS by default.", 3, \
+         20, 0, cmPolicies::WARN)
 
 #define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
 #define CM_FOR_EACH_POLICY_ID(POLICY)                                         \
diff --git a/Source/cmProjectCommand.cxx b/Source/cmProjectCommand.cxx
index 0cfba63..ed32de9 100644
--- a/Source/cmProjectCommand.cxx
+++ b/Source/cmProjectCommand.cxx
@@ -358,6 +358,17 @@
     return true;
   }
 
+  std::string includeFile =
+    cmSystemTools::CollapseFullPath(*include, mf.GetCurrentSourceDirectory());
+  if (!cmSystemTools::FileExists(includeFile)) {
+    status.SetError(cmStrCat("could not find requested file:\n  ", *include));
+    return false;
+  }
+  if (cmSystemTools::FileIsDirectory(includeFile)) {
+    status.SetError(cmStrCat("requested file is a directory:\n  ", *include));
+    return false;
+  }
+
   const bool readit = mf.ReadDependentFile(*include);
   if (readit) {
     return true;
@@ -367,7 +378,7 @@
     return true;
   }
 
-  status.SetError(cmStrCat("could not find file:\n  ", *include));
+  status.SetError(cmStrCat("could not load requested file:\n  ", *include));
   return false;
 }
 
diff --git a/Source/cmQTWrapCPPCommand.cxx b/Source/cmQTWrapCPPCommand.cxx
index de462db..e058176 100644
--- a/Source/cmQTWrapCPPCommand.cxx
+++ b/Source/cmQTWrapCPPCommand.cxx
@@ -40,8 +40,7 @@
         cmStrCat(mf.GetCurrentBinaryDirectory(), "/moc_", srcName, ".cxx");
       cmSourceFile* sf = mf.GetOrCreateSource(newName, true);
       if (curr) {
-        cmProp p = curr->GetProperty("ABSTRACT");
-        sf->SetProperty("ABSTRACT", cmToCStr(p));
+        sf->SetProperty("ABSTRACT", cmToCStr(curr->GetProperty("ABSTRACT")));
       }
 
       // Compute the name of the header from which to generate the file.
diff --git a/Source/cmQtAutoGen.h b/Source/cmQtAutoGen.h
index cf90417..2db1b84 100644
--- a/Source/cmQtAutoGen.h
+++ b/Source/cmQtAutoGen.h
@@ -29,13 +29,13 @@
     {
     }
 
-    bool operator>(IntegerVersion const version)
+    bool operator>(IntegerVersion const version) const
     {
       return (this->Major > version.Major) ||
         ((this->Major == version.Major) && (this->Minor > version.Minor));
     }
 
-    bool operator>=(IntegerVersion const version)
+    bool operator>=(IntegerVersion const version) const
     {
       return (this->Major > version.Major) ||
         ((this->Major == version.Major) && (this->Minor >= version.Minor));
diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx
index 3b62e9c..f2696a6 100644
--- a/Source/cmQtAutoGenInitializer.cxx
+++ b/Source/cmQtAutoGenInitializer.cxx
@@ -807,7 +807,7 @@
           qrc.Generated = sf->GetIsGenerated();
           // RCC options
           {
-            std::string const opts = sf->GetSafeProperty(kw.AUTORCC_OPTIONS);
+            std::string const& opts = sf->GetSafeProperty(kw.AUTORCC_OPTIONS);
             if (!opts.empty()) {
               cmExpandList(opts, qrc.Options);
             }
diff --git a/Source/cmQtAutoMocUic.cxx b/Source/cmQtAutoMocUic.cxx
index 9cb172b..b27bb88 100644
--- a/Source/cmQtAutoMocUic.cxx
+++ b/Source/cmQtAutoMocUic.cxx
@@ -15,6 +15,7 @@
 #include <vector>
 
 #include <cm/memory>
+#include <cm/optional>
 #include <cm/string_view>
 #include <cmext/algorithm>
 
@@ -26,7 +27,6 @@
 #include "cmCryptoHash.h"
 #include "cmFileTime.h"
 #include "cmGccDepfileReader.h"
-#include "cmGccDepfileReaderTypes.h"
 #include "cmGeneratedFileStream.h"
 #include "cmQtAutoGen.h"
 #include "cmQtAutoGenerator.h"
@@ -2841,14 +2841,14 @@
 std::vector<std::string> cmQtAutoMocUicT::dependenciesFromDepFile(
   const char* filePath)
 {
-  cmGccDepfileContent content = cmReadGccDepfile(filePath);
-  if (content.empty()) {
+  auto const content = cmReadGccDepfile(filePath);
+  if (!content || content->empty()) {
     return {};
   }
 
   // Moc outputs a depfile with exactly one rule.
   // Discard the rule and return the dependencies.
-  return content.front().paths;
+  return content->front().paths;
 }
 
 void cmQtAutoMocUicT::Abort(bool error)
diff --git a/Source/cmScanDepFormat.cxx b/Source/cmScanDepFormat.cxx
new file mode 100644
index 0000000..40bf4c9
--- /dev/null
+++ b/Source/cmScanDepFormat.cxx
@@ -0,0 +1,267 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file Copyright.txt or https://cmake.org/licensing for details.  */
+
+#include "cmScanDepFormat.h"
+
+#include <cctype>
+#include <cstdio>
+
+#include <cm3p/json/reader.h>
+#include <cm3p/json/value.h>
+#include <cm3p/json/writer.h>
+
+#include "cmsys/FStream.hxx"
+
+#include "cmGeneratedFileStream.h"
+#include "cmStringAlgorithms.h"
+#include "cmSystemTools.h"
+
+static bool ParseFilename(Json::Value const& val, std::string& result)
+{
+  if (val.isString()) {
+    result = val.asString();
+  } else {
+    return false;
+  }
+
+  return true;
+}
+
+static Json::Value EncodeFilename(std::string const& path)
+{
+  std::string data;
+  data.reserve(path.size());
+
+  for (auto const& byte : path) {
+    if (std::iscntrl(byte)) {
+      // Control characters.
+      data.append("\\u");
+      char buf[5];
+      std::snprintf(buf, sizeof(buf), "%04x", byte);
+      data.append(buf);
+    } else if (byte == '"' || byte == '\\') {
+      // Special JSON characters.
+      data.push_back('\\');
+      data.push_back(byte);
+    } else {
+      // Other data.
+      data.push_back(byte);
+    }
+  }
+
+  return data;
+}
+
+#define PARSE_BLOB(val, res)                                                  \
+  do {                                                                        \
+    if (!ParseFilename(val, res)) {                                           \
+      cmSystemTools::Error(                                                   \
+        cmStrCat("-E cmake_ninja_depends failed to parse ", arg_pp,           \
+                 ": invalid blob"));                                          \
+      return false;                                                           \
+    }                                                                         \
+  } while (0)
+
+#define PARSE_FILENAME(val, res)                                              \
+  do {                                                                        \
+    if (!ParseFilename(val, res)) {                                           \
+      cmSystemTools::Error(                                                   \
+        cmStrCat("-E cmake_ninja_depends failed to parse ", arg_pp,           \
+                 ": invalid filename"));                                      \
+      return false;                                                           \
+    }                                                                         \
+                                                                              \
+    if (!cmSystemTools::FileIsFullPath(res)) {                                \
+      res = cmStrCat(work_directory, '/', res);                               \
+    }                                                                         \
+  } while (0)
+
+bool cmScanDepFormat_P1689_Parse(std::string const& arg_pp, cmSourceInfo* info)
+{
+  Json::Value ppio;
+  Json::Value const& ppi = ppio;
+  cmsys::ifstream ppf(arg_pp.c_str(), std::ios::in | std::ios::binary);
+  {
+    Json::Reader reader;
+    if (!reader.parse(ppf, ppio, false)) {
+      cmSystemTools::Error(cmStrCat("-E cmake_ninja_depends failed to parse ",
+                                    arg_pp,
+                                    reader.getFormattedErrorMessages()));
+      return false;
+    }
+  }
+
+  Json::Value const& version = ppi["version"];
+  if (version.asUInt() != 0) {
+    cmSystemTools::Error(cmStrCat("-E cmake_ninja_depends failed to parse ",
+                                  arg_pp, ": version ", version.asString()));
+    return false;
+  }
+
+  Json::Value const& rules = ppi["rules"];
+  if (rules.isArray()) {
+    if (rules.size() != 1) {
+      cmSystemTools::Error(cmStrCat("-E cmake_ninja_depends failed to parse ",
+                                    arg_pp, ": expected 1 source entry"));
+      return false;
+    }
+
+    for (auto const& rule : rules) {
+      Json::Value const& workdir = rule["work-directory"];
+      if (!workdir.isString()) {
+        cmSystemTools::Error(
+          cmStrCat("-E cmake_ninja_depends failed to parse ", arg_pp,
+                   ": work-directory is not a string"));
+        return false;
+      }
+      std::string work_directory;
+      PARSE_BLOB(workdir, work_directory);
+
+      Json::Value const& depends = rule["depends"];
+      if (depends.isArray()) {
+        std::string depend_filename;
+        for (auto const& depend : depends) {
+          PARSE_FILENAME(depend, depend_filename);
+          info->Includes.push_back(depend_filename);
+        }
+      }
+
+      if (rule.isMember("future-compile")) {
+        Json::Value const& future_compile = rule["future-compile"];
+
+        if (future_compile.isMember("outputs")) {
+          Json::Value const& outputs = future_compile["outputs"];
+          if (outputs.isArray()) {
+            if (outputs.empty()) {
+              cmSystemTools::Error(
+                cmStrCat("-E cmake_ninja_depends failed to parse ", arg_pp,
+                         ": expected at least one 1 output"));
+              return false;
+            }
+
+            PARSE_FILENAME(outputs[0], info->PrimaryOutput);
+          }
+        }
+
+        if (future_compile.isMember("provides")) {
+          Json::Value const& provides = future_compile["provides"];
+          if (provides.isArray()) {
+            for (auto const& provide : provides) {
+              cmSourceReqInfo provide_info;
+
+              Json::Value const& logical_name = provide["logical-name"];
+              PARSE_BLOB(logical_name, provide_info.LogicalName);
+
+              if (provide.isMember("compiled-module-path")) {
+                Json::Value const& compiled_module_path =
+                  provide["compiled-module-path"];
+                PARSE_FILENAME(compiled_module_path,
+                               provide_info.CompiledModulePath);
+              } else {
+                provide_info.CompiledModulePath =
+                  cmStrCat(provide_info.LogicalName, ".mod");
+              }
+
+              info->Provides.push_back(provide_info);
+            }
+          }
+        }
+
+        if (future_compile.isMember("requires")) {
+          Json::Value const& reqs = future_compile["requires"];
+          if (reqs.isArray()) {
+            for (auto const& require : reqs) {
+              cmSourceReqInfo require_info;
+
+              Json::Value const& logical_name = require["logical-name"];
+              PARSE_BLOB(logical_name, require_info.LogicalName);
+
+              if (require.isMember("compiled-module-path")) {
+                Json::Value const& compiled_module_path =
+                  require["compiled-module-path"];
+                PARSE_FILENAME(compiled_module_path,
+                               require_info.CompiledModulePath);
+              }
+
+              info->Requires.push_back(require_info);
+            }
+          }
+        }
+      }
+    }
+  }
+
+  return true;
+}
+
+bool cmScanDepFormat_P1689_Write(std::string const& path,
+                                 std::string const& input,
+                                 cmSourceInfo const& info)
+{
+  Json::Value ddi(Json::objectValue);
+  ddi["version"] = 0;
+  ddi["revision"] = 0;
+
+  Json::Value& rules = ddi["rules"] = Json::arrayValue;
+
+  Json::Value rule(Json::objectValue);
+  rule["work-directory"] =
+    EncodeFilename(cmSystemTools::GetCurrentWorkingDirectory());
+  Json::Value& inputs = rule["inputs"] = Json::arrayValue;
+  inputs.append(EncodeFilename(input));
+
+  Json::Value& rule_outputs = rule["outputs"] = Json::arrayValue;
+  rule_outputs.append(EncodeFilename(path));
+
+  Json::Value& depends = rule["depends"] = Json::arrayValue;
+  for (auto const& include : info.Includes) {
+    depends.append(EncodeFilename(include));
+  }
+
+  Json::Value& future_compile = rule["future-compile"] = Json::objectValue;
+
+  Json::Value& outputs = future_compile["outputs"] = Json::arrayValue;
+  outputs.append(info.PrimaryOutput);
+
+  Json::Value& provides = future_compile["provides"] = Json::arrayValue;
+  for (auto const& provide : info.Provides) {
+    Json::Value provide_obj(Json::objectValue);
+    auto const encoded = EncodeFilename(provide.LogicalName);
+    provide_obj["logical-name"] = encoded;
+    if (provide.CompiledModulePath.empty()) {
+      provide_obj["compiled-module-path"] = encoded;
+    } else {
+      provide_obj["compiled-module-path"] =
+        EncodeFilename(provide.CompiledModulePath);
+    }
+
+    // TODO: Source file tracking. See below.
+
+    provides.append(provide_obj);
+  }
+
+  Json::Value& reqs = future_compile["requires"] = Json::arrayValue;
+  for (auto const& require : info.Requires) {
+    Json::Value require_obj(Json::objectValue);
+    auto const encoded = EncodeFilename(require.LogicalName);
+    require_obj["logical-name"] = encoded;
+    if (require.CompiledModulePath.empty()) {
+      require_obj["compiled-module-path"] = encoded;
+    } else {
+      require_obj["compiled-module-path"] =
+        EncodeFilename(require.CompiledModulePath);
+    }
+
+    // TODO: Source filename inclusion. Requires collating with the provides
+    // filenames (as a sanity check if available on both sides).
+
+    reqs.append(require_obj);
+  }
+
+  rules.append(rule);
+
+  cmGeneratedFileStream ddif(path);
+  ddif << ddi;
+
+  return !!ddif;
+}
diff --git a/Source/cmScanDepFormat.h b/Source/cmScanDepFormat.h
new file mode 100644
index 0000000..1ad0ecf
--- /dev/null
+++ b/Source/cmScanDepFormat.h
@@ -0,0 +1,30 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file Copyright.txt or https://cmake.org/licensing for details.  */
+#pragma once
+
+#include <string>
+#include <vector>
+
+struct cmSourceReqInfo
+{
+  std::string LogicalName;
+  std::string CompiledModulePath;
+};
+
+struct cmSourceInfo
+{
+  std::string PrimaryOutput;
+
+  // Set of provided and required modules.
+  std::vector<cmSourceReqInfo> Provides;
+  std::vector<cmSourceReqInfo> Requires;
+
+  // Set of files included in the translation unit.
+  std::vector<std::string> Includes;
+};
+
+bool cmScanDepFormat_P1689_Parse(std::string const& arg_pp,
+                                 cmSourceInfo* info);
+bool cmScanDepFormat_P1689_Write(std::string const& path,
+                                 std::string const& input,
+                                 cmSourceInfo const& info);
diff --git a/Source/cmServer.cxx b/Source/cmServer.cxx
deleted file mode 100644
index 7f97406..0000000
--- a/Source/cmServer.cxx
+++ /dev/null
@@ -1,570 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
-   file Copyright.txt or https://cmake.org/licensing for details.  */
-#include "cmServer.h"
-
-#include <algorithm>
-#include <cassert>
-#include <csignal>
-#include <cstdint>
-#include <iostream>
-#include <mutex>
-#include <utility>
-
-#include <cm/memory>
-#include <cm/shared_mutex>
-
-#include <cm3p/json/reader.h>
-#include <cm3p/json/writer.h>
-
-#include "cmsys/FStream.hxx"
-
-#include "cmConnection.h"
-#include "cmFileMonitor.h"
-#include "cmJsonObjectDictionary.h"
-#include "cmServerDictionary.h"
-#include "cmServerProtocol.h"
-#include "cmSystemTools.h"
-#include "cmake.h"
-
-void on_signal(uv_signal_t* signal, int signum)
-{
-  auto conn = static_cast<cmServerBase*>(signal->data);
-  conn->OnSignal(signum);
-}
-
-static void on_walk_to_shutdown(uv_handle_t* handle, void* arg)
-{
-  (void)arg;
-  assert(uv_is_closing(handle));
-  if (!uv_is_closing(handle)) {
-    uv_close(handle, &cmEventBasedConnection::on_close);
-  }
-}
-
-class cmServer::DebugInfo
-{
-public:
-  DebugInfo()
-    : StartTime(uv_hrtime())
-  {
-  }
-
-  bool PrintStatistics = false;
-
-  std::string OutputFile;
-  uint64_t StartTime;
-};
-
-cmServer::cmServer(cmConnection* conn, bool supportExperimental)
-  : cmServerBase(conn)
-  , SupportExperimental(supportExperimental)
-{
-  // Register supported protocols:
-  this->RegisterProtocol(cm::make_unique<cmServerProtocol1>());
-}
-
-cmServer::~cmServer()
-{
-  Close();
-}
-
-void cmServer::ProcessRequest(cmConnection* connection,
-                              const std::string& input)
-{
-  Json::Reader reader;
-  Json::Value value;
-  if (!reader.parse(input, value)) {
-    this->WriteParseError(connection, "Failed to parse JSON input.");
-    return;
-  }
-
-  std::unique_ptr<DebugInfo> debug;
-  Json::Value debugValue = value["debug"];
-  if (!debugValue.isNull()) {
-    debug = cm::make_unique<DebugInfo>();
-    debug->OutputFile = debugValue["dumpToFile"].asString();
-    debug->PrintStatistics = debugValue["showStats"].asBool();
-  }
-
-  const cmServerRequest request(this, connection, value[kTYPE_KEY].asString(),
-                                value[kCOOKIE_KEY].asString(), value);
-
-  if (request.Type.empty()) {
-    cmServerResponse response(request);
-    response.SetError("No type given in request.");
-    this->WriteResponse(connection, response, nullptr);
-    return;
-  }
-
-  cmSystemTools::SetMessageCallback(
-    [&request](const std::string& msg, const char* title) {
-      reportMessage(msg, title, request);
-    });
-
-  if (this->Protocol) {
-    this->Protocol->CMakeInstance()->SetProgressCallback(
-      [&request](const std::string& msg, float prog) {
-        reportProgress(msg, prog, request);
-      });
-    this->WriteResponse(connection, this->Protocol->Process(request),
-                        debug.get());
-  } else {
-    this->WriteResponse(connection, this->SetProtocolVersion(request),
-                        debug.get());
-  }
-}
-
-void cmServer::RegisterProtocol(std::unique_ptr<cmServerProtocol> protocol)
-{
-  if (protocol->IsExperimental() && !this->SupportExperimental) {
-    protocol.reset();
-    return;
-  }
-  auto version = protocol->ProtocolVersion();
-  assert(version.first >= 0);
-  assert(version.second >= 0);
-  auto it = std::find_if(
-    this->SupportedProtocols.begin(), this->SupportedProtocols.end(),
-    [version](const std::unique_ptr<cmServerProtocol>& p) {
-      return p->ProtocolVersion() == version;
-    });
-  if (it == this->SupportedProtocols.end()) {
-    this->SupportedProtocols.push_back(std::move(protocol));
-  }
-}
-
-void cmServer::PrintHello(cmConnection* connection) const
-{
-  Json::Value hello = Json::objectValue;
-  hello[kTYPE_KEY] = "hello";
-
-  Json::Value& protocolVersions = hello[kSUPPORTED_PROTOCOL_VERSIONS] =
-    Json::arrayValue;
-
-  for (auto const& proto : this->SupportedProtocols) {
-    auto version = proto->ProtocolVersion();
-    Json::Value tmp = Json::objectValue;
-    tmp[kMAJOR_KEY] = version.first;
-    tmp[kMINOR_KEY] = version.second;
-    if (proto->IsExperimental()) {
-      tmp[kIS_EXPERIMENTAL_KEY] = true;
-    }
-    protocolVersions.append(tmp);
-  }
-
-  this->WriteJsonObject(connection, hello, nullptr);
-}
-
-void cmServer::reportProgress(const std::string& msg, float progress,
-                              const cmServerRequest& request)
-{
-  if (progress < 0.0f || progress > 1.0f) {
-    request.ReportMessage(msg, "");
-  } else {
-    request.ReportProgress(0, static_cast<int>(progress * 1000), 1000, msg);
-  }
-}
-
-void cmServer::reportMessage(const std::string& msg, const char* title,
-                             const cmServerRequest& request)
-{
-  std::string titleString;
-  if (title) {
-    titleString = title;
-  }
-  request.ReportMessage(msg, titleString);
-}
-
-cmServerResponse cmServer::SetProtocolVersion(const cmServerRequest& request)
-{
-  if (request.Type != kHANDSHAKE_TYPE) {
-    return request.ReportError("Waiting for type \"" + kHANDSHAKE_TYPE +
-                               "\".");
-  }
-
-  Json::Value requestedProtocolVersion = request.Data[kPROTOCOL_VERSION_KEY];
-  if (requestedProtocolVersion.isNull()) {
-    return request.ReportError("\"" + kPROTOCOL_VERSION_KEY +
-                               "\" is required for \"" + kHANDSHAKE_TYPE +
-                               "\".");
-  }
-
-  if (!requestedProtocolVersion.isObject()) {
-    return request.ReportError("\"" + kPROTOCOL_VERSION_KEY +
-                               "\" must be a JSON object.");
-  }
-
-  Json::Value majorValue = requestedProtocolVersion[kMAJOR_KEY];
-  if (!majorValue.isInt()) {
-    return request.ReportError("\"" + kMAJOR_KEY +
-                               "\" must be set and an integer.");
-  }
-
-  Json::Value minorValue = requestedProtocolVersion[kMINOR_KEY];
-  if (!minorValue.isNull() && !minorValue.isInt()) {
-    return request.ReportError("\"" + kMINOR_KEY +
-                               "\" must be unset or an integer.");
-  }
-
-  const int major = majorValue.asInt();
-  const int minor = minorValue.isNull() ? -1 : minorValue.asInt();
-  if (major < 0) {
-    return request.ReportError("\"" + kMAJOR_KEY + "\" must be >= 0.");
-  }
-  if (!minorValue.isNull() && minor < 0) {
-    return request.ReportError("\"" + kMINOR_KEY +
-                               "\" must be >= 0 when set.");
-  }
-
-  this->Protocol =
-    cmServer::FindMatchingProtocol(this->SupportedProtocols, major, minor);
-  if (!this->Protocol) {
-    return request.ReportError("Protocol version not supported.");
-  }
-
-  std::string errorMessage;
-  if (!this->Protocol->Activate(this, request, &errorMessage)) {
-    this->Protocol = nullptr;
-    return request.ReportError("Failed to activate protocol version: " +
-                               errorMessage);
-  }
-  return request.Reply(Json::objectValue);
-}
-
-bool cmServer::Serve(std::string* errorMessage)
-{
-  if (this->SupportedProtocols.empty()) {
-    *errorMessage =
-      "No protocol versions defined. Maybe you need --experimental?";
-    return false;
-  }
-  assert(!this->Protocol);
-
-  return cmServerBase::Serve(errorMessage);
-}
-
-cmFileMonitor* cmServer::FileMonitor() const
-{
-  return fileMonitor.get();
-}
-
-void cmServer::WriteJsonObject(const Json::Value& jsonValue,
-                               const DebugInfo* debug) const
-{
-  cm::shared_lock<cm::shared_mutex> lock(ConnectionsMutex);
-  for (auto& connection : this->Connections) {
-    WriteJsonObject(connection.get(), jsonValue, debug);
-  }
-}
-
-void cmServer::WriteJsonObject(cmConnection* connection,
-                               const Json::Value& jsonValue,
-                               const DebugInfo* debug) const
-{
-  Json::FastWriter writer;
-
-  auto beforeJson = uv_hrtime();
-  std::string result = writer.write(jsonValue);
-
-  if (debug) {
-    Json::Value copy = jsonValue;
-    if (debug->PrintStatistics) {
-      Json::Value stats = Json::objectValue;
-      auto endTime = uv_hrtime();
-
-      stats["jsonSerialization"] = double(endTime - beforeJson) / 1000000.0;
-      stats["totalTime"] = double(endTime - debug->StartTime) / 1000000.0;
-      stats["size"] = static_cast<int>(result.size());
-      if (!debug->OutputFile.empty()) {
-        stats["dumpFile"] = debug->OutputFile;
-      }
-
-      copy["zzzDebug"] = stats;
-
-      result = writer.write(copy); // Update result to include debug info
-    }
-
-    if (!debug->OutputFile.empty()) {
-      cmsys::ofstream myfile(debug->OutputFile.c_str());
-      myfile << result;
-    }
-  }
-
-  connection->WriteData(result);
-}
-
-cmServerProtocol* cmServer::FindMatchingProtocol(
-  const std::vector<std::unique_ptr<cmServerProtocol>>& protocols, int major,
-  int minor)
-{
-  cmServerProtocol* bestMatch = nullptr;
-  for (const auto& protocol : protocols) {
-    auto version = protocol->ProtocolVersion();
-    if (major != version.first) {
-      continue;
-    }
-    if (minor == version.second) {
-      return protocol.get();
-    }
-    if (!bestMatch || bestMatch->ProtocolVersion().second < version.second) {
-      bestMatch = protocol.get();
-    }
-  }
-  return minor < 0 ? bestMatch : nullptr;
-}
-
-void cmServer::WriteProgress(const cmServerRequest& request, int min,
-                             int current, int max,
-                             const std::string& message) const
-{
-  assert(min <= current && current <= max);
-  assert(message.length() != 0);
-
-  Json::Value obj = Json::objectValue;
-  obj[kTYPE_KEY] = kPROGRESS_TYPE;
-  obj[kREPLY_TO_KEY] = request.Type;
-  obj[kCOOKIE_KEY] = request.Cookie;
-  obj[kPROGRESS_MESSAGE_KEY] = message;
-  obj[kPROGRESS_MINIMUM_KEY] = min;
-  obj[kPROGRESS_MAXIMUM_KEY] = max;
-  obj[kPROGRESS_CURRENT_KEY] = current;
-
-  this->WriteJsonObject(request.Connection, obj, nullptr);
-}
-
-void cmServer::WriteMessage(const cmServerRequest& request,
-                            const std::string& message,
-                            const std::string& title) const
-{
-  if (message.empty()) {
-    return;
-  }
-
-  Json::Value obj = Json::objectValue;
-  obj[kTYPE_KEY] = kMESSAGE_TYPE;
-  obj[kREPLY_TO_KEY] = request.Type;
-  obj[kCOOKIE_KEY] = request.Cookie;
-  obj[kMESSAGE_KEY] = message;
-  if (!title.empty()) {
-    obj[kTITLE_KEY] = title;
-  }
-
-  WriteJsonObject(request.Connection, obj, nullptr);
-}
-
-void cmServer::WriteParseError(cmConnection* connection,
-                               const std::string& message) const
-{
-  Json::Value obj = Json::objectValue;
-  obj[kTYPE_KEY] = kERROR_TYPE;
-  obj[kERROR_MESSAGE_KEY] = message;
-  obj[kREPLY_TO_KEY] = "";
-  obj[kCOOKIE_KEY] = "";
-
-  this->WriteJsonObject(connection, obj, nullptr);
-}
-
-void cmServer::WriteSignal(const std::string& name,
-                           const Json::Value& data) const
-{
-  assert(data.isObject());
-  Json::Value obj = data;
-  obj[kTYPE_KEY] = kSIGNAL_TYPE;
-  obj[kREPLY_TO_KEY] = "";
-  obj[kCOOKIE_KEY] = "";
-  obj[kNAME_KEY] = name;
-
-  WriteJsonObject(obj, nullptr);
-}
-
-void cmServer::WriteResponse(cmConnection* connection,
-                             const cmServerResponse& response,
-                             const DebugInfo* debug) const
-{
-  assert(response.IsComplete());
-
-  Json::Value obj = response.Data();
-  obj[kCOOKIE_KEY] = response.Cookie;
-  obj[kTYPE_KEY] = response.IsError() ? kERROR_TYPE : kREPLY_TYPE;
-  obj[kREPLY_TO_KEY] = response.Type;
-  if (response.IsError()) {
-    obj[kERROR_MESSAGE_KEY] = response.ErrorMessage();
-  }
-
-  this->WriteJsonObject(connection, obj, debug);
-}
-
-void cmServer::OnConnected(cmConnection* connection)
-{
-  PrintHello(connection);
-}
-
-void cmServer::OnServeStart()
-{
-  cmServerBase::OnServeStart();
-  fileMonitor = std::make_shared<cmFileMonitor>(GetLoop());
-}
-
-void cmServer::StartShutDown()
-{
-  if (fileMonitor) {
-    fileMonitor->StopMonitoring();
-    fileMonitor.reset();
-  }
-  cmServerBase::StartShutDown();
-}
-
-static void __start_thread(void* arg)
-{
-  auto server = static_cast<cmServerBase*>(arg);
-  std::string error;
-  bool success = server->Serve(&error);
-  if (!success || !error.empty()) {
-    std::cerr << "Error during serve: " << error << std::endl;
-  }
-}
-
-bool cmServerBase::StartServeThread()
-{
-  ServeThreadRunning = true;
-  uv_thread_create(&ServeThread, __start_thread, this);
-  return true;
-}
-
-static void __shutdownThread(uv_async_t* arg)
-{
-  auto server = static_cast<cmServerBase*>(arg->data);
-  server->StartShutDown();
-}
-
-bool cmServerBase::Serve(std::string* errorMessage)
-{
-#ifndef NDEBUG
-  uv_thread_t blank_thread_t = {};
-  assert(uv_thread_equal(&blank_thread_t, &ServeThreadId));
-  ServeThreadId = uv_thread_self();
-#endif
-
-  errorMessage->clear();
-
-  ShutdownSignal.init(Loop, __shutdownThread, this);
-
-  SIGINTHandler.init(Loop, this);
-  SIGHUPHandler.init(Loop, this);
-
-  SIGINTHandler.start(&on_signal, SIGINT);
-  SIGHUPHandler.start(&on_signal, SIGHUP);
-
-  OnServeStart();
-
-  {
-    cm::shared_lock<cm::shared_mutex> lock(ConnectionsMutex);
-    for (auto& connection : Connections) {
-      if (!connection->OnServeStart(errorMessage)) {
-        return false;
-      }
-    }
-  }
-
-  if (uv_run(&Loop, UV_RUN_DEFAULT) != 0) {
-    // It is important we don't ever let the event loop exit with open handles
-    // at best this is a memory leak, but it can also introduce race conditions
-    // which can hang the program.
-    assert(false && "Event loop stopped in unclean state.");
-
-    *errorMessage = "Internal Error: Event loop stopped in unclean state.";
-    return false;
-  }
-
-  return true;
-}
-
-void cmServerBase::OnConnected(cmConnection*)
-{
-}
-
-void cmServerBase::OnServeStart()
-{
-}
-
-void cmServerBase::StartShutDown()
-{
-  ShutdownSignal.reset();
-  SIGINTHandler.reset();
-  SIGHUPHandler.reset();
-
-  {
-    std::unique_lock<cm::shared_mutex> lock(ConnectionsMutex);
-    for (auto& connection : Connections) {
-      connection->OnConnectionShuttingDown();
-    }
-    Connections.clear();
-  }
-
-  uv_walk(&Loop, on_walk_to_shutdown, nullptr);
-}
-
-bool cmServerBase::OnSignal(int signum)
-{
-  (void)signum;
-  StartShutDown();
-  return true;
-}
-
-cmServerBase::cmServerBase(cmConnection* connection)
-{
-  auto err = uv_loop_init(&Loop);
-  (void)err;
-  Loop.data = this;
-  assert(err == 0);
-
-  AddNewConnection(connection);
-}
-
-void cmServerBase::Close()
-{
-  if (Loop.data) {
-    if (ServeThreadRunning) {
-      this->ShutdownSignal.send();
-      uv_thread_join(&ServeThread);
-    }
-
-    uv_loop_close(&Loop);
-    Loop.data = nullptr;
-  }
-}
-cmServerBase::~cmServerBase()
-{
-  Close();
-}
-
-void cmServerBase::AddNewConnection(cmConnection* ownedConnection)
-{
-  {
-    std::unique_lock<cm::shared_mutex> lock(ConnectionsMutex);
-    Connections.emplace_back(ownedConnection);
-  }
-  ownedConnection->SetServer(this);
-}
-
-uv_loop_t* cmServerBase::GetLoop()
-{
-  return &Loop;
-}
-
-void cmServerBase::OnDisconnect(cmConnection* pConnection)
-{
-  auto pred = [pConnection](const std::unique_ptr<cmConnection>& m) {
-    return m.get() == pConnection;
-  };
-  {
-    std::unique_lock<cm::shared_mutex> lock(ConnectionsMutex);
-    Connections.erase(
-      std::remove_if(Connections.begin(), Connections.end(), pred),
-      Connections.end());
-  }
-
-  if (Connections.empty()) {
-    this->ShutdownSignal.send();
-  }
-}
diff --git a/Source/cmServer.h b/Source/cmServer.h
deleted file mode 100644
index 9543329..0000000
--- a/Source/cmServer.h
+++ /dev/null
@@ -1,162 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
-   file Copyright.txt or https://cmake.org/licensing for details.  */
-#pragma once
-
-#include "cmConfigure.h" // IWYU pragma: keep
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include <cm/shared_mutex>
-
-#include <cm3p/json/value.h>
-#include <cm3p/uv.h>
-
-#include "cmUVHandlePtr.h"
-
-class cmConnection;
-class cmFileMonitor;
-class cmServerProtocol;
-class cmServerRequest;
-class cmServerResponse;
-
-/***
- * This essentially hold and manages a libuv event queue and responds to
- * messages
- * on any of its connections.
- */
-class cmServerBase
-{
-public:
-  cmServerBase(cmConnection* connection);
-  virtual ~cmServerBase();
-
-  virtual void AddNewConnection(cmConnection* ownedConnection);
-
-  /***
-   * The main override responsible for tailoring behavior towards
-   * whatever the given server is supposed to do
-   *
-   * This should almost always be called by the given connections
-   * directly.
-   *
-   * @param connection The connection the request was received on
-   * @param request The actual request
-   */
-  virtual void ProcessRequest(cmConnection* connection,
-                              const std::string& request) = 0;
-  virtual void OnConnected(cmConnection* connection);
-
-  /***
-   * Start a dedicated thread. If this is used to start the server, it will
-   * join on the
-   * servers dtor.
-   */
-  virtual bool StartServeThread();
-  virtual bool Serve(std::string* errorMessage);
-
-  virtual void OnServeStart();
-  virtual void StartShutDown();
-
-  virtual bool OnSignal(int signum);
-  uv_loop_t* GetLoop();
-  void Close();
-  void OnDisconnect(cmConnection* pConnection);
-
-protected:
-  mutable cm::shared_mutex ConnectionsMutex;
-  std::vector<std::unique_ptr<cmConnection>> Connections;
-
-  bool ServeThreadRunning = false;
-  uv_thread_t ServeThread;
-  cm::uv_async_ptr ShutdownSignal;
-#ifndef NDEBUG
-public:
-  // When the server starts it will mark down it's current thread ID,
-  // which is useful in other contexts to just assert that operations
-  // are performed on that same thread.
-  uv_thread_t ServeThreadId = {};
-
-protected:
-#endif
-
-  uv_loop_t Loop;
-
-  cm::uv_signal_ptr SIGINTHandler;
-  cm::uv_signal_ptr SIGHUPHandler;
-};
-
-class cmServer : public cmServerBase
-{
-public:
-  class DebugInfo;
-
-  cmServer(cmConnection* conn, bool supportExperimental);
-  ~cmServer() override;
-
-  cmServer(cmServer const&) = delete;
-  cmServer& operator=(cmServer const&) = delete;
-
-  bool Serve(std::string* errorMessage) override;
-
-  cmFileMonitor* FileMonitor() const;
-
-private:
-  void RegisterProtocol(std::unique_ptr<cmServerProtocol> protocol);
-
-  // Callbacks from cmServerConnection:
-
-  void ProcessRequest(cmConnection* connection,
-                      const std::string& request) override;
-  std::shared_ptr<cmFileMonitor> fileMonitor;
-
-public:
-  void OnServeStart() override;
-
-  void StartShutDown() override;
-
-public:
-  void OnConnected(cmConnection* connection) override;
-
-private:
-  static void reportProgress(const std::string& msg, float progress,
-                             const cmServerRequest& request);
-  static void reportMessage(const std::string& msg, const char* title,
-                            const cmServerRequest& request);
-
-  // Handle requests:
-  cmServerResponse SetProtocolVersion(const cmServerRequest& request);
-
-  void PrintHello(cmConnection* connection) const;
-
-  // Write responses:
-  void WriteProgress(const cmServerRequest& request, int min, int current,
-                     int max, const std::string& message) const;
-  void WriteMessage(const cmServerRequest& request, const std::string& message,
-                    const std::string& title) const;
-  void WriteResponse(cmConnection* connection,
-                     const cmServerResponse& response,
-                     const DebugInfo* debug) const;
-  void WriteParseError(cmConnection* connection,
-                       const std::string& message) const;
-  void WriteSignal(const std::string& name, const Json::Value& obj) const;
-
-  void WriteJsonObject(Json::Value const& jsonValue,
-                       const DebugInfo* debug) const;
-
-  void WriteJsonObject(cmConnection* connection, Json::Value const& jsonValue,
-                       const DebugInfo* debug) const;
-
-  static cmServerProtocol* FindMatchingProtocol(
-    const std::vector<std::unique_ptr<cmServerProtocol>>& protocols, int major,
-    int minor);
-
-  const bool SupportExperimental;
-
-  cmServerProtocol* Protocol = nullptr;
-  std::vector<std::unique_ptr<cmServerProtocol>> SupportedProtocols;
-
-  friend class cmServerProtocol;
-  friend class cmServerRequest;
-};
diff --git a/Source/cmServerConnection.cxx b/Source/cmServerConnection.cxx
deleted file mode 100644
index b4f41a0..0000000
--- a/Source/cmServerConnection.cxx
+++ /dev/null
@@ -1,165 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
-   file Copyright.txt or https://cmake.org/licensing for details.  */
-#include "cmConfigure.h"
-
-#include "cmServerConnection.h"
-
-#include <cm3p/uv.h>
-
-#include "cmServer.h"
-#include "cmServerDictionary.h"
-
-#ifdef _WIN32
-#  include "io.h"
-#else
-#  include <unistd.h>
-#endif
-#include <cassert>
-#include <utility>
-
-cmStdIoConnection::cmStdIoConnection(
-  cmConnectionBufferStrategy* bufferStrategy)
-  : cmEventBasedConnection(bufferStrategy)
-{
-}
-
-cm::uv_stream_ptr cmStdIoConnection::SetupStream(int file_id)
-{
-  switch (uv_guess_handle(file_id)) {
-    case UV_TTY: {
-      cm::uv_tty_ptr tty;
-      tty.init(*this->Server->GetLoop(), file_id, file_id == 0,
-               static_cast<cmEventBasedConnection*>(this));
-      uv_tty_set_mode(tty, UV_TTY_MODE_NORMAL);
-      return { std::move(tty) };
-    }
-    case UV_FILE:
-      if (file_id == 0) {
-        return nullptr;
-      }
-      // Intentional fallthrough; stdin can _not_ be treated as a named
-      // pipe, however stdout can be.
-      CM_FALLTHROUGH;
-    case UV_NAMED_PIPE: {
-      cm::uv_pipe_ptr pipe;
-      pipe.init(*this->Server->GetLoop(), 0,
-                static_cast<cmEventBasedConnection*>(this));
-      uv_pipe_open(pipe, file_id);
-      return { std::move(pipe) };
-    }
-    default:
-      assert(false && "Unable to determine stream type");
-      return nullptr;
-  }
-}
-
-void cmStdIoConnection::SetServer(cmServerBase* s)
-{
-  cmConnection::SetServer(s);
-  if (!s) {
-    return;
-  }
-
-  this->ReadStream = SetupStream(0);
-  this->WriteStream = SetupStream(1);
-}
-
-void shutdown_connection(uv_prepare_t* prepare)
-{
-  cmStdIoConnection* connection =
-    static_cast<cmStdIoConnection*>(prepare->data);
-
-  if (!uv_is_closing(reinterpret_cast<uv_handle_t*>(prepare))) {
-    uv_close(reinterpret_cast<uv_handle_t*>(prepare),
-             &cmEventBasedConnection::on_close_delete<uv_prepare_t>);
-  }
-  connection->OnDisconnect(0);
-}
-
-bool cmStdIoConnection::OnServeStart(std::string* pString)
-{
-  Server->OnConnected(this);
-  if (this->ReadStream.get()) {
-    uv_read_start(this->ReadStream, on_alloc_buffer, on_read);
-  } else if (uv_guess_handle(0) == UV_FILE) {
-    char buffer[1024];
-    while (auto len = read(0, buffer, sizeof(buffer))) {
-      ReadData(std::string(buffer, buffer + len));
-    }
-
-    // We can't start the disconnect from here, add a prepare hook to do that
-    // for us
-    auto prepare = new uv_prepare_t();
-    prepare->data = this;
-    uv_prepare_init(Server->GetLoop(), prepare);
-    uv_prepare_start(prepare, shutdown_connection);
-  }
-  return cmConnection::OnServeStart(pString);
-}
-
-bool cmStdIoConnection::OnConnectionShuttingDown()
-{
-  if (ReadStream.get()) {
-    uv_read_stop(ReadStream);
-    ReadStream->data = nullptr;
-  }
-
-  this->ReadStream.reset();
-
-  cmEventBasedConnection::OnConnectionShuttingDown();
-
-  return true;
-}
-
-cmServerPipeConnection::cmServerPipeConnection(const std::string& name)
-  : cmPipeConnection(name, new cmServerBufferStrategy)
-{
-}
-
-cmServerStdIoConnection::cmServerStdIoConnection()
-  : cmStdIoConnection(new cmServerBufferStrategy)
-{
-}
-
-cmConnectionBufferStrategy::~cmConnectionBufferStrategy() = default;
-
-void cmConnectionBufferStrategy::clear()
-{
-}
-
-std::string cmServerBufferStrategy::BufferOutMessage(
-  const std::string& rawBuffer) const
-{
-  return std::string("\n") + kSTART_MAGIC + std::string("\n") + rawBuffer +
-    kEND_MAGIC + std::string("\n");
-}
-
-std::string cmServerBufferStrategy::BufferMessage(std::string& RawReadBuffer)
-{
-  for (;;) {
-    auto needle = RawReadBuffer.find('\n');
-
-    if (needle == std::string::npos) {
-      return "";
-    }
-    std::string line = RawReadBuffer.substr(0, needle);
-    const auto ls = line.size();
-    if (ls > 1 && line.at(ls - 1) == '\r') {
-      line.erase(ls - 1, 1);
-    }
-    RawReadBuffer.erase(RawReadBuffer.begin(),
-                        RawReadBuffer.begin() + static_cast<long>(needle) + 1);
-    if (line == kSTART_MAGIC) {
-      RequestBuffer.clear();
-      continue;
-    }
-    if (line == kEND_MAGIC) {
-      std::string rtn;
-      rtn.swap(this->RequestBuffer);
-      return rtn;
-    }
-
-    this->RequestBuffer += line;
-    this->RequestBuffer += "\n";
-  }
-}
diff --git a/Source/cmServerConnection.h b/Source/cmServerConnection.h
deleted file mode 100644
index a70edb4..0000000
--- a/Source/cmServerConnection.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
-   file Copyright.txt or https://cmake.org/licensing for details.  */
-#pragma once
-
-#include "cmConfigure.h" // IWYU pragma: keep
-
-#include <string>
-
-#include "cmConnection.h"
-#include "cmPipeConnection.h"
-#include "cmUVHandlePtr.h"
-
-class cmServerBase;
-
-/***
- * This connection buffer strategy accepts messages in the form of
- * [== "CMake Server" ==[
-{
-  ... some JSON message ...
-}
-]== "CMake Server" ==]
- * and only passes on the core json; it discards the envelope.
- */
-class cmServerBufferStrategy : public cmConnectionBufferStrategy
-{
-public:
-  std::string BufferMessage(std::string& rawBuffer) override;
-  std::string BufferOutMessage(const std::string& rawBuffer) const override;
-
-private:
-  std::string RequestBuffer;
-};
-
-/***
- * Generic connection over std io interfaces -- tty
- */
-class cmStdIoConnection : public cmEventBasedConnection
-{
-public:
-  cmStdIoConnection(cmConnectionBufferStrategy* bufferStrategy);
-
-  void SetServer(cmServerBase* s) override;
-
-  bool OnConnectionShuttingDown() override;
-
-  bool OnServeStart(std::string* pString) override;
-
-private:
-  cm::uv_stream_ptr SetupStream(int file_id);
-  cm::uv_stream_ptr ReadStream;
-};
-
-/***
- * These specific connections use the cmake server
- * buffering strategy.
- */
-class cmServerStdIoConnection : public cmStdIoConnection
-{
-public:
-  cmServerStdIoConnection();
-};
-
-class cmServerPipeConnection : public cmPipeConnection
-{
-public:
-  cmServerPipeConnection(const std::string& name);
-};
diff --git a/Source/cmServerDictionary.h b/Source/cmServerDictionary.h
deleted file mode 100644
index 961e4b7..0000000
--- a/Source/cmServerDictionary.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
-   file Copyright.txt or https://cmake.org/licensing for details.  */
-#pragma once
-
-#include <string>
-
-// Vocabulary:
-
-static const std::string kDIRTY_SIGNAL = "dirty";
-static const std::string kFILE_CHANGE_SIGNAL = "fileChange";
-
-static const std::string kCACHE_TYPE = "cache";
-static const std::string kCMAKE_INPUTS_TYPE = "cmakeInputs";
-static const std::string kCODE_MODEL_TYPE = "codemodel";
-static const std::string kCOMPUTE_TYPE = "compute";
-static const std::string kCONFIGURE_TYPE = "configure";
-static const std::string kERROR_TYPE = "error";
-static const std::string kFILESYSTEM_WATCHERS_TYPE = "fileSystemWatchers";
-static const std::string kGLOBAL_SETTINGS_TYPE = "globalSettings";
-static const std::string kHANDSHAKE_TYPE = "handshake";
-static const std::string kMESSAGE_TYPE = "message";
-static const std::string kPROGRESS_TYPE = "progress";
-static const std::string kREPLY_TYPE = "reply";
-static const std::string kSET_GLOBAL_SETTINGS_TYPE = "setGlobalSettings";
-static const std::string kSIGNAL_TYPE = "signal";
-static const std::string kCTEST_INFO_TYPE = "ctestInfo";
-
-static const std::string kBUILD_FILES_KEY = "buildFiles";
-static const std::string kCACHE_ARGUMENTS_KEY = "cacheArguments";
-static const std::string kCACHE_KEY = "cache";
-static const std::string kCAPABILITIES_KEY = "capabilities";
-static const std::string kCHECK_SYSTEM_VARS_KEY = "checkSystemVars";
-static const std::string kCMAKE_ROOT_DIRECTORY_KEY = "cmakeRootDirectory";
-static const std::string kCOOKIE_KEY = "cookie";
-static const std::string kDEBUG_OUTPUT_KEY = "debugOutput";
-static const std::string kERROR_MESSAGE_KEY = "errorMessage";
-static const std::string kEXTRA_GENERATOR_KEY = "extraGenerator";
-static const std::string kGENERATOR_KEY = "generator";
-static const std::string kIS_EXPERIMENTAL_KEY = "isExperimental";
-static const std::string kKEYS_KEY = "keys";
-static const std::string kMAJOR_KEY = "major";
-static const std::string kMESSAGE_KEY = "message";
-static const std::string kMINOR_KEY = "minor";
-static const std::string kPLATFORM_KEY = "platform";
-static const std::string kPROGRESS_CURRENT_KEY = "progressCurrent";
-static const std::string kPROGRESS_MAXIMUM_KEY = "progressMaximum";
-static const std::string kPROGRESS_MESSAGE_KEY = "progressMessage";
-static const std::string kPROGRESS_MINIMUM_KEY = "progressMinimum";
-static const std::string kPROTOCOL_VERSION_KEY = "protocolVersion";
-static const std::string kREPLY_TO_KEY = "inReplyTo";
-static const std::string kSUPPORTED_PROTOCOL_VERSIONS =
-  "supportedProtocolVersions";
-static const std::string kTITLE_KEY = "title";
-static const std::string kTOOLSET_KEY = "toolset";
-static const std::string kTRACE_EXPAND_KEY = "traceExpand";
-static const std::string kTRACE_KEY = "trace";
-static const std::string kWARN_UNINITIALIZED_KEY = "warnUninitialized";
-static const std::string kWARN_UNUSED_CLI_KEY = "warnUnusedCli";
-static const std::string kWARN_UNUSED_KEY = "warnUnused";
-static const std::string kWATCHED_DIRECTORIES_KEY = "watchedDirectories";
-static const std::string kWATCHED_FILES_KEY = "watchedFiles";
-
-static const std::string kSTART_MAGIC = "[== \"CMake Server\" ==[";
-static const std::string kEND_MAGIC = "]== \"CMake Server\" ==]";
-
-static const std::string kRENAME_PROPERTY_VALUE = "rename";
-static const std::string kCHANGE_PROPERTY_VALUE = "change";
diff --git a/Source/cmServerProtocol.cxx b/Source/cmServerProtocol.cxx
deleted file mode 100644
index e586fd9..0000000
--- a/Source/cmServerProtocol.cxx
+++ /dev/null
@@ -1,760 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
-   file Copyright.txt or https://cmake.org/licensing for details.  */
-#include "cmServerProtocol.h"
-
-#include <algorithm>
-#include <cassert>
-#include <functional>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include <cm/memory>
-#include <cmext/algorithm>
-
-#include <cm3p/uv.h>
-
-#include "cmExternalMakefileProjectGenerator.h"
-#include "cmFileMonitor.h"
-#include "cmGlobalGenerator.h"
-#include "cmJsonObjectDictionary.h"
-#include "cmJsonObjects.h"
-#include "cmMessageType.h"
-#include "cmProperty.h"
-#include "cmServer.h"
-#include "cmServerDictionary.h"
-#include "cmState.h"
-#include "cmSystemTools.h"
-#include "cmake.h"
-
-// Get rid of some windows macros:
-#undef max
-
-namespace {
-
-std::vector<std::string> toStringList(const Json::Value& in)
-{
-  std::vector<std::string> result;
-  for (auto const& it : in) {
-    result.push_back(it.asString());
-  }
-  return result;
-}
-
-} // namespace
-
-cmServerRequest::cmServerRequest(cmServer* server, cmConnection* connection,
-                                 std::string t, std::string c, Json::Value d)
-  : Type(std::move(t))
-  , Cookie(std::move(c))
-  , Data(std::move(d))
-  , Connection(connection)
-  , m_Server(server)
-{
-}
-
-void cmServerRequest::ReportProgress(int min, int current, int max,
-                                     const std::string& message) const
-{
-  this->m_Server->WriteProgress(*this, min, current, max, message);
-}
-
-void cmServerRequest::ReportMessage(const std::string& message,
-                                    const std::string& title) const
-{
-  m_Server->WriteMessage(*this, message, title);
-}
-
-cmServerResponse cmServerRequest::Reply(const Json::Value& data) const
-{
-  cmServerResponse response(*this);
-  response.SetData(data);
-  return response;
-}
-
-cmServerResponse cmServerRequest::ReportError(const std::string& message) const
-{
-  cmServerResponse response(*this);
-  response.SetError(message);
-  return response;
-}
-
-cmServerResponse::cmServerResponse(const cmServerRequest& request)
-  : Type(request.Type)
-  , Cookie(request.Cookie)
-{
-}
-
-void cmServerResponse::SetData(const Json::Value& data)
-{
-  assert(this->m_Payload == PAYLOAD_UNKNOWN);
-  if (!data[kCOOKIE_KEY].isNull() || !data[kTYPE_KEY].isNull()) {
-    this->SetError("Response contains cookie or type field.");
-    return;
-  }
-  this->m_Payload = PAYLOAD_DATA;
-  this->m_Data = data;
-}
-
-void cmServerResponse::SetError(const std::string& message)
-{
-  assert(this->m_Payload == PAYLOAD_UNKNOWN);
-  this->m_Payload = PAYLOAD_ERROR;
-  this->m_ErrorMessage = message;
-}
-
-bool cmServerResponse::IsComplete() const
-{
-  return this->m_Payload != PAYLOAD_UNKNOWN;
-}
-
-bool cmServerResponse::IsError() const
-{
-  assert(this->m_Payload != PAYLOAD_UNKNOWN);
-  return this->m_Payload == PAYLOAD_ERROR;
-}
-
-std::string cmServerResponse::ErrorMessage() const
-{
-  if (this->m_Payload == PAYLOAD_ERROR) {
-    return this->m_ErrorMessage;
-  }
-  return std::string();
-}
-
-Json::Value cmServerResponse::Data() const
-{
-  assert(this->m_Payload != PAYLOAD_UNKNOWN);
-  return this->m_Data;
-}
-
-bool cmServerProtocol::Activate(cmServer* server,
-                                const cmServerRequest& request,
-                                std::string* errorMessage)
-{
-  assert(server);
-  this->m_Server = server;
-  this->m_CMakeInstance =
-    cm::make_unique<cmake>(cmake::RoleProject, cmState::Project);
-  this->m_WarnUnused = false;
-  const bool result = this->DoActivate(request, errorMessage);
-  if (!result) {
-    this->m_CMakeInstance = nullptr;
-  }
-  return result;
-}
-
-cmFileMonitor* cmServerProtocol::FileMonitor() const
-{
-  return this->m_Server ? this->m_Server->FileMonitor() : nullptr;
-}
-
-void cmServerProtocol::SendSignal(const std::string& name,
-                                  const Json::Value& data) const
-{
-  if (this->m_Server) {
-    this->m_Server->WriteSignal(name, data);
-  }
-}
-
-cmake* cmServerProtocol::CMakeInstance() const
-{
-  return this->m_CMakeInstance.get();
-}
-
-bool cmServerProtocol::DoActivate(const cmServerRequest& /*request*/,
-                                  std::string* /*errorMessage*/)
-{
-  return true;
-}
-
-std::pair<int, int> cmServerProtocol1::ProtocolVersion() const
-{
-  return { 1, 2 };
-}
-
-static void setErrorMessage(std::string* errorMessage, const std::string& text)
-{
-  if (errorMessage) {
-    *errorMessage = text;
-  }
-}
-
-static bool getOrTestHomeDirectory(cmState* state, std::string& value,
-                                   std::string* errorMessage)
-{
-  const std::string cachedValue =
-    *state->GetCacheEntryValue("CMAKE_HOME_DIRECTORY");
-  if (value.empty()) {
-    value = cachedValue;
-    return true;
-  }
-  const std::string suffix = "/CMakeLists.txt";
-  const std::string cachedValueCML = cachedValue + suffix;
-  const std::string valueCML = value + suffix;
-  if (!cmSystemTools::SameFile(valueCML, cachedValueCML)) {
-    setErrorMessage(errorMessage,
-                    std::string("\"CMAKE_HOME_DIRECTORY\" is set but "
-                                "incompatible with configured "
-                                "source directory value."));
-    return false;
-  }
-  return true;
-}
-
-static bool getOrTestValue(cmState* state, const std::string& key,
-                           std::string& value,
-                           const std::string& keyDescription,
-                           std::string* errorMessage)
-{
-  const std::string cachedValue = state->GetSafeCacheEntryValue(key);
-  if (value.empty()) {
-    value = cachedValue;
-  }
-  if (!cachedValue.empty() && cachedValue != value) {
-    setErrorMessage(errorMessage,
-                    std::string("\"") + key +
-                      "\" is set but incompatible with configured " +
-                      keyDescription + " value.");
-    return false;
-  }
-  return true;
-}
-
-bool cmServerProtocol1::DoActivate(const cmServerRequest& request,
-                                   std::string* errorMessage)
-{
-  std::string sourceDirectory = request.Data[kSOURCE_DIRECTORY_KEY].asString();
-  std::string buildDirectory = request.Data[kBUILD_DIRECTORY_KEY].asString();
-  std::string generator = request.Data[kGENERATOR_KEY].asString();
-  std::string extraGenerator = request.Data[kEXTRA_GENERATOR_KEY].asString();
-  std::string toolset = request.Data[kTOOLSET_KEY].asString();
-  std::string platform = request.Data[kPLATFORM_KEY].asString();
-
-  // normalize source and build directory
-  if (!sourceDirectory.empty()) {
-    sourceDirectory = cmSystemTools::CollapseFullPath(sourceDirectory);
-    cmSystemTools::ConvertToUnixSlashes(sourceDirectory);
-  }
-  if (!buildDirectory.empty()) {
-    buildDirectory = cmSystemTools::CollapseFullPath(buildDirectory);
-    cmSystemTools::ConvertToUnixSlashes(buildDirectory);
-  }
-
-  if (buildDirectory.empty()) {
-    setErrorMessage(errorMessage,
-                    std::string("\"") + kBUILD_DIRECTORY_KEY +
-                      "\" is missing.");
-    return false;
-  }
-
-  cmake* cm = CMakeInstance();
-  if (cmSystemTools::PathExists(buildDirectory)) {
-    if (!cmSystemTools::FileIsDirectory(buildDirectory)) {
-      setErrorMessage(errorMessage,
-                      std::string("\"") + kBUILD_DIRECTORY_KEY +
-                        "\" exists but is not a directory.");
-      return false;
-    }
-
-    const std::string cachePath = cmake::FindCacheFile(buildDirectory);
-    if (cm->LoadCache(cachePath)) {
-      cmState* state = cm->GetState();
-
-      // Check generator:
-      if (!getOrTestValue(state, "CMAKE_GENERATOR", generator, "generator",
-                          errorMessage)) {
-        return false;
-      }
-
-      // check extra generator:
-      if (!getOrTestValue(state, "CMAKE_EXTRA_GENERATOR", extraGenerator,
-                          "extra generator", errorMessage)) {
-        return false;
-      }
-
-      // check sourcedir:
-      if (!getOrTestHomeDirectory(state, sourceDirectory, errorMessage)) {
-        return false;
-      }
-
-      // check toolset:
-      if (!getOrTestValue(state, "CMAKE_GENERATOR_TOOLSET", toolset, "toolset",
-                          errorMessage)) {
-        return false;
-      }
-
-      // check platform:
-      if (!getOrTestValue(state, "CMAKE_GENERATOR_PLATFORM", platform,
-                          "platform", errorMessage)) {
-        return false;
-      }
-    }
-  }
-
-  if (sourceDirectory.empty()) {
-    setErrorMessage(errorMessage,
-                    std::string("\"") + kSOURCE_DIRECTORY_KEY +
-                      "\" is unset but required.");
-    return false;
-  }
-  if (!cmSystemTools::FileIsDirectory(sourceDirectory)) {
-    setErrorMessage(errorMessage,
-                    std::string("\"") + kSOURCE_DIRECTORY_KEY +
-                      "\" is not a directory.");
-    return false;
-  }
-  if (generator.empty()) {
-    setErrorMessage(errorMessage,
-                    std::string("\"") + kGENERATOR_KEY +
-                      "\" is unset but required.");
-    return false;
-  }
-
-  std::vector<cmake::GeneratorInfo> generators;
-  cm->GetRegisteredGenerators(generators);
-  auto baseIt = std::find_if(generators.begin(), generators.end(),
-                             [&generator](const cmake::GeneratorInfo& info) {
-                               return info.name == generator;
-                             });
-  if (baseIt == generators.end()) {
-    setErrorMessage(errorMessage,
-                    std::string("Generator \"") + generator +
-                      "\" not supported.");
-    return false;
-  }
-  auto extraIt = std::find_if(
-    generators.begin(), generators.end(),
-    [&generator, &extraGenerator](const cmake::GeneratorInfo& info) {
-      return info.baseName == generator && info.extraName == extraGenerator;
-    });
-  if (extraIt == generators.end()) {
-    setErrorMessage(errorMessage,
-                    std::string("The combination of generator \"" + generator +
-                                "\" and extra generator \"" + extraGenerator +
-                                "\" is not supported."));
-    return false;
-  }
-  if (!extraIt->supportsToolset && !toolset.empty()) {
-    setErrorMessage(errorMessage,
-                    std::string("Toolset was provided but is not supported by "
-                                "the requested generator."));
-    return false;
-  }
-  if (!extraIt->supportsPlatform && !platform.empty()) {
-    setErrorMessage(errorMessage,
-                    std::string("Platform was provided but is not supported "
-                                "by the requested generator."));
-    return false;
-  }
-
-  this->GeneratorInfo =
-    GeneratorInformation(generator, extraGenerator, toolset, platform,
-                         sourceDirectory, buildDirectory);
-
-  this->m_State = STATE_ACTIVE;
-  return true;
-}
-
-void cmServerProtocol1::HandleCMakeFileChanges(const std::string& path,
-                                               int event, int status)
-{
-  assert(status == 0);
-  static_cast<void>(status);
-
-  if (!m_isDirty) {
-    m_isDirty = true;
-    SendSignal(kDIRTY_SIGNAL, Json::objectValue);
-  }
-  Json::Value obj = Json::objectValue;
-  obj[kPATH_KEY] = path;
-  Json::Value properties = Json::arrayValue;
-  if (event & UV_RENAME) {
-    properties.append(kRENAME_PROPERTY_VALUE);
-  }
-  if (event & UV_CHANGE) {
-    properties.append(kCHANGE_PROPERTY_VALUE);
-  }
-
-  obj[kPROPERTIES_KEY] = properties;
-  SendSignal(kFILE_CHANGE_SIGNAL, obj);
-}
-
-cmServerResponse cmServerProtocol1::Process(const cmServerRequest& request)
-{
-  assert(this->m_State >= STATE_ACTIVE);
-
-  if (request.Type == kCACHE_TYPE) {
-    return this->ProcessCache(request);
-  }
-  if (request.Type == kCMAKE_INPUTS_TYPE) {
-    return this->ProcessCMakeInputs(request);
-  }
-  if (request.Type == kCODE_MODEL_TYPE) {
-    return this->ProcessCodeModel(request);
-  }
-  if (request.Type == kCOMPUTE_TYPE) {
-    return this->ProcessCompute(request);
-  }
-  if (request.Type == kCONFIGURE_TYPE) {
-    return this->ProcessConfigure(request);
-  }
-  if (request.Type == kFILESYSTEM_WATCHERS_TYPE) {
-    return this->ProcessFileSystemWatchers(request);
-  }
-  if (request.Type == kGLOBAL_SETTINGS_TYPE) {
-    return this->ProcessGlobalSettings(request);
-  }
-  if (request.Type == kSET_GLOBAL_SETTINGS_TYPE) {
-    return this->ProcessSetGlobalSettings(request);
-  }
-  if (request.Type == kCTEST_INFO_TYPE) {
-    return this->ProcessCTests(request);
-  }
-
-  return request.ReportError("Unknown command!");
-}
-
-bool cmServerProtocol1::IsExperimental() const
-{
-  return true;
-}
-
-cmServerResponse cmServerProtocol1::ProcessCache(
-  const cmServerRequest& request)
-{
-  cmState* state = this->CMakeInstance()->GetState();
-
-  Json::Value result = Json::objectValue;
-
-  std::vector<std::string> allKeys = state->GetCacheEntryKeys();
-
-  Json::Value list = Json::arrayValue;
-  std::vector<std::string> keys = toStringList(request.Data[kKEYS_KEY]);
-  if (keys.empty()) {
-    keys = allKeys;
-  } else {
-    for (auto const& i : keys) {
-      if (!cm::contains(allKeys, i)) {
-        return request.ReportError("Key \"" + i + "\" not found in cache.");
-      }
-    }
-  }
-  std::sort(keys.begin(), keys.end());
-  for (auto const& key : keys) {
-    Json::Value entry = Json::objectValue;
-    entry[kKEY_KEY] = key;
-    entry[kTYPE_KEY] =
-      cmState::CacheEntryTypeToString(state->GetCacheEntryType(key));
-    entry[kVALUE_KEY] = *state->GetCacheEntryValue(key);
-
-    Json::Value props = Json::objectValue;
-    bool haveProperties = false;
-    for (auto const& prop : state->GetCacheEntryPropertyList(key)) {
-      haveProperties = true;
-      props[prop] = *state->GetCacheEntryProperty(key, prop);
-    }
-    if (haveProperties) {
-      entry[kPROPERTIES_KEY] = props;
-    }
-
-    list.append(entry);
-  }
-
-  result[kCACHE_KEY] = list;
-  return request.Reply(result);
-}
-
-cmServerResponse cmServerProtocol1::ProcessCMakeInputs(
-  const cmServerRequest& request)
-{
-  if (this->m_State < STATE_CONFIGURED) {
-    return request.ReportError("This instance was not yet configured.");
-  }
-
-  const cmake* cm = this->CMakeInstance();
-  const std::string cmakeRootDir = cmSystemTools::GetCMakeRoot();
-  const std::string& sourceDir = cm->GetHomeDirectory();
-
-  Json::Value result = Json::objectValue;
-  result[kSOURCE_DIRECTORY_KEY] = sourceDir;
-  result[kCMAKE_ROOT_DIRECTORY_KEY] = cmakeRootDir;
-  result[kBUILD_FILES_KEY] = cmDumpCMakeInputs(cm);
-  return request.Reply(result);
-}
-
-cmServerResponse cmServerProtocol1::ProcessCodeModel(
-  const cmServerRequest& request)
-{
-  if (this->m_State != STATE_COMPUTED) {
-    return request.ReportError("No build system was generated yet.");
-  }
-
-  return request.Reply(cmDumpCodeModel(this->CMakeInstance()));
-}
-
-cmServerResponse cmServerProtocol1::ProcessCompute(
-  const cmServerRequest& request)
-{
-  if (this->m_State > STATE_CONFIGURED) {
-    return request.ReportError("This build system was already generated.");
-  }
-  if (this->m_State < STATE_CONFIGURED) {
-    return request.ReportError("This project was not configured yet.");
-  }
-
-  cmake* cm = this->CMakeInstance();
-  int ret = cm->Generate();
-
-  if (ret < 0) {
-    return request.ReportError("Failed to compute build system.");
-  }
-  m_State = STATE_COMPUTED;
-  return request.Reply(Json::Value());
-}
-
-cmServerResponse cmServerProtocol1::ProcessConfigure(
-  const cmServerRequest& request)
-{
-  if (this->m_State == STATE_INACTIVE) {
-    return request.ReportError("This instance is inactive.");
-  }
-
-  FileMonitor()->StopMonitoring();
-
-  std::string errorMessage;
-  cmake* cm = this->CMakeInstance();
-  this->GeneratorInfo.SetupGenerator(cm, &errorMessage);
-  if (!errorMessage.empty()) {
-    return request.ReportError(errorMessage);
-  }
-
-  // Make sure the types of cacheArguments matches (if given):
-  std::vector<std::string> cacheArgs = { "unused" };
-  bool cacheArgumentsError = false;
-  const Json::Value passedArgs = request.Data[kCACHE_ARGUMENTS_KEY];
-  if (!passedArgs.isNull()) {
-    if (passedArgs.isString()) {
-      cacheArgs.push_back(passedArgs.asString());
-    } else if (passedArgs.isArray()) {
-      for (auto const& arg : passedArgs) {
-        if (!arg.isString()) {
-          cacheArgumentsError = true;
-          break;
-        }
-        cacheArgs.push_back(arg.asString());
-      }
-    } else {
-      cacheArgumentsError = true;
-    }
-  }
-  if (cacheArgumentsError) {
-    request.ReportError(
-      "cacheArguments must be unset, a string or an array of strings.");
-  }
-
-  std::string sourceDir = cm->GetHomeDirectory();
-  const std::string buildDir = cm->GetHomeOutputDirectory();
-
-  cmGlobalGenerator* gg = cm->GetGlobalGenerator();
-
-  if (buildDir.empty()) {
-    return request.ReportError("No build directory set via Handshake.");
-  }
-
-  if (cm->LoadCache(buildDir)) {
-    // build directory has been set up before
-    cmProp cachedSourceDir =
-      cm->GetState()->GetInitializedCacheValue("CMAKE_HOME_DIRECTORY");
-    if (!cachedSourceDir) {
-      return request.ReportError("No CMAKE_HOME_DIRECTORY found in cache.");
-    }
-    if (sourceDir.empty()) {
-      sourceDir = *cachedSourceDir;
-      cm->SetHomeDirectory(sourceDir);
-    }
-
-    cmProp cachedGenerator =
-      cm->GetState()->GetInitializedCacheValue("CMAKE_GENERATOR");
-    if (cachedGenerator) {
-      if (gg && gg->GetName() != *cachedGenerator) {
-        return request.ReportError("Configured generator does not match with "
-                                   "CMAKE_GENERATOR found in cache.");
-      }
-    }
-  } else {
-    // build directory has not been set up before
-    if (sourceDir.empty()) {
-      return request.ReportError("No sourceDirectory set via "
-                                 "setGlobalSettings and no cache found in "
-                                 "buildDirectory.");
-    }
-  }
-
-  cmSystemTools::ResetErrorOccuredFlag(); // Reset error state
-
-  if (cm->AddCMakePaths() != 1) {
-    return request.ReportError("Failed to set CMake paths.");
-  }
-
-  if (!cm->SetCacheArgs(cacheArgs)) {
-    return request.ReportError("cacheArguments could not be set.");
-  }
-
-  int ret = cm->Configure();
-  cm->IssueMessage(
-    MessageType::DEPRECATION_WARNING,
-    "The 'cmake-server(7)' is deprecated.  "
-    "Please port clients to use the 'cmake-file-api(7)' instead.");
-  if (ret < 0) {
-    return request.ReportError("Configuration failed.");
-  }
-
-  std::vector<std::string> toWatchList;
-  cmGetCMakeInputs(gg, std::string(), buildDir, nullptr, &toWatchList,
-                   nullptr);
-
-  FileMonitor()->MonitorPaths(toWatchList,
-                              [this](const std::string& p, int e, int s) {
-                                this->HandleCMakeFileChanges(p, e, s);
-                              });
-
-  m_State = STATE_CONFIGURED;
-  m_isDirty = false;
-  return request.Reply(Json::Value());
-}
-
-cmServerResponse cmServerProtocol1::ProcessGlobalSettings(
-  const cmServerRequest& request)
-{
-  cmake* cm = this->CMakeInstance();
-  Json::Value obj = Json::objectValue;
-
-  // Capabilities information:
-  obj[kCAPABILITIES_KEY] = cm->ReportCapabilitiesJson();
-
-  obj[kDEBUG_OUTPUT_KEY] = cm->GetDebugOutput();
-  obj[kTRACE_KEY] = cm->GetTrace();
-  obj[kTRACE_EXPAND_KEY] = cm->GetTraceExpand();
-  obj[kWARN_UNINITIALIZED_KEY] = cm->GetWarnUninitialized();
-  obj[kWARN_UNUSED_KEY] = m_WarnUnused;
-  obj[kWARN_UNUSED_CLI_KEY] = cm->GetWarnUnusedCli();
-  obj[kCHECK_SYSTEM_VARS_KEY] = cm->GetCheckSystemVars();
-
-  obj[kSOURCE_DIRECTORY_KEY] = this->GeneratorInfo.SourceDirectory;
-  obj[kBUILD_DIRECTORY_KEY] = this->GeneratorInfo.BuildDirectory;
-
-  // Currently used generator:
-  obj[kGENERATOR_KEY] = this->GeneratorInfo.GeneratorName;
-  obj[kEXTRA_GENERATOR_KEY] = this->GeneratorInfo.ExtraGeneratorName;
-
-  return request.Reply(obj);
-}
-
-static void setBool(const cmServerRequest& request, const std::string& key,
-                    std::function<void(bool)> const& setter)
-{
-  if (request.Data[key].isNull()) {
-    return;
-  }
-  setter(request.Data[key].asBool());
-}
-
-cmServerResponse cmServerProtocol1::ProcessSetGlobalSettings(
-  const cmServerRequest& request)
-{
-  const std::vector<std::string> boolValues = {
-    kDEBUG_OUTPUT_KEY,       kTRACE_KEY,       kTRACE_EXPAND_KEY,
-    kWARN_UNINITIALIZED_KEY, kWARN_UNUSED_KEY, kWARN_UNUSED_CLI_KEY,
-    kCHECK_SYSTEM_VARS_KEY
-  };
-  for (std::string const& i : boolValues) {
-    if (!request.Data[i].isNull() && !request.Data[i].isBool()) {
-      return request.ReportError("\"" + i +
-                                 "\" must be unset or a bool value.");
-    }
-  }
-
-  cmake* cm = this->CMakeInstance();
-
-  setBool(request, kDEBUG_OUTPUT_KEY,
-          [cm](bool e) { cm->SetDebugOutputOn(e); });
-  setBool(request, kTRACE_KEY, [cm](bool e) { cm->SetTrace(e); });
-  setBool(request, kTRACE_EXPAND_KEY, [cm](bool e) { cm->SetTraceExpand(e); });
-  setBool(request, kWARN_UNINITIALIZED_KEY,
-          [cm](bool e) { cm->SetWarnUninitialized(e); });
-  setBool(request, kWARN_UNUSED_KEY, [this](bool e) { m_WarnUnused = e; });
-  setBool(request, kWARN_UNUSED_CLI_KEY,
-          [cm](bool e) { cm->SetWarnUnusedCli(e); });
-  setBool(request, kCHECK_SYSTEM_VARS_KEY,
-          [cm](bool e) { cm->SetCheckSystemVars(e); });
-
-  return request.Reply(Json::Value());
-}
-
-cmServerResponse cmServerProtocol1::ProcessFileSystemWatchers(
-  const cmServerRequest& request)
-{
-  const cmFileMonitor* const fm = FileMonitor();
-  Json::Value result = Json::objectValue;
-  Json::Value files = Json::arrayValue;
-  for (auto const& f : fm->WatchedFiles()) {
-    files.append(f);
-  }
-  Json::Value directories = Json::arrayValue;
-  for (auto const& d : fm->WatchedDirectories()) {
-    directories.append(d);
-  }
-  result[kWATCHED_FILES_KEY] = files;
-  result[kWATCHED_DIRECTORIES_KEY] = directories;
-
-  return request.Reply(result);
-}
-
-cmServerResponse cmServerProtocol1::ProcessCTests(
-  const cmServerRequest& request)
-{
-  if (this->m_State < STATE_COMPUTED) {
-    return request.ReportError("This instance was not yet computed.");
-  }
-
-  return request.Reply(cmDumpCTestInfo(this->CMakeInstance()));
-}
-
-cmServerProtocol1::GeneratorInformation::GeneratorInformation(
-  std::string generatorName, std::string extraGeneratorName,
-  std::string toolset, std::string platform, std::string sourceDirectory,
-  std::string buildDirectory)
-  : GeneratorName(std::move(generatorName))
-  , ExtraGeneratorName(std::move(extraGeneratorName))
-  , Toolset(std::move(toolset))
-  , Platform(std::move(platform))
-  , SourceDirectory(std::move(sourceDirectory))
-  , BuildDirectory(std::move(buildDirectory))
-{
-}
-
-void cmServerProtocol1::GeneratorInformation::SetupGenerator(
-  cmake* cm, std::string* errorMessage)
-{
-  const std::string fullGeneratorName =
-    cmExternalMakefileProjectGenerator::CreateFullGeneratorName(
-      GeneratorName, ExtraGeneratorName);
-
-  cm->SetHomeDirectory(SourceDirectory);
-  cm->SetHomeOutputDirectory(BuildDirectory);
-
-  auto gg = cm->CreateGlobalGenerator(fullGeneratorName);
-  if (!gg) {
-    setErrorMessage(
-      errorMessage,
-      std::string("Could not set up the requested combination of \"") +
-        kGENERATOR_KEY + "\" and \"" + kEXTRA_GENERATOR_KEY + "\"");
-    return;
-  }
-
-  cm->SetGlobalGenerator(std::move(gg));
-
-  cm->SetGeneratorToolset(Toolset);
-  cm->SetGeneratorPlatform(Platform);
-}
diff --git a/Source/cmServerProtocol.h b/Source/cmServerProtocol.h
deleted file mode 100644
index 6009e23..0000000
--- a/Source/cmServerProtocol.h
+++ /dev/null
@@ -1,162 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
-   file Copyright.txt or https://cmake.org/licensing for details.  */
-#pragma once
-
-#include "cmConfigure.h" // IWYU pragma: keep
-
-#include <memory>
-#include <string>
-#include <utility>
-
-#include <cm3p/json/value.h>
-
-#include "cmake.h"
-
-class cmConnection;
-class cmFileMonitor;
-class cmServer;
-class cmServerRequest;
-
-class cmServerResponse
-{
-public:
-  explicit cmServerResponse(const cmServerRequest& request);
-
-  void SetData(const Json::Value& data);
-  void SetError(const std::string& message);
-
-  bool IsComplete() const;
-  bool IsError() const;
-  std::string ErrorMessage() const;
-  Json::Value Data() const;
-
-  const std::string Type;
-  const std::string Cookie;
-
-private:
-  enum PayLoad
-  {
-    PAYLOAD_UNKNOWN,
-    PAYLOAD_ERROR,
-    PAYLOAD_DATA
-  };
-  PayLoad m_Payload = PAYLOAD_UNKNOWN;
-  std::string m_ErrorMessage;
-  Json::Value m_Data;
-};
-
-class cmServerRequest
-{
-public:
-  cmServerResponse Reply(const Json::Value& data) const;
-  cmServerResponse ReportError(const std::string& message) const;
-
-  const std::string Type;
-  const std::string Cookie;
-  const Json::Value Data;
-  cmConnection* Connection;
-
-private:
-  cmServerRequest(cmServer* server, cmConnection* connection, std::string t,
-                  std::string c, Json::Value d);
-
-  void ReportProgress(int min, int current, int max,
-                      const std::string& message) const;
-  void ReportMessage(const std::string& message,
-                     const std::string& title) const;
-
-  cmServer* m_Server;
-
-  friend class cmServer;
-};
-
-class cmServerProtocol
-{
-public:
-  cmServerProtocol() = default;
-  virtual ~cmServerProtocol() = default;
-
-  cmServerProtocol(cmServerProtocol const&) = delete;
-  cmServerProtocol& operator=(cmServerProtocol const&) = delete;
-
-  virtual std::pair<int, int> ProtocolVersion() const = 0;
-  virtual bool IsExperimental() const = 0;
-  virtual cmServerResponse Process(const cmServerRequest& request) = 0;
-
-  bool Activate(cmServer* server, const cmServerRequest& request,
-                std::string* errorMessage);
-
-  cmFileMonitor* FileMonitor() const;
-  void SendSignal(const std::string& name, const Json::Value& data) const;
-
-protected:
-  cmake* CMakeInstance() const;
-  // Implement protocol specific activation tasks here. Called from Activate().
-  virtual bool DoActivate(const cmServerRequest& request,
-                          std::string* errorMessage);
-  bool m_WarnUnused = false; // storage for legacy option
-
-private:
-  std::unique_ptr<cmake> m_CMakeInstance;
-  cmServer* m_Server = nullptr; // not owned!
-
-  friend class cmServer;
-};
-
-class cmServerProtocol1 : public cmServerProtocol
-{
-public:
-  std::pair<int, int> ProtocolVersion() const override;
-  bool IsExperimental() const override;
-  cmServerResponse Process(const cmServerRequest& request) override;
-
-private:
-  bool DoActivate(const cmServerRequest& request,
-                  std::string* errorMessage) override;
-
-  void HandleCMakeFileChanges(const std::string& path, int event, int status);
-
-  // Handle requests:
-  cmServerResponse ProcessCache(const cmServerRequest& request);
-  cmServerResponse ProcessCMakeInputs(const cmServerRequest& request);
-  cmServerResponse ProcessCodeModel(const cmServerRequest& request);
-  cmServerResponse ProcessCompute(const cmServerRequest& request);
-  cmServerResponse ProcessConfigure(const cmServerRequest& request);
-  cmServerResponse ProcessGlobalSettings(const cmServerRequest& request);
-  cmServerResponse ProcessSetGlobalSettings(const cmServerRequest& request);
-  cmServerResponse ProcessFileSystemWatchers(const cmServerRequest& request);
-  cmServerResponse ProcessCTests(const cmServerRequest& request);
-
-  enum State
-  {
-    STATE_INACTIVE,
-    STATE_ACTIVE,
-    STATE_CONFIGURED,
-    STATE_COMPUTED
-  };
-  State m_State = STATE_INACTIVE;
-
-  bool m_isDirty = false;
-
-  struct GeneratorInformation
-  {
-  public:
-    GeneratorInformation() = default;
-    GeneratorInformation(std::string generatorName,
-                         std::string extraGeneratorName, std::string toolset,
-                         std::string platform, std::string sourceDirectory,
-                         std::string buildDirectory);
-
-    void SetupGenerator(cmake* cm, std::string* errorMessage);
-
-    std::string GeneratorName;
-    std::string ExtraGeneratorName;
-    std::string Toolset;
-    std::string Platform;
-
-    std::string SourceDirectory;
-    std::string BuildDirectory;
-  };
-
-  GeneratorInformation GeneratorInfo;
-};
diff --git a/Source/cmSourceFile.cxx b/Source/cmSourceFile.cxx
index ef44a57..39074a5 100644
--- a/Source/cmSourceFile.cxx
+++ b/Source/cmSourceFile.cxx
@@ -8,6 +8,7 @@
 #include "cmListFileCache.h"
 #include "cmMakefile.h"
 #include "cmMessageType.h"
+#include "cmPolicies.h"
 #include "cmProperty.h"
 #include "cmState.h"
 #include "cmStringAlgorithms.h"
@@ -93,10 +94,11 @@
   return this->Location;
 }
 
-std::string const& cmSourceFile::ResolveFullPath(std::string* error)
+std::string const& cmSourceFile::ResolveFullPath(std::string* error,
+                                                 std::string* cmp0115Warning)
 {
   if (this->FullPath.empty()) {
-    if (this->FindFullPath(error)) {
+    if (this->FindFullPath(error, cmp0115Warning)) {
       this->CheckExtension();
     }
   }
@@ -108,7 +110,8 @@
   return this->FullPath;
 }
 
-bool cmSourceFile::FindFullPath(std::string* error)
+bool cmSourceFile::FindFullPath(std::string* error,
+                                std::string* cmp0115Warning)
 {
   // If the file is generated compute the location without checking on disk.
   if (this->GetIsGenerated()) {
@@ -131,9 +134,11 @@
   // List of extension lists
   std::vector<std::string> exts =
     makefile->GetCMakeInstance()->GetAllExtensions();
+  auto cmp0115 = makefile->GetPolicyStatus(cmPolicies::CMP0115);
 
   // Tries to find the file in a given directory
-  auto findInDir = [this, &exts, &lPath](std::string const& dir) -> bool {
+  auto findInDir = [this, &exts, &lPath, cmp0115, cmp0115Warning,
+                    makefile](std::string const& dir) -> bool {
     // Compute full path
     std::string const fullPath = cmSystemTools::CollapseFullPath(lPath, dir);
     // Try full path
@@ -141,13 +146,29 @@
       this->FullPath = fullPath;
       return true;
     }
-    // Try full path with extension
-    for (std::string const& ext : exts) {
-      if (!ext.empty()) {
-        std::string extPath = cmStrCat(fullPath, '.', ext);
-        if (cmSystemTools::FileExists(extPath)) {
-          this->FullPath = extPath;
-          return true;
+    // This has to be an if statement due to a bug in Oracle Developer Studio.
+    // See https://community.oracle.com/tech/developers/discussion/4476246/
+    // for details.
+    if (cmp0115 == cmPolicies::OLD || cmp0115 == cmPolicies::WARN) {
+      // Try full path with extension
+      for (std::string const& ext : exts) {
+        if (!ext.empty()) {
+          std::string extPath = cmStrCat(fullPath, '.', ext);
+          if (cmSystemTools::FileExists(extPath)) {
+            this->FullPath = extPath;
+            if (cmp0115 == cmPolicies::WARN) {
+              std::string warning =
+                cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0115),
+                         "\nFile:\n  ", extPath);
+              if (cmp0115Warning) {
+                *cmp0115Warning = std::move(warning);
+              } else {
+                makefile->GetCMakeInstance()->IssueMessage(
+                  MessageType::AUTHOR_WARNING, warning);
+              }
+            }
+            return true;
+          }
         }
       }
     }
@@ -168,11 +189,19 @@
   }
 
   // Compose error
-  std::string err =
-    cmStrCat("Cannot find source file:\n  ", lPath, "\nTried extensions");
-  for (std::string const& ext : exts) {
-    err += " .";
-    err += ext;
+  std::string err = cmStrCat("Cannot find source file:\n  ", lPath);
+  switch (cmp0115) {
+    case cmPolicies::OLD:
+    case cmPolicies::WARN:
+      err = cmStrCat(err, "\nTried extensions");
+      for (auto const& ext : exts) {
+        err = cmStrCat(err, " .", ext);
+      }
+      break;
+    case cmPolicies::REQUIRED_IF_USED:
+    case cmPolicies::REQUIRED_ALWAYS:
+    case cmPolicies::NEW:
+      break;
   }
   if (error != nullptr) {
     *error = std::move(err);
@@ -281,7 +310,7 @@
   }
 }
 
-const char* cmSourceFile::GetPropertyForUser(const std::string& prop)
+cmProp cmSourceFile::GetPropertyForUser(const std::string& prop)
 {
   // This method is a consequence of design history and backwards
   // compatibility.  GetProperty is (and should be) a const method.
@@ -305,13 +334,12 @@
   // Similarly, LANGUAGE can be determined by the file extension
   // if it is requested by the user.
   if (prop == propLANGUAGE) {
-    // The c_str pointer is valid until `this->Language` is modified.
-    return this->GetOrDetermineLanguage().c_str();
+    // The pointer is valid until `this->Language` is modified.
+    return &this->GetOrDetermineLanguage();
   }
 
   // Perform the normal property lookup.
-  cmProp p = this->GetProperty(prop);
-  return p ? p->c_str() : nullptr;
+  return this->GetProperty(prop);
 }
 
 cmProp cmSourceFile::GetProperty(const std::string& prop) const
@@ -369,13 +397,15 @@
   return retVal;
 }
 
-const char* cmSourceFile::GetSafeProperty(const std::string& prop) const
+const std::string& cmSourceFile::GetSafeProperty(const std::string& prop) const
 {
   cmProp ret = this->GetProperty(prop);
-  if (!ret) {
-    return "";
+  if (ret) {
+    return *ret;
   }
-  return ret->c_str();
+
+  static std::string const s_empty;
+  return s_empty;
 }
 
 bool cmSourceFile::GetPropertyAsBool(const std::string& prop) const
diff --git a/Source/cmSourceFile.h b/Source/cmSourceFile.h
index 39ea8e3..3ad2664 100644
--- a/Source/cmSourceFile.h
+++ b/Source/cmSourceFile.h
@@ -47,12 +47,12 @@
   //! Might return a nullptr if the property is not set or invalid
   cmProp GetProperty(const std::string& prop) const;
   //! Always returns a valid pointer
-  const char* GetSafeProperty(const std::string& prop) const;
+  const std::string& GetSafeProperty(const std::string& prop) const;
   bool GetPropertyAsBool(const std::string& prop) const;
 
   /** Implement getting a property when called from a CMake language
       command like get_property or get_source_file_property.  */
-  const char* GetPropertyForUser(const std::string& prop);
+  cmProp GetPropertyForUser(const std::string& prop);
 
   //! Checks is the GENERATED property is set and true
   /// @return Equivalent to GetPropertyAsBool("GENERATED")
@@ -77,7 +77,8 @@
    * Resolves the full path to the file.  Attempts to locate the file on disk
    * and finalizes its location.
    */
-  std::string const& ResolveFullPath(std::string* error = nullptr);
+  std::string const& ResolveFullPath(std::string* error = nullptr,
+                                     std::string* cmp0115Warning = nullptr);
 
   /**
    * The resolved full path to the file.  The returned file name might be empty
@@ -138,7 +139,7 @@
   bool FindFullPathFailed = false;
   bool IsGenerated = false;
 
-  bool FindFullPath(std::string* error);
+  bool FindFullPath(std::string* error, std::string* cmp0115Warning);
   void CheckExtension();
   void CheckLanguage(std::string const& ext);
 
diff --git a/Source/cmSourceFileLocation.cxx b/Source/cmSourceFileLocation.cxx
index 222bafa..921eb0e 100644
--- a/Source/cmSourceFileLocation.cxx
+++ b/Source/cmSourceFileLocation.cxx
@@ -33,8 +33,7 @@
   this->AmbiguousExtension = true;
   this->Directory = cmSystemTools::GetFilenamePath(name);
   if (cmSystemTools::FileIsFullPath(this->Directory)) {
-    this->Directory = cmSystemTools::CollapseFullPath(
-      this->Directory, mf->GetHomeOutputDirectory());
+    this->Directory = cmSystemTools::CollapseFullPath(this->Directory);
   }
   this->Name = cmSystemTools::GetFilenameName(name);
   if (kind == cmSourceFileLocationKind::Known) {
diff --git a/Source/cmState.cxx b/Source/cmState.cxx
index d268e62..3692a01 100644
--- a/Source/cmState.cxx
+++ b/Source/cmState.cxx
@@ -441,6 +441,19 @@
     });
 }
 
+void cmState::AddFlowControlCommand(std::string const& name, Command command)
+{
+  this->FlowControlCommands.insert(name);
+  this->AddBuiltinCommand(name, std::move(command));
+}
+
+void cmState::AddFlowControlCommand(std::string const& name,
+                                    BuiltinCommand command)
+{
+  this->FlowControlCommands.insert(name);
+  this->AddBuiltinCommand(name, command);
+}
+
 void cmState::AddDisallowedCommand(std::string const& name,
                                    BuiltinCommand command,
                                    cmPolicies::PolicyID policy,
@@ -470,7 +483,7 @@
 
 void cmState::AddUnexpectedCommand(std::string const& name, const char* error)
 {
-  this->AddBuiltinCommand(
+  this->AddFlowControlCommand(
     name,
     [name, error](std::vector<cmListFileArgument> const&,
                   cmExecutionStatus& status) -> bool {
@@ -485,16 +498,28 @@
     });
 }
 
-void cmState::AddScriptedCommand(std::string const& name, Command command)
+bool cmState::AddScriptedCommand(std::string const& name, BT<Command> command,
+                                 cmMakefile& mf)
 {
   std::string sName = cmSystemTools::LowerCase(name);
 
+  if (this->FlowControlCommands.count(sName)) {
+    mf.GetCMakeInstance()->IssueMessage(
+      MessageType::FATAL_ERROR,
+      cmStrCat("Built-in flow control command \"", sName,
+               "\" cannot be overridden."),
+      command.Backtrace);
+    cmSystemTools::SetFatalErrorOccured();
+    return false;
+  }
+
   // if the command already exists, give a new name to the old command.
   if (Command oldCmd = this->GetCommandByExactName(sName)) {
     this->ScriptedCommands["_" + sName] = oldCmd;
   }
 
-  this->ScriptedCommands[sName] = std::move(command);
+  this->ScriptedCommands[sName] = std::move(command.Value);
+  return true;
 }
 
 cmState::Command cmState::GetCommand(std::string const& name) const
diff --git a/Source/cmState.h b/Source/cmState.h
index e4c9eb5..4e41156 100644
--- a/Source/cmState.h
+++ b/Source/cmState.h
@@ -9,6 +9,7 @@
 #include <set>
 #include <string>
 #include <unordered_map>
+#include <unordered_set>
 #include <vector>
 
 #include "cmDefinitions.h"
@@ -24,6 +25,7 @@
 class cmCacheManager;
 class cmCommand;
 class cmGlobVerificationManager;
+class cmMakefile;
 class cmStateSnapshot;
 class cmMessenger;
 class cmExecutionStatus;
@@ -159,10 +161,13 @@
                          std::unique_ptr<cmCommand> command);
   void AddBuiltinCommand(std::string const& name, Command command);
   void AddBuiltinCommand(std::string const& name, BuiltinCommand command);
+  void AddFlowControlCommand(std::string const& name, Command command);
+  void AddFlowControlCommand(std::string const& name, BuiltinCommand command);
   void AddDisallowedCommand(std::string const& name, BuiltinCommand command,
                             cmPolicies::PolicyID policy, const char* message);
   void AddUnexpectedCommand(std::string const& name, const char* error);
-  void AddScriptedCommand(std::string const& name, Command command);
+  bool AddScriptedCommand(std::string const& name, BT<Command> command,
+                          cmMakefile& mf);
   void RemoveBuiltinCommand(std::string const& name);
   void RemoveUserDefinedCommands();
   std::vector<std::string> GetCommandNames() const;
@@ -225,6 +230,7 @@
   std::vector<std::string> EnabledLanguages;
   std::unordered_map<std::string, Command> BuiltinCommands;
   std::unordered_map<std::string, Command> ScriptedCommands;
+  std::unordered_set<std::string> FlowControlCommands;
   cmPropertyMap GlobalProperties;
   std::unique_ptr<cmCacheManager> CacheManager;
   std::unique_ptr<cmGlobVerificationManager> GlobVerificationManager;
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index e076d1e..35224eb 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -213,7 +213,7 @@
   bool CheckImportedLibName(std::string const& prop,
                             std::string const& value) const;
 
-  std::string ProcessSourceItemCMP0049(const std::string& s);
+  std::string ProcessSourceItemCMP0049(const std::string& s) const;
 };
 
 namespace {
@@ -372,6 +372,8 @@
     initProp("ISPC_INSTRUCTION_SETS");
     initProp("LINK_SEARCH_START_STATIC");
     initProp("LINK_SEARCH_END_STATIC");
+    initProp("OBJC_CLANG_TIDY");
+    initProp("OBJCXX_CLANG_TIDY");
     initProp("Swift_LANGUAGE_VERSION");
     initProp("Swift_MODULE_DIRECTORY");
     initProp("VS_JUST_MY_CODE_DEBUGGING");
@@ -623,6 +625,11 @@
     { name, cross }, mf ? mf->GetBacktrace() : cmListFileBacktrace()));
 }
 
+void cmTarget::AddUtility(BT<std::pair<std::string, bool>> util)
+{
+  impl->Utilities.emplace(std::move(util));
+}
+
 std::set<BT<std::pair<std::string, bool>>> const& cmTarget::GetUtilities()
   const
 {
@@ -740,7 +747,8 @@
   }
 }
 
-std::string cmTargetInternals::ProcessSourceItemCMP0049(const std::string& s)
+std::string cmTargetInternals::ProcessSourceItemCMP0049(
+  const std::string& s) const
 {
   std::string src = s;
 
@@ -791,7 +799,7 @@
   {
   }
 
-  cmSourceFileLocation operator()(const std::string& filename)
+  cmSourceFileLocation operator()(const std::string& filename) const
   {
     return cmSourceFileLocation(this->Makefile, filename);
   }
@@ -857,7 +865,7 @@
                                            cmSourceFileLocationKind::Known);
 }
 
-void cmTarget::ClearDependencyInformation(cmMakefile& mf)
+void cmTarget::ClearDependencyInformation(cmMakefile& mf) const
 {
   std::string depname = cmStrCat(this->GetName(), "_LIB_DEPENDS");
   mf.RemoveCacheDefinition(depname);
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index d8f66bc..27f0c59 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -114,7 +114,7 @@
   LinkLibraryVectorType const& GetOriginalLinkLibraries() const;
 
   //! Clear the dependency information recorded for this target, if any.
-  void ClearDependencyInformation(cmMakefile& mf);
+  void ClearDependencyInformation(cmMakefile& mf) const;
 
   void AddLinkLibrary(cmMakefile& mf, std::string const& lib,
                       cmTargetLinkLibraryType llt);
@@ -164,6 +164,7 @@
    */
   void AddUtility(std::string const& name, bool cross,
                   cmMakefile* mf = nullptr);
+  void AddUtility(BT<std::pair<std::string, bool>> util);
   //! Get the utilities used by this target
   std::set<BT<std::pair<std::string, bool>>> const& GetUtilities() const;
 
diff --git a/Source/cmTargetPropCommandBase.cxx b/Source/cmTargetPropCommandBase.cxx
index 9e30136..b050a58 100644
--- a/Source/cmTargetPropCommandBase.cxx
+++ b/Source/cmTargetPropCommandBase.cxx
@@ -45,15 +45,26 @@
     this->HandleMissingTarget(args[0]);
     return false;
   }
-  if ((this->Target->GetType() != cmStateEnums::EXECUTABLE) &&
-      (this->Target->GetType() != cmStateEnums::STATIC_LIBRARY) &&
-      (this->Target->GetType() != cmStateEnums::SHARED_LIBRARY) &&
-      (this->Target->GetType() != cmStateEnums::MODULE_LIBRARY) &&
-      (this->Target->GetType() != cmStateEnums::OBJECT_LIBRARY) &&
-      (this->Target->GetType() != cmStateEnums::INTERFACE_LIBRARY) &&
-      (this->Target->GetType() != cmStateEnums::UNKNOWN_LIBRARY)) {
-    this->SetError("called with non-compilable target type");
-    return false;
+  const bool isRegularTarget =
+    (this->Target->GetType() == cmStateEnums::EXECUTABLE) ||
+    (this->Target->GetType() == cmStateEnums::STATIC_LIBRARY) ||
+    (this->Target->GetType() == cmStateEnums::SHARED_LIBRARY) ||
+    (this->Target->GetType() == cmStateEnums::MODULE_LIBRARY) ||
+    (this->Target->GetType() == cmStateEnums::OBJECT_LIBRARY) ||
+    (this->Target->GetType() == cmStateEnums::INTERFACE_LIBRARY) ||
+    (this->Target->GetType() == cmStateEnums::UNKNOWN_LIBRARY);
+  const bool isCustomTarget = this->Target->GetType() == cmStateEnums::UTILITY;
+
+  if (prop == "SOURCES") {
+    if (!isRegularTarget && !isCustomTarget) {
+      this->SetError("called with non-compilable target type");
+      return false;
+    }
+  } else {
+    if (!isRegularTarget) {
+      this->SetError("called with non-compilable target type");
+      return false;
+    }
   }
 
   bool system = false;
@@ -131,6 +142,11 @@
       this->SetError("may only set INTERFACE properties on IMPORTED targets");
       return false;
     }
+    if (this->Target->GetType() == cmStateEnums::UTILITY &&
+        scope != "PRIVATE") {
+      this->SetError("may only set PRIVATE properties on custom targets");
+      return false;
+    }
   }
   return this->PopulateTargetProperies(scope, content, prepend, system);
 }
diff --git a/Source/cmTransformDepfile.cxx b/Source/cmTransformDepfile.cxx
new file mode 100644
index 0000000..e1f8753
--- /dev/null
+++ b/Source/cmTransformDepfile.cxx
@@ -0,0 +1,114 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file Copyright.txt or https://cmake.org/licensing for details.  */
+#include "cmTransformDepfile.h"
+
+#include <string>
+#include <type_traits>
+#include <utility>
+#include <vector>
+
+#include <cm/optional>
+
+#include "cmsys/FStream.hxx"
+
+#include "cmGccDepfileReader.h"
+#include "cmGccDepfileReaderTypes.h"
+#include "cmStringAlgorithms.h"
+#include "cmSystemTools.h"
+
+namespace {
+void WriteFilenameGcc(cmsys::ofstream& fout, const std::string& filename)
+{
+  for (auto c : filename) {
+    switch (c) {
+      case ' ':
+        fout << "\\ ";
+        break;
+      case '\\':
+        fout << "\\\\";
+        break;
+      default:
+        fout << c;
+        break;
+    }
+  }
+}
+
+void WriteGccDepfile(cmsys::ofstream& fout, const cmGccDepfileContent& content)
+{
+  for (auto const& dep : content) {
+    bool first = true;
+    for (auto const& rule : dep.rules) {
+      if (!first) {
+        fout << " \\\n  ";
+      }
+      first = false;
+      WriteFilenameGcc(fout, rule);
+    }
+    fout << ':';
+    for (auto const& path : dep.paths) {
+      fout << " \\\n  " << path;
+    }
+    fout << '\n';
+  }
+}
+
+void WriteVsTlog(cmsys::ofstream& fout, const cmGccDepfileContent& content)
+{
+  for (auto const& dep : content) {
+    fout << '^';
+    bool first = true;
+    for (auto const& rule : dep.rules) {
+      if (!first) {
+        fout << '|';
+      }
+      first = false;
+      fout << cmSystemTools::ConvertToOutputPath(rule);
+    }
+    fout << "\r\n";
+    for (auto const& path : dep.paths) {
+      fout << cmSystemTools::ConvertToOutputPath(path) << "\r\n";
+    }
+  }
+}
+}
+
+bool cmTransformDepfile(cmDepfileFormat format, const std::string& prefix,
+                        const std::string& infile, const std::string& outfile)
+{
+  cmGccDepfileContent content;
+  if (cmSystemTools::FileExists(infile)) {
+    auto result = cmReadGccDepfile(infile.c_str());
+    if (!result) {
+      return false;
+    }
+    content = *std::move(result);
+  }
+
+  for (auto& dep : content) {
+    for (auto& rule : dep.rules) {
+      if (!cmSystemTools::FileIsFullPath(rule)) {
+        rule = cmStrCat(prefix, rule);
+      }
+    }
+    for (auto& path : dep.paths) {
+      if (!cmSystemTools::FileIsFullPath(path)) {
+        path = cmStrCat(prefix, path);
+      }
+    }
+  }
+
+  cmsys::ofstream fout(outfile.c_str());
+  if (!fout) {
+    return false;
+  }
+  switch (format) {
+    case cmDepfileFormat::GccDepfile:
+      WriteGccDepfile(fout, content);
+      break;
+    case cmDepfileFormat::VsTlog:
+      WriteVsTlog(fout, content);
+      break;
+  }
+  return true;
+}
diff --git a/Source/cmTransformDepfile.h b/Source/cmTransformDepfile.h
new file mode 100644
index 0000000..792c1aa
--- /dev/null
+++ b/Source/cmTransformDepfile.h
@@ -0,0 +1,14 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file Copyright.txt or https://cmake.org/licensing for details.  */
+#pragma once
+
+#include <string>
+
+enum class cmDepfileFormat
+{
+  GccDepfile,
+  VsTlog,
+};
+
+bool cmTransformDepfile(cmDepfileFormat format, const std::string& prefix,
+                        const std::string& infile, const std::string& outfile);
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index a482ed6..ab66fd0 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -676,7 +676,7 @@
           cmStrCat(this->DefaultArtifactDir, "\\nasm.props");
         ConvertToWindowsSlash(propsLocal);
         this->Makefile->ConfigureFile(propsTemplate, propsLocal, false, true,
-                                      true, true);
+                                      true);
         Elem(e1, "Import").Attribute("Project", propsLocal);
       }
     }
@@ -1020,9 +1020,9 @@
             cm::string_view tagName =
               cm::string_view(p).substr(propNamePrefix.length());
             if (!tagName.empty()) {
-              const std::string& value = *props.GetPropertyValue(p);
-              if (!value.empty()) {
-                e2.Element(tagName, value);
+              cmProp value = props.GetPropertyValue(p);
+              if (cmNonempty(value)) {
+                e2.Element(tagName, *value);
               }
             }
           }
@@ -2402,27 +2402,28 @@
       configDefines += *ccdefs;
     }
 
-    // Add precompile headers compile options.
-    std::string customAndPchOptions = options;
+    // We have pch state in the following situation:
+    // 1. We have SKIP_PRECOMPILE_HEADERS == true
+    // 2. We are creating the pre-compiled header
+    // 3. We are a different language than the linker language AND pch is
+    // enabled
     const std::string pchSource =
       this->GeneratorTarget->GetPchSource(config, lang);
-    if (!pchSource.empty() && !sf.GetProperty("SKIP_PRECOMPILE_HEADERS")) {
-      std::string pchOptions;
-      if (sf.GetFullPath() == pchSource) {
-        pchOptions =
-          this->GeneratorTarget->GetPchCreateCompileOptions(config, lang);
-      } else {
-        pchOptions =
-          this->GeneratorTarget->GetPchUseCompileOptions(config, lang);
-      }
-      customAndPchOptions = cmStrCat(customAndPchOptions, ';', pchOptions);
-    }
+    const bool skipPCH =
+      pchSource.empty() || sf.GetPropertyAsBool("SKIP_PRECOMPILE_HEADERS");
+    const bool makePCH = (sf.GetFullPath() == pchSource);
+    const bool useSharedPCH =
+      !skipPCH && (lang == this->GeneratorTarget->GetLinkerLanguage(config));
+    const bool useDifferentLangPCH =
+      !skipPCH && (lang != this->GeneratorTarget->GetLinkerLanguage(config));
+    const bool needsPCHFlags =
+      (makePCH || useSharedPCH || useDifferentLangPCH);
 
     // if we have flags or defines for this config then
     // use them
     if (!flags.empty() || !options.empty() || !configDefines.empty() ||
-        !includes.empty() || compileAs || noWinRT ||
-        !customAndPchOptions.empty()) {
+        !includes.empty() || compileAs || noWinRT || !options.empty() ||
+        needsPCHFlags) {
       cmGlobalVisualStudio10Generator* gg = this->GlobalGenerator;
       cmIDEFlagTable const* flagtable = nullptr;
       const std::string& srclang = source->GetLanguage();
@@ -2455,15 +2456,35 @@
       } else {
         clOptions.Parse(flags);
       }
-      if (!customAndPchOptions.empty()) {
+
+      if (needsPCHFlags) {
+        // Add precompile headers compile options.
+        std::string expandedOptions;
+        std::string pchOptions;
+        if (makePCH) {
+          pchOptions =
+            this->GeneratorTarget->GetPchCreateCompileOptions(config, lang);
+        } else if (useSharedPCH) {
+          std::string pchHeader =
+            this->GeneratorTarget->GetPchHeader(config, lang);
+          clOptions.AddFlag("ForcedIncludeFiles", pchHeader);
+        } else if (useDifferentLangPCH) {
+          pchOptions =
+            this->GeneratorTarget->GetPchUseCompileOptions(config, lang);
+        }
+        this->LocalGenerator->AppendCompileOptions(expandedOptions,
+                                                   pchOptions);
+        clOptions.Parse(expandedOptions);
+      }
+
+      if (!options.empty()) {
         std::string expandedOptions;
         if (configDependentOptions) {
           this->LocalGenerator->AppendCompileOptions(
             expandedOptions,
-            genexInterpreter.Evaluate(customAndPchOptions, "COMPILE_OPTIONS"));
+            genexInterpreter.Evaluate(options, "COMPILE_OPTIONS"));
         } else {
-          this->LocalGenerator->AppendCompileOptions(expandedOptions,
-                                                     customAndPchOptions);
+          this->LocalGenerator->AppendCompileOptions(expandedOptions, options);
         }
         clOptions.Parse(expandedOptions);
       }
@@ -2786,6 +2807,13 @@
     this->GeneratorTarget->GetPchHeader(configName, linkLanguage);
   if (this->MSTools && vcxproj == this->ProjectType && pchHeader.empty()) {
     clOptions.AddFlag("PrecompiledHeader", "NotUsing");
+  } else if (this->MSTools && vcxproj == this->ProjectType &&
+             !pchHeader.empty()) {
+    clOptions.AddFlag("PrecompiledHeader", "Use");
+    clOptions.AddFlag("PrecompiledHeaderFile", pchHeader);
+    std::string pchFile =
+      this->GeneratorTarget->GetPchFile(configName, linkLanguage);
+    clOptions.AddFlag("PrecompiledHeaderOutputFile", pchFile);
   }
 
   // Get preprocessor definitions for this directory.
@@ -4182,8 +4210,7 @@
     cmLocalGenerator* lg = dt->GetLocalGenerator();
     std::string name = dt->GetName();
     std::string path;
-    cmProp p = dt->GetProperty("EXTERNAL_MSPROJECT");
-    if (p) {
+    if (cmProp p = dt->GetProperty("EXTERNAL_MSPROJECT")) {
       path = *p;
     } else {
       path = cmStrCat(lg->GetCurrentBinaryDirectory(), '/', dt->GetName(),
@@ -4971,9 +4998,9 @@
       if (cmHasPrefix(p, propNamePrefix)) {
         std::string tagName = p.substr(propNamePrefix.length());
         if (!tagName.empty()) {
-          const std::string& val = *props.GetPropertyValue(p);
-          if (!val.empty()) {
-            tags[tagName] = val;
+          cmProp val = props.GetPropertyValue(p);
+          if (cmNonempty(val)) {
+            tags[tagName] = *val;
           } else {
             tags.erase(tagName);
           }
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index 60a493c..4a2bb49 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -263,7 +263,7 @@
   }
   obj["generators"] = generators;
   obj["fileApi"] = cmFileAPI::ReportCapabilities();
-  obj["serverMode"] = true;
+  obj["serverMode"] = false;
 
   return obj;
 }
@@ -1949,7 +1949,7 @@
     }
   }
 
-  auto& mf = this->GlobalGenerator->GetMakefiles()[0];
+  const auto& mf = this->GlobalGenerator->GetMakefiles()[0];
   if (mf->IsOn("CTEST_USE_LAUNCHERS") &&
       !this->State->GetGlobalProperty("RULE_LAUNCH_COMPILE")) {
     cmSystemTools::Error(
@@ -2291,12 +2291,12 @@
   return this->State->GetInitializedCacheValue(name);
 }
 
-void cmake::AddScriptingCommands()
+void cmake::AddScriptingCommands() const
 {
   GetScriptingCommands(this->GetState());
 }
 
-void cmake::AddProjectCommands()
+void cmake::AddProjectCommands() const
 {
   GetProjectCommands(this->GetState());
 }
@@ -2571,8 +2571,7 @@
 
   if (this->ClearBuildSystem) {
     // Get the generator used for this build system.
-    const char* genName =
-      cmToCStr(mf.GetDefinition("CMAKE_DEPENDS_GENERATOR"));
+    std::string genName = mf.GetSafeDefinition("CMAKE_DEPENDS_GENERATOR");
     if (!cmNonempty(genName)) {
       genName = "Unix Makefiles";
     }
diff --git a/Source/cmake.h b/Source/cmake.h
index 1ecf2c2..914b827 100644
--- a/Source/cmake.h
+++ b/Source/cmake.h
@@ -411,7 +411,7 @@
   WorkingMode GetWorkingMode() { return this->CurrentWorkingMode; }
 
   //! Debug the try compile stuff by not deleting the files
-  bool GetDebugTryCompile() { return this->DebugTryCompile; }
+  bool GetDebugTryCompile() const { return this->DebugTryCompile; }
   void DebugTryCompileOn() { this->DebugTryCompile = true; }
 
   /**
@@ -456,11 +456,11 @@
   void SetShowLogContext(bool b) { this->LogContext = b; }
 
   //! Do we want debug output during the cmake run.
-  bool GetDebugOutput() { return this->DebugOutput; }
+  bool GetDebugOutput() const { return this->DebugOutput; }
   void SetDebugOutputOn(bool b) { this->DebugOutput = b; }
 
   //! Do we want debug output from the find commands during the cmake run.
-  bool GetDebugFindOutput() { return this->DebugFindOutput; }
+  bool GetDebugFindOutput() const { return this->DebugFindOutput; }
   void SetDebugFindOutputOn(bool b) { this->DebugFindOutput = b; }
 
   //! Do we want trace output during the cmake run.
@@ -482,11 +482,11 @@
   void SetTraceFile(std::string const& file);
   void PrintTraceFormatVersion();
 
-  bool GetWarnUninitialized() { return this->WarnUninitialized; }
+  bool GetWarnUninitialized() const { return this->WarnUninitialized; }
   void SetWarnUninitialized(bool b) { this->WarnUninitialized = b; }
-  bool GetWarnUnusedCli() { return this->WarnUnusedCli; }
+  bool GetWarnUnusedCli() const { return this->WarnUnusedCli; }
   void SetWarnUnusedCli(bool b) { this->WarnUnusedCli = b; }
-  bool GetCheckSystemVars() { return this->CheckSystemVars; }
+  bool GetCheckSystemVars() const { return this->CheckSystemVars; }
   void SetCheckSystemVars(bool b) { this->CheckSystemVars = b; }
 
   void MarkCliAsUsed(const std::string& variable);
@@ -591,8 +591,8 @@
   using RegisteredExtraGeneratorsVector =
     std::vector<cmExternalMakefileProjectGeneratorFactory*>;
   RegisteredExtraGeneratorsVector ExtraGenerators;
-  void AddScriptingCommands();
-  void AddProjectCommands();
+  void AddScriptingCommands() const;
+  void AddProjectCommands() const;
   void AddDefaultGenerators();
   void AddDefaultExtraGenerators();
 
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx
index e2ff8b7..81374a1 100644
--- a/Source/cmcmd.cxx
+++ b/Source/cmcmd.cxx
@@ -20,6 +20,7 @@
 #include "cmStateSnapshot.h"
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
+#include "cmTransformDepfile.h"
 #include "cmUVProcessChain.h"
 #include "cmUtils.hxx"
 #include "cmVersion.h"
@@ -28,8 +29,6 @@
 #if !defined(CMAKE_BOOTSTRAP)
 #  include "cmDependsFortran.h" // For -E cmake_copy_f90_mod callback.
 #  include "cmFileTime.h"
-#  include "cmServer.h"
-#  include "cmServerConnection.h"
 
 #  include "bindexplib.h"
 #endif
@@ -59,10 +58,9 @@
 #include "cmsys/Directory.hxx"
 #include "cmsys/FStream.hxx"
 #include "cmsys/Process.h"
+#include "cmsys/RegularExpression.hxx"
 #include "cmsys/Terminal.h"
 
-class cmConnection;
-
 int cmcmd_cmake_ninja_depends(std::vector<std::string>::const_iterator argBeg,
                               std::vector<std::string>::const_iterator argEnd);
 int cmcmd_cmake_ninja_dyndep(std::vector<std::string>::const_iterator argBeg,
@@ -121,7 +119,6 @@
        "(on one volume)\n"
     << "  rm [-rRf] <file/dir>...    - remove files or directories, use -f to "
        "force it, r or R to remove directories and their contents recursively\n"
-    << "  server                    - start cmake in server mode\n"
     << "  sleep <number>...         - sleep for given number of seconds\n"
     << "  tar [cxt][vf][zjJ] file.tar [file/dir1 file/dir2 ...]\n"
     << "                            - create or extract a tar or zip archive\n"
@@ -1170,7 +1167,7 @@
       return cmcmd::ExecuteLinkScript(args);
     }
 
-#if !defined(CMAKE_BOOTSTRAP) || defined(CMAKE_BOOTSTRAP_NINJA)
+#if !defined(CMAKE_BOOTSTRAP)
     // Internal CMake ninja dependency scanning support.
     if (args[1] == "cmake_ninja_depends") {
       return cmcmd_cmake_ninja_depends(args.begin() + 2, args.end());
@@ -1359,47 +1356,8 @@
     }
 
     if (args[1] == "server") {
-      const std::string pipePrefix = "--pipe=";
-      bool supportExperimental = false;
-      bool isDebug = false;
-      std::string pipe;
-
-      for (auto const& arg : cmMakeRange(args).advance(2)) {
-        if (arg == "--experimental") {
-          supportExperimental = true;
-        } else if (arg == "--debug") {
-          pipe.clear();
-          isDebug = true;
-        } else if (cmHasPrefix(arg, pipePrefix)) {
-          isDebug = false;
-          pipe = arg.substr(pipePrefix.size());
-          if (pipe.empty()) {
-            cmSystemTools::Error("No pipe given after --pipe=");
-            return 2;
-          }
-        } else {
-          cmSystemTools::Error("Unknown argument for server mode");
-          return 1;
-        }
-      }
-#if !defined(CMAKE_BOOTSTRAP)
-      cmConnection* conn;
-      if (isDebug) {
-        conn = new cmServerStdIoConnection;
-      } else {
-        conn = new cmServerPipeConnection(pipe);
-      }
-      cmServer server(conn, supportExperimental);
-      std::string errorMessage;
-      if (server.Serve(&errorMessage)) {
-        return 0;
-      }
-      cmSystemTools::Error(errorMessage);
-#else
-      static_cast<void>(supportExperimental);
-      static_cast<void>(isDebug);
-      cmSystemTools::Error("CMake was not built with server mode enabled");
-#endif
+      cmSystemTools::Error(
+        "CMake server mode has been removed in favor of the file-api.");
       return 1;
     }
 
@@ -1435,6 +1393,23 @@
       return cmcmd::WindowsCEEnvironment("9.0", args[2]);
     }
 #endif
+
+    // Internal depfile transformation
+    if (args[1] == "cmake_transform_depfile" && args.size() == 6) {
+      auto format = cmDepfileFormat::GccDepfile;
+      if (args[2] == "gccdepfile") {
+        format = cmDepfileFormat::GccDepfile;
+      } else if (args[2] == "vstlog") {
+        format = cmDepfileFormat::VsTlog;
+      } else {
+        return 1;
+      }
+      std::string prefix = args[3];
+      if (prefix == "./") {
+        prefix.clear();
+      }
+      return cmTransformDepfile(format, prefix, args[4], args[5]) ? 0 : 1;
+    }
   }
 
   ::CMakeCommandUsage(args[0].c_str());
@@ -1737,7 +1712,6 @@
 int cmcmd::RunPreprocessor(const std::vector<std::string>& command,
                            const std::string& intermediate_file)
 {
-
   cmUVProcessChainBuilder builder;
 
   uv_fs_t fs_req;
@@ -1769,7 +1743,6 @@
 
     return 1;
   }
-
   return 0;
 }
 
@@ -1787,19 +1760,56 @@
     std::cerr << "Invalid cmake_llvm_rc arguments";
     return 1;
   }
+
   const std::string& intermediate_file = args[3];
   const std::string& source_file = args[2];
   std::vector<std::string> preprocess;
   std::vector<std::string> resource_compile;
   std::vector<std::string>* pArgTgt = &preprocess;
+
+  static const cmsys::RegularExpression llvm_rc_only_single_arg("^[-/](N|Y)");
+  static const cmsys::RegularExpression llvm_rc_only_double_arg(
+    "^[-/](C|LN|L)(.)?");
+  static const cmsys::RegularExpression common_double_arg(
+    "^[-/](D|U|I|FO|fo|Fo)(.)?");
+  bool acceptNextArg = false;
+  bool skipNextArg = false;
   for (std::string const& arg : cmMakeRange(args).advance(4)) {
+    if (skipNextArg) {
+      skipNextArg = false;
+      continue;
+    }
     // We use ++ as seperator between the preprocessing step definition and the
     // rc compilation step becase we need to prepend a -- to seperate the
     // source file properly from other options when using clang-cl for
     // preprocessing.
     if (arg == "++") {
       pArgTgt = &resource_compile;
+      skipNextArg = false;
+      acceptNextArg = true;
     } else {
+      cmsys::RegularExpressionMatch match;
+      if (!acceptNextArg) {
+        if (common_double_arg.find(arg.c_str(), match)) {
+          acceptNextArg = match.match(2).empty();
+        } else {
+          if (llvm_rc_only_single_arg.find(arg.c_str(), match)) {
+            if (pArgTgt == &preprocess) {
+              continue;
+            }
+          } else if (llvm_rc_only_double_arg.find(arg.c_str(), match)) {
+            if (pArgTgt == &preprocess) {
+              skipNextArg = match.match(2).empty();
+              continue;
+            }
+            acceptNextArg = match.match(2).empty();
+          } else if (pArgTgt == &resource_compile) {
+            continue;
+          }
+        }
+      } else {
+        acceptNextArg = false;
+      }
       if (arg.find("SOURCE_DIR") != std::string::npos) {
         std::string sourceDirArg = arg;
         cmSystemTools::ReplaceString(
@@ -1819,10 +1829,14 @@
     std::cerr << "Empty resource compilation command";
     return 1;
   }
+  // Since we might have skipped the last argument to llvm-rc
+  // we need to make sure the llvm-rc source file is present in the commandline
+  if (resource_compile.back() != intermediate_file) {
+    resource_compile.push_back(intermediate_file);
+  }
 
   auto result = RunPreprocessor(preprocess, intermediate_file);
   if (result != 0) {
-
     cmSystemTools::RemoveFile(intermediate_file);
     return result;
   }
@@ -1986,7 +2000,7 @@
               << NumberFormatter(exitFormat, retCode)
               << ") with the following output:\n"
               << output;
-  } else {
+  } else if (verbose) {
     // always print the output of the command, unless
     // it is the dumb rc command banner
     if (output.find("Resource Compiler Version") == std::string::npos) {
diff --git a/Tests/CMakeLib/testGccDepfileReader.cxx b/Tests/CMakeLib/testGccDepfileReader.cxx
index e79f047..d46e8f3 100644
--- a/Tests/CMakeLib/testGccDepfileReader.cxx
+++ b/Tests/CMakeLib/testGccDepfileReader.cxx
@@ -5,6 +5,8 @@
 #include <utility>
 #include <vector>
 
+#include <cm/optional>
+
 #include "cmsys/FStream.hxx"
 
 #include "cmGccDepfileReader.h"
@@ -112,17 +114,26 @@
 
   std::string dataDirPath = argv[1];
   dataDirPath += "/testGccDepfileReader_data";
-  const int numberOfTestFiles = 3;
+  const int numberOfTestFiles = 7; // 6th file doesn't exist
   for (int i = 1; i <= numberOfTestFiles; ++i) {
     const std::string base = dataDirPath + "/deps" + std::to_string(i);
     const std::string depfile = base + ".d";
     const std::string plainDepfile = base + ".txt";
     std::cout << "Comparing " << base << " with " << plainDepfile << std::endl;
     const auto actual = cmReadGccDepfile(depfile.c_str());
-    const auto expected = readPlainDepfile(plainDepfile.c_str());
-    if (!compare(actual, expected)) {
-      dump("actual", actual);
-      dump("expected", expected);
+    if (cmSystemTools::FileExists(plainDepfile)) {
+      if (!actual) {
+        std::cerr << "Reading " << depfile << " should have succeeded\n";
+        return 1;
+      }
+      const auto expected = readPlainDepfile(plainDepfile.c_str());
+      if (!compare(*actual, expected)) {
+        dump("actual", *actual);
+        dump("expected", expected);
+        return 1;
+      }
+    } else if (actual) {
+      std::cerr << "Reading " << depfile << " should have failed\n";
       return 1;
     }
   }
diff --git a/Tests/CMakeLib/testGccDepfileReader_data/deps4.d b/Tests/CMakeLib/testGccDepfileReader_data/deps4.d
new file mode 100644
index 0000000..9977a28
--- /dev/null
+++ b/Tests/CMakeLib/testGccDepfileReader_data/deps4.d
@@ -0,0 +1 @@
+invalid
diff --git a/Tests/CMakeLib/testGccDepfileReader_data/deps5.d b/Tests/CMakeLib/testGccDepfileReader_data/deps5.d
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/CMakeLib/testGccDepfileReader_data/deps5.d
diff --git a/Tests/CMakeLib/testGccDepfileReader_data/deps5.txt b/Tests/CMakeLib/testGccDepfileReader_data/deps5.txt
new file mode 100644
index 0000000..6c4a75b
--- /dev/null
+++ b/Tests/CMakeLib/testGccDepfileReader_data/deps5.txt
@@ -0,0 +1,2 @@
+--RULES--
+--DEPENDENCIES--
diff --git a/Tests/CMakeLib/testGccDepfileReader_data/deps7.d b/Tests/CMakeLib/testGccDepfileReader_data/deps7.d
new file mode 100644
index 0000000..92280cf
--- /dev/null
+++ b/Tests/CMakeLib/testGccDepfileReader_data/deps7.d
@@ -0,0 +1,6 @@
+out1 \
+  out2: \
+  in1 \
+  in2
+
+out3: in3
diff --git a/Tests/CMakeLib/testGccDepfileReader_data/deps7.txt b/Tests/CMakeLib/testGccDepfileReader_data/deps7.txt
new file mode 100644
index 0000000..86b6600
--- /dev/null
+++ b/Tests/CMakeLib/testGccDepfileReader_data/deps7.txt
@@ -0,0 +1,10 @@
+--RULES--
+out1
+out2
+--DEPENDENCIES--
+in1
+in2
+--RULES--
+out3
+--DEPENDENCIES--
+in3
diff --git a/Tests/CMakeLib/testOptional.cxx b/Tests/CMakeLib/testOptional.cxx
index de09c0f..2d7dd7c 100644
--- a/Tests/CMakeLib/testOptional.cxx
+++ b/Tests/CMakeLib/testOptional.cxx
@@ -82,6 +82,18 @@
   int Value = 0;
 };
 
+class NoMoveAssignEventLogger : public EventLogger
+{
+public:
+  using EventLogger::EventLogger;
+
+  NoMoveAssignEventLogger(const NoMoveAssignEventLogger&) = default;
+  NoMoveAssignEventLogger(NoMoveAssignEventLogger&&) = default;
+
+  NoMoveAssignEventLogger& operator=(const NoMoveAssignEventLogger&) = default;
+  NoMoveAssignEventLogger& operator=(NoMoveAssignEventLogger&&) = delete;
+};
+
 #define ASSERT_TRUE(x)                                                        \
   do {                                                                        \
     if (!(x)) {                                                               \
@@ -328,12 +340,28 @@
   o1 = o4; // Intentionally duplicated to test assigning an empty optional to
   // an empty optional
 
+  cm::optional<NoMoveAssignEventLogger> o5{ 1 };
+  auto const* v5 = &*o5;
+  const cm::optional<NoMoveAssignEventLogger> o6{ 2 };
+  auto const* v6 = &*o6;
+  o5 = std::move(o6);
+  const NoMoveAssignEventLogger e7{ 3 };
+  o5 = std::move(e7);
+
   expected = {
     { Event::VALUE_CONSTRUCT, v2, nullptr, 4 },
     { Event::COPY_CONSTRUCT, v1, v2, 4 },
     { Event::VALUE_CONSTRUCT, v3, nullptr, 5 },
     { Event::COPY_ASSIGN, v1, v3, 5 },
     { Event::DESTRUCT, v1, nullptr, 5 },
+    { Event::VALUE_CONSTRUCT, v5, nullptr, 1 },
+    { Event::VALUE_CONSTRUCT, v6, nullptr, 2 },
+    { Event::COPY_ASSIGN, v5, v6, 2 },
+    { Event::VALUE_CONSTRUCT, &e7, nullptr, 3 },
+    { Event::COPY_ASSIGN, v5, &e7, 3 },
+    { Event::DESTRUCT, &e7, nullptr, 3 },
+    { Event::DESTRUCT, v6, nullptr, 2 },
+    { Event::DESTRUCT, v5, nullptr, 3 },
     { Event::DESTRUCT, v3, nullptr, 5 },
     { Event::DESTRUCT, v2, nullptr, 4 },
   };
diff --git a/Tests/CMakeLib/testUVProcessChain.cxx b/Tests/CMakeLib/testUVProcessChain.cxx
index 61a77cf..a003205 100644
--- a/Tests/CMakeLib/testUVProcessChain.cxx
+++ b/Tests/CMakeLib/testUVProcessChain.cxx
@@ -181,6 +181,10 @@
   }
 
   std::string error = getInput(errorStream);
+  auto qemu_error_pos = error.find("qemu:");
+  if (qemu_error_pos != std::string::npos) {
+    error.resize(qemu_error_pos);
+  }
   if (error.length() != 3 || error.find('1') == std::string::npos ||
       error.find('2') == std::string::npos ||
       error.find('3') == std::string::npos) {
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index 9aa401d..328ab7f 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -240,8 +240,6 @@
 
   if(NOT CMake_TEST_EXTERNAL_CMAKE)
     add_subdirectory(CMakeLib)
-
-    add_subdirectory(CMakeServerLib)
   endif()
   add_subdirectory(CMakeOnly)
   add_subdirectory(RunCMake)
@@ -1422,6 +1420,7 @@
             GTK2
             Iconv
             ICU
+            Intl
             JPEG
             JsonCpp
             LAPACK
@@ -2910,13 +2909,6 @@
   ADD_TEST_MACRO(CMakeCommands.link_directories)
   ADD_TEST_MACRO(CMakeCommands.target_link_directories)
 
-  # The cmake server-mode test requires python for a simple client.
-  find_package(PythonInterp QUIET)
-  if(PYTHON_EXECUTABLE)
-    set(Server_BUILD_OPTIONS -DPYTHON_EXECUTABLE:FILEPATH=${PYTHON_EXECUTABLE})
-    ADD_TEST_MACRO(Server Server)
-  endif()
-
   configure_file(
     "${CMake_SOURCE_DIR}/Tests/CTestTestCrash/test.cmake.in"
     "${CMake_BINARY_DIR}/Tests/CTestTestCrash/test.cmake"
diff --git a/Tests/CMakeServerLib/CMakeLists.txt b/Tests/CMakeServerLib/CMakeLists.txt
deleted file mode 100644
index 2c23c2d..0000000
--- a/Tests/CMakeServerLib/CMakeLists.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-include_directories(
-  ${CMAKE_CURRENT_BINARY_DIR}
-  ${CMake_BINARY_DIR}/Source
-  ${CMake_SOURCE_DIR}/Source
-  )
-
-set(CMakeServerLib_TESTS
-  testServerBuffering.cpp
-  )
-
-create_test_sourcelist(CMakeLib_TEST_SRCS CMakeServerLibTests.cxx ${CMakeServerLib_TESTS})
-add_executable(CMakeServerLibTests ${CMakeLib_TEST_SRCS})
-target_link_libraries(CMakeServerLibTests CMakeLib CMakeServerLib)
-
-SET_PROPERTY(TARGET CMakeServerLibTests PROPERTY C_CLANG_TIDY "")
-SET_PROPERTY(TARGET CMakeServerLibTests PROPERTY CXX_CLANG_TIDY "")
-
-foreach(testfile ${CMakeServerLib_TESTS})
-  get_filename_component(test "${testfile}" NAME_WE)
-  add_test(CMakeServerLib.${test} CMakeServerLibTests ${test} ${${test}_ARGS})
-endforeach()
diff --git a/Tests/CMakeServerLib/testServerBuffering.cpp b/Tests/CMakeServerLib/testServerBuffering.cpp
deleted file mode 100644
index 6f22940..0000000
--- a/Tests/CMakeServerLib/testServerBuffering.cpp
+++ /dev/null
@@ -1,87 +0,0 @@
-#include <iostream>
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "cmConnection.h"
-#include "cmServerConnection.h"
-
-void print_error(const std::vector<std::string>& input,
-                 const std::vector<std::string>& output)
-{
-  std::cerr << "Responses don't equal input messages input." << std::endl;
-  std::cerr << "Responses: " << std::endl;
-
-  for (auto& msg : output) {
-    std::cerr << "'" << msg << "'" << std::endl;
-  }
-
-  std::cerr << "Input messages" << std::endl;
-  for (auto& msg : input) {
-    std::cerr << "'" << msg << "'" << std::endl;
-  }
-}
-
-std::string trim_newline(const std::string& _buffer)
-{
-  auto buffer = _buffer;
-  while (!buffer.empty() && (buffer.back() == '\n' || buffer.back() == '\r')) {
-    buffer.pop_back();
-  }
-  return buffer;
-}
-
-int testServerBuffering(int, char** const)
-{
-  std::vector<std::string> messages = {
-    "{ \"test\": 10}", "{ \"test\": { \"test2\": false} }",
-    "{ \"test\": [1, 2, 3] }",
-    "{ \"a\": { \"1\": {}, \n\n\n \"2\":[] \t\t\t\t}}"
-  };
-
-  std::string fullMessage;
-  for (auto& msg : messages) {
-    fullMessage += "[== \"CMake Server\" ==[\n";
-    fullMessage += msg;
-    fullMessage += "\n]== \"CMake Server\" ==]\n";
-  }
-
-  // The buffering strategy should cope with any fragmentation, including
-  // just getting the characters one at a time.
-  auto bufferingStrategy =
-    std::unique_ptr<cmConnectionBufferStrategy>(new cmServerBufferStrategy);
-  std::vector<std::string> response;
-  std::string rawBuffer;
-  for (auto& messageChar : fullMessage) {
-    rawBuffer += messageChar;
-    std::string packet = bufferingStrategy->BufferMessage(rawBuffer);
-    do {
-      if (!packet.empty() && packet != "\r\n") {
-        response.push_back(trim_newline(packet));
-      }
-      packet = bufferingStrategy->BufferMessage(rawBuffer);
-    } while (!packet.empty());
-  }
-
-  if (response != messages) {
-    print_error(messages, response);
-    return 1;
-  }
-
-  // We should also be able to deal with getting a bunch at once
-  response.clear();
-  std::string packet = bufferingStrategy->BufferMessage(fullMessage);
-  do {
-    if (!packet.empty() && packet != "\r\n") {
-      response.push_back(trim_newline(packet));
-    }
-    packet = bufferingStrategy->BufferMessage(fullMessage);
-  } while (!packet.empty());
-
-  if (response != messages) {
-    print_error(messages, response);
-    return 1;
-  }
-
-  return 0;
-}
diff --git a/Tests/CMakeTests/EndStuffTestScript.cmake b/Tests/CMakeTests/EndStuffTestScript.cmake
index 9f40818..6a6b162 100644
--- a/Tests/CMakeTests/EndStuffTestScript.cmake
+++ b/Tests/CMakeTests/EndStuffTestScript.cmake
@@ -1,68 +1,40 @@
 message(STATUS "testname='${testname}'")
 
-if(testname STREQUAL bad_else) # fail
-  file(WRITE "${dir}/${testname}.cmake"
-"else()
-")
+function(do_end content)
+  file(WRITE "${dir}/${testname}.cmake" "${content}")
   execute_process(COMMAND ${CMAKE_COMMAND} -P "${dir}/${testname}.cmake"
     RESULT_VARIABLE rv)
   if(NOT rv EQUAL 0)
     message(FATAL_ERROR "${testname} failed")
   endif()
+endfunction()
+
+if(testname STREQUAL bad_else) # fail
+  do_end("else()\n")
 
 elseif(testname STREQUAL bad_elseif) # fail
-  file(WRITE "${dir}/${testname}.cmake"
-"elseif()
-")
-  execute_process(COMMAND ${CMAKE_COMMAND} -P "${dir}/${testname}.cmake"
-    RESULT_VARIABLE rv)
-  if(NOT rv EQUAL 0)
-    message(FATAL_ERROR "${testname} failed")
-  endif()
+  do_end("elseif()\n")
 
 elseif(testname STREQUAL bad_endforeach) # fail
-  endforeach()
+  do_end("endforeach()\n")
 
 elseif(testname STREQUAL bad_endfunction) # fail
-  endfunction()
+  do_end("endfunction()\n")
 
 elseif(testname STREQUAL bad_endif) # fail
-  file(WRITE "${dir}/${testname}.cmake"
-"cmake_minimum_required(VERSION 2.8)
-endif()
-")
-  execute_process(COMMAND ${CMAKE_COMMAND} -P "${dir}/${testname}.cmake"
-    RESULT_VARIABLE rv)
-  if(NOT rv EQUAL 0)
-    message(FATAL_ERROR "${testname} failed")
-  endif()
+  do_end("cmake_minimum_required(VERSION 2.8)\nendif()\n")
 
-elseif(testname STREQUAL endif_low_min_version) # pass
-  file(WRITE "${dir}/${testname}.cmake"
-"cmake_minimum_required(VERSION 1.2)
-endif()
-")
-  execute_process(COMMAND ${CMAKE_COMMAND} -P "${dir}/${testname}.cmake"
-    RESULT_VARIABLE rv)
-  if(NOT rv EQUAL 0)
-    message(FATAL_ERROR "${testname} failed")
-  endif()
+elseif(testname STREQUAL endif_low_min_version) # fail
+  do_end("cmake_minimum_required(VERSION 1.2)\nendif()\n")
 
-elseif(testname STREQUAL endif_no_min_version) # pass
-  file(WRITE "${dir}/${testname}.cmake"
-"endif()
-")
-  execute_process(COMMAND ${CMAKE_COMMAND} -P "${dir}/${testname}.cmake"
-    RESULT_VARIABLE rv)
-  if(NOT rv EQUAL 0)
-    message(FATAL_ERROR "${testname} failed")
-  endif()
+elseif(testname STREQUAL endif_no_min_version) # fail
+  do_end("endif()\n")
 
 elseif(testname STREQUAL bad_endmacro) # fail
-  endmacro()
+  do_end("endmacro()\n")
 
 elseif(testname STREQUAL bad_endwhile) # fail
-  endwhile()
+  do_end("endwhile()\n")
 
 else() # fail
   message(FATAL_ERROR "testname='${testname}' - error: no such test in '${CMAKE_CURRENT_LIST_FILE}'")
diff --git a/Tests/FindIntl/CMakeLists.txt b/Tests/FindIntl/CMakeLists.txt
new file mode 100644
index 0000000..0906ede
--- /dev/null
+++ b/Tests/FindIntl/CMakeLists.txt
@@ -0,0 +1,10 @@
+add_test(NAME FindIntl.Test COMMAND
+  ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+  --build-and-test
+  "${CMake_SOURCE_DIR}/Tests/FindIntl/Test"
+  "${CMake_BINARY_DIR}/Tests/FindIntl/Test"
+  ${build_generator_args}
+  --build-project TestFindIntl
+  --build-options ${build_options}
+  --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+  )
diff --git a/Tests/FindIntl/Test/CMakeLists.txt b/Tests/FindIntl/Test/CMakeLists.txt
new file mode 100644
index 0000000..5140406
--- /dev/null
+++ b/Tests/FindIntl/Test/CMakeLists.txt
@@ -0,0 +1,14 @@
+cmake_minimum_required(VERSION 3.10)
+project(TestFindIntl CXX)
+include(CTest)
+
+find_package(Intl REQUIRED)
+
+add_executable(test_intl_tgt main.cxx)
+target_link_libraries(test_intl_tgt Intl::Intl)
+add_test(NAME test_intl_tgt COMMAND test_intl_tgt)
+
+add_executable(test_intl_var main.cxx)
+target_include_directories(test_intl_var PRIVATE ${Intl_INCLUDE_DIRS})
+target_link_libraries(test_intl_var PRIVATE ${Intl_LIBRARIES})
+add_test(NAME test_intl_var COMMAND test_intl_var)
diff --git a/Tests/FindIntl/Test/main.cxx b/Tests/FindIntl/Test/main.cxx
new file mode 100644
index 0000000..d90c095
--- /dev/null
+++ b/Tests/FindIntl/Test/main.cxx
@@ -0,0 +1,11 @@
+extern "C" {
+#include <libintl.h>
+}
+
+int main()
+{
+  // Check if we include the directory correctly and have no link errors
+  bindtextdomain("", "");
+  gettext("");
+  return 0;
+}
diff --git a/Tests/FindPython/CMakeLists.txt b/Tests/FindPython/CMakeLists.txt
index 44484c3..520ba9e 100644
--- a/Tests/FindPython/CMakeLists.txt
+++ b/Tests/FindPython/CMakeLists.txt
@@ -451,6 +451,18 @@
       --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
       )
   endif()
+
+  if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
+    add_test(NAME FindPython.UnversionedNames COMMAND
+      ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+      --build-and-test
+      "${CMake_SOURCE_DIR}/Tests/FindPython/UnversionedNames"
+      "${CMake_BINARY_DIR}/Tests/FindPython/UnversionedNames"
+      ${build_generator_args}
+      --build-project UnversionedNames
+      --build-options ${build_options}
+    )
+  endif()
 endif()
 
 if(CMake_TEST_FindPython_NumPy)
diff --git a/Tests/FindPython/UnversionedNames/CMakeLists.txt b/Tests/FindPython/UnversionedNames/CMakeLists.txt
new file mode 100644
index 0000000..597bd4e
--- /dev/null
+++ b/Tests/FindPython/UnversionedNames/CMakeLists.txt
@@ -0,0 +1,66 @@
+cmake_minimum_required(VERSION 3.19...3.20)
+
+project(UnversionedNames LANGUAGES NONE)
+
+# check if it is possible to find python with a generic name
+find_program(UNVERSIONED_Python3 NAMES python3)
+
+if (NOT UNVERSIONED_Python3)
+  # no generic name available
+  # test cannot be done
+  return()
+endif()
+
+# search with default configuration
+find_package(Python3 REQUIRED COMPONENTS Interpreter)
+
+if (Python3_EXECUTABLE STREQUAL UNVERSIONED_Python3)
+  # default configuration pick-up the generic name
+  # test cannot be completed
+  return()
+endif()
+
+unset(Python3_EXECUTABLE)
+# Force now to search first for  generic name
+set(Python3_FIND_UNVERSIONED_NAMES FIRST)
+
+find_package(Python3 REQUIRED COMPONENTS Interpreter)
+
+if (NOT Python3_EXECUTABLE STREQUAL UNVERSIONED_Python3)
+  message(SEND_ERROR "Found unexpected interpreter ${Python3_EXECUTABLE} instead of ${UNVERSIONED_Python3}")
+endif()
+
+# To check value 'NEVER", creates  directory holding a symlink to the generic name
+file(REMOVE_RECURSE "${CMAKE_CURRENT_BINARY_DIR}/bin")
+file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin")
+file(CREATE_LINK "${UNVERSIONED_Python3}" "${CMAKE_CURRENT_BINARY_DIR}/bin/python3" SYMBOLIC)
+
+unset(Python3_EXECUTABLE)
+set(Python3_FIND_UNVERSIONED_NAMES FIRST)
+set(Python3_ROOT_DIR "${CMAKE_CURRENT_BINARY_DIR}")
+# First search: generic name must be found
+find_package(Python3 REQUIRED COMPONENTS Interpreter)
+
+if (NOT Python3_EXECUTABLE STREQUAL "${CMAKE_CURRENT_BINARY_DIR}/bin/python3")
+  message(FATAL_ERROR "Found unexpected interpreter ${Python3_EXECUTABLE} instead of ${CMAKE_CURRENT_BINARY_DIR}/bin/python3")
+endif()
+
+unset(Python3_EXECUTABLE)
+set(Python3_FIND_UNVERSIONED_NAMES LAST)
+
+# Second search: generic name must be found
+find_package(Python3 REQUIRED COMPONENTS Interpreter)
+
+if (NOT Python3_EXECUTABLE STREQUAL "${CMAKE_CURRENT_BINARY_DIR}/bin/python3")
+  message(FATAL_ERROR "Found unexpected interpreter ${Python3_EXECUTABLE} instead of ${CMAKE_CURRENT_BINARY_DIR}/bin/python3")
+endif()
+
+unset(Python3_EXECUTABLE)
+set(Python3_FIND_UNVERSIONED_NAMES NEVER)
+
+# Third search: generic name must NOT be found
+find_package(Python3 REQUIRED COMPONENTS Interpreter)
+
+if (Python3_EXECUTABLE STREQUAL "${CMAKE_CURRENT_BINARY_DIR}/bin/python3")
+  message(FATAL_ERROR "Found unexpected interpreter ${Python3_EXECUTABLE}")
+endif()
diff --git a/Tests/RunCMake/ABI/C-stdout.txt b/Tests/RunCMake/ABI/C-stdout.txt
new file mode 100644
index 0000000..5b67b84
--- /dev/null
+++ b/Tests/RunCMake/ABI/C-stdout.txt
@@ -0,0 +1 @@
+-- Check if the system is big endian
diff --git a/Tests/RunCMake/ABI/C.cmake b/Tests/RunCMake/ABI/C.cmake
new file mode 100644
index 0000000..92f5da4
--- /dev/null
+++ b/Tests/RunCMake/ABI/C.cmake
@@ -0,0 +1,22 @@
+enable_language(C)
+if(NOT CMAKE_C_BYTE_ORDER MATCHES "^(BIG_ENDIAN|LITTLE_ENDIAN)$")
+  if(CMAKE_OSX_ARCHITECTURES MATCHES ";ppc|ppc;")
+    return()
+  endif()
+  message(FATAL_ERROR "CMAKE_C_BYTE_ORDER has unexpected value '${CMAKE_C_BYTE_ORDER}'")
+endif()
+
+include(TestBigEndian)
+test_big_endian(IS_BIG_ENDIAN)
+if(IS_BIG_ENDIAN AND NOT CMAKE_C_BYTE_ORDER STREQUAL "BIG_ENDIAN")
+  message(FATAL_ERROR "test_big_endian result does not match ABI result")
+endif()
+
+# Test legacy check.
+set(byte_order "${CMAKE_C_BYTE_ORDER}")
+unset(CMAKE_C_BYTE_ORDER)
+include(TestBigEndian)
+test_big_endian(IS_BIG)
+if(IS_BIG AND NOT byte_order STREQUAL "BIG_ENDIAN")
+  message(FATAL_ERROR "test_big_endian result does not match ABI result")
+endif()
diff --git a/Tests/RunCMake/ABI/CMakeLists.txt b/Tests/RunCMake/ABI/CMakeLists.txt
new file mode 100644
index 0000000..ab1a20c
--- /dev/null
+++ b/Tests/RunCMake/ABI/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.19)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/ABI/CUDA.cmake b/Tests/RunCMake/ABI/CUDA.cmake
new file mode 100644
index 0000000..8ede3a9
--- /dev/null
+++ b/Tests/RunCMake/ABI/CUDA.cmake
@@ -0,0 +1,13 @@
+enable_language(CUDA)
+if(NOT CMAKE_CUDA_BYTE_ORDER MATCHES "^(BIG_ENDIAN|LITTLE_ENDIAN)$")
+  if(CMAKE_OSX_ARCHITECTURES MATCHES ";ppc|ppc;")
+    return()
+  endif()
+  message(FATAL_ERROR "CMAKE_CUDA_BYTE_ORDER has unexpected value '${CMAKE_CUDA_BYTE_ORDER}'")
+endif()
+
+include(TestBigEndian)
+test_big_endian(IS_BIG_ENDIAN)
+if(IS_BIG_ENDIAN AND NOT CMAKE_CUDA_BYTE_ORDER STREQUAL "BIG_ENDIAN")
+  message(FATAL_ERROR "test_big_endian result does not match ABI result")
+endif()
diff --git a/Tests/RunCMake/ABI/CXX-stdout.txt b/Tests/RunCMake/ABI/CXX-stdout.txt
new file mode 100644
index 0000000..5b67b84
--- /dev/null
+++ b/Tests/RunCMake/ABI/CXX-stdout.txt
@@ -0,0 +1 @@
+-- Check if the system is big endian
diff --git a/Tests/RunCMake/ABI/CXX.cmake b/Tests/RunCMake/ABI/CXX.cmake
new file mode 100644
index 0000000..2310002
--- /dev/null
+++ b/Tests/RunCMake/ABI/CXX.cmake
@@ -0,0 +1,22 @@
+enable_language(CXX)
+if(NOT CMAKE_CXX_BYTE_ORDER MATCHES "^(BIG_ENDIAN|LITTLE_ENDIAN)$")
+  if(CMAKE_OSX_ARCHITECTURES MATCHES ";ppc|ppc;")
+    return()
+  endif()
+  message(FATAL_ERROR "CMAKE_CXX_BYTE_ORDER has unexpected value '${CMAKE_CXX_BYTE_ORDER}'")
+endif()
+
+include(TestBigEndian)
+test_big_endian(IS_BIG_ENDIAN)
+if(IS_BIG_ENDIAN AND NOT CMAKE_CXX_BYTE_ORDER STREQUAL "BIG_ENDIAN")
+  message(FATAL_ERROR "test_big_endian result does not match ABI result")
+endif()
+
+# Test legacy check.
+set(byte_order "${CMAKE_CXX_BYTE_ORDER}")
+unset(CMAKE_CXX_BYTE_ORDER)
+include(TestBigEndian)
+test_big_endian(IS_BIG)
+if(IS_BIG AND NOT byte_order STREQUAL "BIG_ENDIAN")
+  message(FATAL_ERROR "test_big_endian result does not match ABI result")
+endif()
diff --git a/Tests/RunCMake/ABI/OBJC.cmake b/Tests/RunCMake/ABI/OBJC.cmake
new file mode 100644
index 0000000..ab67459
--- /dev/null
+++ b/Tests/RunCMake/ABI/OBJC.cmake
@@ -0,0 +1,13 @@
+enable_language(OBJC)
+if(NOT CMAKE_OBJC_BYTE_ORDER MATCHES "^(BIG_ENDIAN|LITTLE_ENDIAN)$")
+  if(CMAKE_OSX_ARCHITECTURES MATCHES ";ppc|ppc;")
+    return()
+  endif()
+  message(FATAL_ERROR "CMAKE_OBJC_BYTE_ORDER has unexpected value '${CMAKE_OBJC_BYTE_ORDER}'")
+endif()
+
+include(TestBigEndian)
+test_big_endian(IS_BIG_ENDIAN)
+if(IS_BIG_ENDIAN AND NOT CMAKE_OBJC_BYTE_ORDER STREQUAL "BIG_ENDIAN")
+  message(FATAL_ERROR "test_big_endian result does not match ABI result")
+endif()
diff --git a/Tests/RunCMake/ABI/OBJCXX.cmake b/Tests/RunCMake/ABI/OBJCXX.cmake
new file mode 100644
index 0000000..41a719e
--- /dev/null
+++ b/Tests/RunCMake/ABI/OBJCXX.cmake
@@ -0,0 +1,13 @@
+enable_language(OBJCXX)
+if(NOT CMAKE_OBJCXX_BYTE_ORDER MATCHES "^(BIG_ENDIAN|LITTLE_ENDIAN)$")
+  if(CMAKE_OSX_ARCHITECTURES MATCHES ";ppc|ppc;")
+    return()
+  endif()
+  message(FATAL_ERROR "CMAKE_OBJCXX_BYTE_ORDER has unexpected value '${CMAKE_OBJCXX_BYTE_ORDER}'")
+endif()
+
+include(TestBigEndian)
+test_big_endian(IS_BIG_ENDIAN)
+if(IS_BIG_ENDIAN AND NOT CMAKE_OBJCXX_BYTE_ORDER STREQUAL "BIG_ENDIAN")
+  message(FATAL_ERROR "test_big_endian result does not match ABI result")
+endif()
diff --git a/Tests/RunCMake/ABI/RunCMakeTest.cmake b/Tests/RunCMake/ABI/RunCMakeTest.cmake
new file mode 100644
index 0000000..d9eabb7
--- /dev/null
+++ b/Tests/RunCMake/ABI/RunCMakeTest.cmake
@@ -0,0 +1,15 @@
+include(RunCMake)
+
+run_cmake(C)
+run_cmake(CXX)
+
+if(APPLE)
+  run_cmake(OBJC)
+  run_cmake(OBJCXX)
+endif()
+
+if(CMake_TEST_CUDA)
+  run_cmake(CUDA)
+endif()
+
+run_cmake(TestBigEndian-NoLang)
diff --git a/Tests/RunCMake/CommandLine/E_server-arg-result.txt b/Tests/RunCMake/ABI/TestBigEndian-NoLang-result.txt
similarity index 100%
copy from Tests/RunCMake/CommandLine/E_server-arg-result.txt
copy to Tests/RunCMake/ABI/TestBigEndian-NoLang-result.txt
diff --git a/Tests/RunCMake/ABI/TestBigEndian-NoLang-stderr.txt b/Tests/RunCMake/ABI/TestBigEndian-NoLang-stderr.txt
new file mode 100644
index 0000000..d0aa899
--- /dev/null
+++ b/Tests/RunCMake/ABI/TestBigEndian-NoLang-stderr.txt
@@ -0,0 +1,8 @@
+^CMake Error at [^
+]*/Modules/TestBigEndian.cmake:[0-9]+ \(message\):
+  TEST_BIG_ENDIAN needs either C or CXX language enabled
+Call Stack \(most recent call first\):
+  [^
+]*/Modules/TestBigEndian.cmake:[0-9]+ \(__TEST_BIG_ENDIAN_LEGACY_IMPL\)
+  TestBigEndian-NoLang.cmake:[0-9]+ \(test_big_endian\)
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/ABI/TestBigEndian-NoLang.cmake b/Tests/RunCMake/ABI/TestBigEndian-NoLang.cmake
new file mode 100644
index 0000000..8c10201
--- /dev/null
+++ b/Tests/RunCMake/ABI/TestBigEndian-NoLang.cmake
@@ -0,0 +1,2 @@
+include(TestBigEndian)
+test_big_endian(var)
diff --git a/Tests/RunCMake/Android/RunCMakeTest.cmake b/Tests/RunCMake/Android/RunCMakeTest.cmake
index c4b1a00..aa0cf4d 100644
--- a/Tests/RunCMake/Android/RunCMakeTest.cmake
+++ b/Tests/RunCMake/Android/RunCMakeTest.cmake
@@ -103,6 +103,13 @@
     set(ndk_arg)
   endif()
 
+  set(RunCMake_TEST_OPTIONS
+    -DCMAKE_SYSTEM_NAME=Android
+    -DCMAKE_FIND_ROOT_PATH=/tmp
+    ${ndk_arg}
+    )
+  run_cmake(ndk-search-order)
+
   # Test failure cases.
   message(STATUS "ndk='${ndk}'")
   if(RunCMake_GENERATOR MATCHES "Visual Studio")
diff --git a/Tests/RunCMake/Android/ndk-search-order.cmake b/Tests/RunCMake/Android/ndk-search-order.cmake
new file mode 100644
index 0000000..498d775
--- /dev/null
+++ b/Tests/RunCMake/Android/ndk-search-order.cmake
@@ -0,0 +1,17 @@
+if(NOT CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED)
+  return()
+endif()
+
+find_library(LIBDL dl)
+if(NOT LIBDL)
+  message(FATAL_ERROR "libdl not found.")
+endif()
+
+if(LIBDL MATCHES ".a$")
+  message(FATAL_ERROR "found libdl.a")
+endif()
+
+find_program(CLANG clang)
+if(NOT CLANG)
+  message(FATAL_ERROR "clang not found")
+endif()
diff --git a/Tests/RunCMake/CommandLine/E_server-arg-result.txt b/Tests/RunCMake/CMP0115/CMP0115-NEW-result.txt
similarity index 100%
copy from Tests/RunCMake/CommandLine/E_server-arg-result.txt
copy to Tests/RunCMake/CMP0115/CMP0115-NEW-result.txt
diff --git a/Tests/RunCMake/CMP0115/CMP0115-NEW-stderr.txt b/Tests/RunCMake/CMP0115/CMP0115-NEW-stderr.txt
new file mode 100644
index 0000000..b63c53d
--- /dev/null
+++ b/Tests/RunCMake/CMP0115/CMP0115-NEW-stderr.txt
@@ -0,0 +1,17 @@
+^CMake Error at CMP0115\.cmake:[0-9]+ \(add_executable\):
+  Cannot find source file:
+
+    main
+Call Stack \(most recent call first\):
+  CMP0115-NEW\.cmake:[0-9]+ \(include\)
+  CMakeLists\.txt:[0-9]+ \(include\)
+
+
+CMake Error at CMP0115\.cmake:[0-9]+ \(add_executable\):
+  No SOURCES given to target: exe
+Call Stack \(most recent call first\):
+  CMP0115-NEW\.cmake:[0-9]+ \(include\)
+  CMakeLists\.txt:[0-9]+ \(include\)
+
+
+CMake Generate step failed\.  Build files cannot be regenerated correctly\.$
diff --git a/Tests/RunCMake/CMP0115/CMP0115-NEW.cmake b/Tests/RunCMake/CMP0115/CMP0115-NEW.cmake
new file mode 100644
index 0000000..ddf5071
--- /dev/null
+++ b/Tests/RunCMake/CMP0115/CMP0115-NEW.cmake
@@ -0,0 +1 @@
+include(CMP0115.cmake)
diff --git a/Tests/RunCMake/CommandLine/E_server-arg-result.txt b/Tests/RunCMake/CMP0115/CMP0115-OLD-result.txt
similarity index 100%
copy from Tests/RunCMake/CommandLine/E_server-arg-result.txt
copy to Tests/RunCMake/CMP0115/CMP0115-OLD-result.txt
diff --git a/Tests/RunCMake/CMP0115/CMP0115-OLD-stderr.txt b/Tests/RunCMake/CMP0115/CMP0115-OLD-stderr.txt
new file mode 100644
index 0000000..8b90311
--- /dev/null
+++ b/Tests/RunCMake/CMP0115/CMP0115-OLD-stderr.txt
@@ -0,0 +1,22 @@
+^CMake Error at CMP0115\.cmake:[0-9]+ \(add_executable\):
+  Cannot find source file:
+
+    noexist
+
+  Tried extensions [^
+]*
+  [^
+]*
+Call Stack \(most recent call first\):
+  CMP0115-OLD\.cmake:[0-9]+ \(include\)
+  CMakeLists\.txt:[0-9]+ \(include\)
+
+
+CMake Error at CMP0115\.cmake:[0-9]+ \(add_executable\):
+  No SOURCES given to target: exe
+Call Stack \(most recent call first\):
+  CMP0115-OLD\.cmake:[0-9]+ \(include\)
+  CMakeLists\.txt:[0-9]+ \(include\)
+
+
+CMake Generate step failed\.  Build files cannot be regenerated correctly\.$
diff --git a/Tests/RunCMake/CMP0115/CMP0115-OLD.cmake b/Tests/RunCMake/CMP0115/CMP0115-OLD.cmake
new file mode 100644
index 0000000..ddf5071
--- /dev/null
+++ b/Tests/RunCMake/CMP0115/CMP0115-OLD.cmake
@@ -0,0 +1 @@
+include(CMP0115.cmake)
diff --git a/Tests/RunCMake/CommandLine/E_server-arg-result.txt b/Tests/RunCMake/CMP0115/CMP0115-WARN-result.txt
similarity index 100%
copy from Tests/RunCMake/CommandLine/E_server-arg-result.txt
copy to Tests/RunCMake/CMP0115/CMP0115-WARN-result.txt
diff --git a/Tests/RunCMake/CMP0115/CMP0115-WARN-stderr.txt b/Tests/RunCMake/CMP0115/CMP0115-WARN-stderr.txt
new file mode 100644
index 0000000..7b100b6
--- /dev/null
+++ b/Tests/RunCMake/CMP0115/CMP0115-WARN-stderr.txt
@@ -0,0 +1,36 @@
+^CMake Warning \(dev\) at CMP0115\.cmake:[0-9]+ \(add_executable\):
+  Policy CMP0115 is not set: Source file extensions must be explicit\.  Run
+  "cmake --help-policy CMP0115" for policy details\.  Use the cmake_policy
+  command to set the policy and suppress this warning\.
+
+  File:
+
+    [^
+]*/Tests/RunCMake/CMP0115/main\.c
+Call Stack \(most recent call first\):
+  CMP0115-WARN\.cmake:[0-9]+ \(include\)
+  CMakeLists\.txt:[0-9]+ \(include\)
+This warning is for project developers\.  Use -Wno-dev to suppress it\.
+
+CMake Error at CMP0115\.cmake:[0-9]+ \(add_executable\):
+  Cannot find source file:
+
+    noexist
+
+  Tried extensions [^
+]*
+  [^
+]*
+Call Stack \(most recent call first\):
+  CMP0115-WARN\.cmake:[0-9]+ \(include\)
+  CMakeLists\.txt:[0-9]+ \(include\)
+
+
+CMake Error at CMP0115\.cmake:[0-9]+ \(add_executable\):
+  No SOURCES given to target: exe
+Call Stack \(most recent call first\):
+  CMP0115-WARN\.cmake:[0-9]+ \(include\)
+  CMakeLists\.txt:[0-9]+ \(include\)
+
+
+CMake Generate step failed\.  Build files cannot be regenerated correctly\.$
diff --git a/Tests/RunCMake/CMP0115/CMP0115-WARN.cmake b/Tests/RunCMake/CMP0115/CMP0115-WARN.cmake
new file mode 100644
index 0000000..ddf5071
--- /dev/null
+++ b/Tests/RunCMake/CMP0115/CMP0115-WARN.cmake
@@ -0,0 +1 @@
+include(CMP0115.cmake)
diff --git a/Tests/RunCMake/CMP0115/CMP0115.cmake b/Tests/RunCMake/CMP0115/CMP0115.cmake
new file mode 100644
index 0000000..be910a4
--- /dev/null
+++ b/Tests/RunCMake/CMP0115/CMP0115.cmake
@@ -0,0 +1,3 @@
+enable_language(C)
+
+add_executable(exe main noexist)
diff --git a/Tests/RunCMake/CMP0115/CMakeLists.txt b/Tests/RunCMake/CMP0115/CMakeLists.txt
new file mode 100644
index 0000000..b646c4a
--- /dev/null
+++ b/Tests/RunCMake/CMP0115/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.18)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CMP0115/RunCMakeTest.cmake b/Tests/RunCMake/CMP0115/RunCMakeTest.cmake
new file mode 100644
index 0000000..58182ac
--- /dev/null
+++ b/Tests/RunCMake/CMP0115/RunCMakeTest.cmake
@@ -0,0 +1,12 @@
+include(RunCMake)
+
+function(run_cmp0115 status)
+  if(NOT status STREQUAL "WARN")
+    set(RunCMake_TEST_OPTIONS -DCMAKE_POLICY_DEFAULT_CMP0115=${status})
+  endif()
+  run_cmake(CMP0115-${status})
+endfunction()
+
+run_cmp0115(OLD)
+run_cmp0115(WARN)
+run_cmp0115(NEW)
diff --git a/Tests/RunCMake/CMP0115/main.c b/Tests/RunCMake/CMP0115/main.c
new file mode 100644
index 0000000..8488f4e
--- /dev/null
+++ b/Tests/RunCMake/CMP0115/main.c
@@ -0,0 +1,4 @@
+int main(void)
+{
+  return 0;
+}
diff --git a/Tests/RunCMake/CMP0116/CMP0116-NEW-NOWARN.cmake b/Tests/RunCMake/CMP0116/CMP0116-NEW-NOWARN.cmake
new file mode 100644
index 0000000..f92fac6
--- /dev/null
+++ b/Tests/RunCMake/CMP0116/CMP0116-NEW-NOWARN.cmake
@@ -0,0 +1,3 @@
+set(depdir)
+
+include(Common.cmake)
diff --git a/Tests/RunCMake/CMP0116/CMP0116-NEW-WARN.cmake b/Tests/RunCMake/CMP0116/CMP0116-NEW-WARN.cmake
new file mode 100644
index 0000000..f92fac6
--- /dev/null
+++ b/Tests/RunCMake/CMP0116/CMP0116-NEW-WARN.cmake
@@ -0,0 +1,3 @@
+set(depdir)
+
+include(Common.cmake)
diff --git a/Tests/RunCMake/CMP0116/CMP0116-OLD-NOWARN.cmake b/Tests/RunCMake/CMP0116/CMP0116-OLD-NOWARN.cmake
new file mode 100644
index 0000000..665f485
--- /dev/null
+++ b/Tests/RunCMake/CMP0116/CMP0116-OLD-NOWARN.cmake
@@ -0,0 +1,3 @@
+set(depdir Subdirectory/)
+
+include(Common.cmake)
diff --git a/Tests/RunCMake/CMP0116/CMP0116-OLD-WARN.cmake b/Tests/RunCMake/CMP0116/CMP0116-OLD-WARN.cmake
new file mode 100644
index 0000000..665f485
--- /dev/null
+++ b/Tests/RunCMake/CMP0116/CMP0116-OLD-WARN.cmake
@@ -0,0 +1,3 @@
+set(depdir Subdirectory/)
+
+include(Common.cmake)
diff --git a/Tests/RunCMake/CMP0116/CMP0116-WARN-NOWARN-stderr.txt b/Tests/RunCMake/CMP0116/CMP0116-WARN-NOWARN-stderr.txt
new file mode 100644
index 0000000..843ff1c
--- /dev/null
+++ b/Tests/RunCMake/CMP0116/CMP0116-WARN-NOWARN-stderr.txt
@@ -0,0 +1,7 @@
+^(CMake Warning \(dev\) at Subdirectory/CMakeLists\.txt:[0-9]+ \(add_custom_command\):
+  Policy CMP0116 is not set: Ninja generators transform DEPFILEs from
+  add_custom_command\(\)\.  Run "cmake --help-policy CMP0116" for policy
+  details\.  Use the cmake_policy command to set the policy and suppress this
+  warning\.
+This warning is for project developers\.  Use -Wno-dev to suppress it\.
+*)+$
diff --git a/Tests/RunCMake/CMP0116/CMP0116-WARN-NOWARN.cmake b/Tests/RunCMake/CMP0116/CMP0116-WARN-NOWARN.cmake
new file mode 100644
index 0000000..665f485
--- /dev/null
+++ b/Tests/RunCMake/CMP0116/CMP0116-WARN-NOWARN.cmake
@@ -0,0 +1,3 @@
+set(depdir Subdirectory/)
+
+include(Common.cmake)
diff --git a/Tests/RunCMake/CMP0116/CMP0116-WARN-WARN-stderr.txt b/Tests/RunCMake/CMP0116/CMP0116-WARN-WARN-stderr.txt
new file mode 100644
index 0000000..e29af91
--- /dev/null
+++ b/Tests/RunCMake/CMP0116/CMP0116-WARN-WARN-stderr.txt
@@ -0,0 +1,16 @@
+^(CMake Warning \(dev\) at Common\.cmake:[0-9]+ \(add_custom_command\):
+  Policy CMP0116 is not set: Ninja generators transform DEPFILEs from
+  add_custom_command\(\)\.  Run "cmake --help-policy CMP0116" for policy
+  details\.  Use the cmake_policy command to set the policy and suppress this
+  warning\.
+Call Stack \(most recent call first\):
+  CMP0116-WARN-WARN\.cmake:[0-9]+ \(include\)
+  CMakeLists\.txt:[0-9]+ \(include\)
+This warning is for project developers\.  Use -Wno-dev to suppress it\.
++)+(CMake Warning \(dev\) at Subdirectory/CMakeLists\.txt:[0-9]+ \(add_custom_command\):
+  Policy CMP0116 is not set: Ninja generators transform DEPFILEs from
+  add_custom_command\(\)\.  Run "cmake --help-policy CMP0116" for policy
+  details\.  Use the cmake_policy command to set the policy and suppress this
+  warning\.
+This warning is for project developers\.  Use -Wno-dev to suppress it\.
+*)+$
diff --git a/Tests/RunCMake/CMP0116/CMP0116-WARN-WARN.cmake b/Tests/RunCMake/CMP0116/CMP0116-WARN-WARN.cmake
new file mode 100644
index 0000000..665f485
--- /dev/null
+++ b/Tests/RunCMake/CMP0116/CMP0116-WARN-WARN.cmake
@@ -0,0 +1,3 @@
+set(depdir Subdirectory/)
+
+include(Common.cmake)
diff --git a/Tests/RunCMake/CMP0116/CMakeLists.txt b/Tests/RunCMake/CMP0116/CMakeLists.txt
new file mode 100644
index 0000000..b646c4a
--- /dev/null
+++ b/Tests/RunCMake/CMP0116/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.18)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CMP0116/Common.cmake b/Tests/RunCMake/CMP0116/Common.cmake
new file mode 100644
index 0000000..472b162
--- /dev/null
+++ b/Tests/RunCMake/CMP0116/Common.cmake
@@ -0,0 +1,8 @@
+add_custom_command(
+  OUTPUT top.txt
+  COMMAND ${CMAKE_COMMAND} -DOUTFILE=top.txt -DINFILE=topdep.txt -DDEPFILE=top.txt.d -DSTAMPFILE=topstamp.txt -DDEPDIR= -P ${CMAKE_SOURCE_DIR}/WriteDepfile.cmake
+  DEPFILE top.txt.d
+  )
+add_custom_target(top ALL DEPENDS top.txt)
+
+add_subdirectory(Subdirectory)
diff --git a/Tests/RunCMake/CMP0116/RunCMakeTest.cmake b/Tests/RunCMake/CMP0116/RunCMakeTest.cmake
new file mode 100644
index 0000000..8a83cc1
--- /dev/null
+++ b/Tests/RunCMake/CMP0116/RunCMakeTest.cmake
@@ -0,0 +1,49 @@
+include(RunCMake)
+
+function(run_cmp0116 status warn)
+  if(warn)
+    set(name CMP0116-${status}-WARN)
+  else()
+    set(name CMP0116-${status}-NOWARN)
+  endif()
+  set(RunCMake_TEST_OPTIONS
+    -DCMAKE_POLICY_WARNING_CMP0116:BOOL=${warn}
+    )
+  if(NOT status STREQUAL "WARN")
+    list(APPEND RunCMake_TEST_OPTIONS
+      -DCMAKE_POLICY_DEFAULT_CMP0116:STRING=${status}
+      )
+  endif()
+
+  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${name}-build)
+  run_cmake(${name})
+  unset(RunCMake_TEST_OPTIONS)
+  set(RunCMake_TEST_NO_CLEAN 1)
+  set(RunCMake-check-file check.cmake)
+
+  file(TOUCH "${RunCMake_TEST_BINARY_DIR}/topdep.txt")
+  file(TOUCH "${RunCMake_TEST_BINARY_DIR}/Subdirectory/subdep.txt")
+  set(cmp0116_step 1)
+  run_cmake_command(${name}-build1 ${CMAKE_COMMAND} --build . --config Debug)
+  file(REMOVE "${RunCMake_TEST_BINARY_DIR}/topstamp.txt")
+  file(REMOVE "${RunCMake_TEST_BINARY_DIR}/Subdirectory/substamp.txt")
+  execute_process(COMMAND ${CMAKE_COMMAND} -E sleep 1.25)
+
+  file(TOUCH "${RunCMake_TEST_BINARY_DIR}/topdep.txt")
+  file(TOUCH "${RunCMake_TEST_BINARY_DIR}/Subdirectory/subdep.txt")
+  set(cmp0116_step 2)
+  run_cmake_command(${name}-build2 ${CMAKE_COMMAND} --build . --config Debug)
+  file(REMOVE "${RunCMake_TEST_BINARY_DIR}/topstamp.txt")
+  file(REMOVE "${RunCMake_TEST_BINARY_DIR}/Subdirectory/substamp.txt")
+  execute_process(COMMAND ${CMAKE_COMMAND} -E sleep 1.25)
+
+  set(cmp0116_step 3)
+  run_cmake_command(${name}-build3 ${CMAKE_COMMAND} --build . --config Debug)
+endfunction()
+
+run_cmp0116(WARN OFF)
+run_cmp0116(OLD OFF)
+run_cmp0116(NEW OFF)
+run_cmp0116(WARN ON)
+run_cmp0116(OLD ON)
+run_cmp0116(NEW ON)
diff --git a/Tests/RunCMake/CMP0116/Subdirectory/CMakeLists.txt b/Tests/RunCMake/CMP0116/Subdirectory/CMakeLists.txt
new file mode 100644
index 0000000..f0f60b2
--- /dev/null
+++ b/Tests/RunCMake/CMP0116/Subdirectory/CMakeLists.txt
@@ -0,0 +1,6 @@
+add_custom_command(
+  OUTPUT sub.txt
+  COMMAND ${CMAKE_COMMAND} -DOUTFILE=sub.txt -DINFILE=subdep.txt -DDEPFILE=sub.txt.d -DSTAMPFILE=substamp.txt -DDEPDIR=${depdir} -P ${CMAKE_SOURCE_DIR}/WriteDepfile.cmake
+  DEPFILE ${depdir}sub.txt.d
+  )
+add_custom_target(sub ALL DEPENDS sub.txt)
diff --git a/Tests/RunCMake/CMP0116/WriteDepfile.cmake b/Tests/RunCMake/CMP0116/WriteDepfile.cmake
new file mode 100644
index 0000000..1a74d2a
--- /dev/null
+++ b/Tests/RunCMake/CMP0116/WriteDepfile.cmake
@@ -0,0 +1,3 @@
+file(TOUCH "${OUTFILE}")
+file(TOUCH "${STAMPFILE}")
+file(WRITE "${DEPFILE}" "${DEPDIR}${OUTFILE}: ${DEPDIR}${INFILE}\n")
diff --git a/Tests/RunCMake/CMP0116/check.cmake b/Tests/RunCMake/CMP0116/check.cmake
new file mode 100644
index 0000000..1b16748
--- /dev/null
+++ b/Tests/RunCMake/CMP0116/check.cmake
@@ -0,0 +1,18 @@
+function(check_exists file)
+  if(NOT EXISTS "${file}")
+    string(APPEND RunCMake_TEST_FAILED "${file} does not exist\n")
+  endif()
+  set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}" PARENT_SCOPE)
+endfunction()
+
+function(check_not_exists file)
+  if(EXISTS "${file}")
+    string(APPEND RunCMake_TEST_FAILED "${file} exists\n")
+  endif()
+  set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}" PARENT_SCOPE)
+endfunction()
+
+if(cmp0116_step EQUAL 3)
+  check_not_exists("${RunCMake_TEST_BINARY_DIR}/topstamp.txt")
+  check_not_exists("${RunCMake_TEST_BINARY_DIR}/Subdirectory/substamp.txt")
+endif()
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index 7000b79..5b0b055 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -125,6 +125,10 @@
 endif()
 add_RunCMake_test(CMP0106)
 add_RunCMake_test(CMP0111)
+add_RunCMake_test(CMP0115)
+if(CMAKE_GENERATOR MATCHES "Ninja")
+  add_RunCMake_test(CMP0116)
+endif()
 
 # The test for Policy 65 requires the use of the
 # CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS variable, which both the VS and Xcode
@@ -175,6 +179,10 @@
     )
 endif()
 
+add_RunCMake_test(ABI -DCMake_TEST_CUDA=${CMake_TEST_CUDA})
+set_property(TEST RunCMake.ABI APPEND
+  PROPERTY LABELS "CUDA")
+
 add_RunCMake_test(AndroidTestUtilities)
 set(autogen_with_qt5 FALSE)
 if(CMake_TEST_Qt5)
@@ -254,6 +262,7 @@
 endif()
 if(MSVC)
   add_RunCMake_test(MSVCRuntimeLibrary)
+  add_RunCMake_test(MSVCRuntimeTypeInfo)
   add_RunCMake_test(MSVCWarningFlags)
 endif()
 add_RunCMake_test(ObjectLibrary)
@@ -308,7 +317,7 @@
 add_RunCMake_test(cmake_language)
 add_RunCMake_test(cmake_minimum_required)
 add_RunCMake_test(cmake_parse_arguments)
-# add_RunCMake_test(cmake_path)
+add_RunCMake_test(cmake_path)
 add_RunCMake_test(continue)
 add_executable(color_warning color_warning.c)
 add_executable(fake_build_command fake_build_command.c)
@@ -561,7 +570,8 @@
 endif()
 
 
-add_RunCMake_test(CommandLine -DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME} -DCYGWIN=${CYGWIN} -DPYTHON_EXECUTABLE=${PYTHON_EXECUTABLE})
+add_executable(pseudo_llvm-rc pseudo_llvm-rc.c)
+add_RunCMake_test(CommandLine -DLLVM_RC=$<TARGET_FILE:pseudo_llvm-rc> -DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME} -DCYGWIN=${CYGWIN} -DPYTHON_EXECUTABLE=${PYTHON_EXECUTABLE})
 add_RunCMake_test(CommandLineTar)
 
 if(CMAKE_PLATFORM_NO_VERSIONED_SONAME OR (NOT CMAKE_SHARED_LIBRARY_SONAME_FLAG AND NOT CMAKE_SHARED_LIBRARY_SONAME_C_FLAG))
@@ -770,6 +780,7 @@
 
 add_RunCMake_test("UnityBuild")
 add_RunCMake_test(CMakePresets -DPYTHON_EXECUTABLE=${PYTHON_EXECUTABLE} -DCMake_TEST_JSON_SCHEMA=${CMake_TEST_JSON_SCHEMA})
+add_RunCMake_test(TransformDepfile)
 
 if(WIN32)
   add_RunCMake_test(Win32GenEx)
diff --git a/Tests/RunCMake/CPack/tests/DEBUGINFO/ExpectedFiles.cmake b/Tests/RunCMake/CPack/tests/DEBUGINFO/ExpectedFiles.cmake
index cf2e8ac..cf4aa51 100644
--- a/Tests/RunCMake/CPack/tests/DEBUGINFO/ExpectedFiles.cmake
+++ b/Tests/RunCMake/CPack/tests/DEBUGINFO/ExpectedFiles.cmake
@@ -1,6 +1,6 @@
 set(whitespaces_ "[\t\n\r ]*")
 
-set(EXPECTED_FILES_COUNT "5")
+set(EXPECTED_FILES_COUNT "6")
 set(EXPECTED_FILES_NAME_GENERATOR_SPECIFIC_FORMAT TRUE)
 
 if(GENERATOR_TYPE STREQUAL "RPM")
@@ -39,3 +39,6 @@
   set(EXPECTED_FILE_5 "TestDinfo-pkg-libs-dbgsym.ddeb")
   set(EXPECTED_FILE_CONTENT_5 ".*/usr/lib/debug/.build-id/.*\.debug.*")
 endif()
+
+set(EXPECTED_FILE_6 "TestDinfo-pkg*-appheaders.${PKG}")
+set(EXPECTED_FILE_CONTENT_6_LIST "/include;/include/test_lib.hpp")
diff --git a/Tests/RunCMake/CPack/tests/DEBUGINFO/test.cmake b/Tests/RunCMake/CPack/tests/DEBUGINFO/test.cmake
index 161a36a..d270005 100644
--- a/Tests/RunCMake/CPack/tests/DEBUGINFO/test.cmake
+++ b/Tests/RunCMake/CPack/tests/DEBUGINFO/test.cmake
@@ -23,6 +23,7 @@
 add_executable(test_prog "${CMAKE_CURRENT_BINARY_DIR}/main.cpp")
 target_link_libraries(test_prog test_lib)
 
+install(FILES "${CMAKE_CURRENT_BINARY_DIR}/test_lib.hpp" DESTINATION include COMPONENT appheaders)
 install(TARGETS test_prog DESTINATION foo COMPONENT applications)
 install(FILES CMakeLists.txt DESTINATION bar COMPONENT headers)
 install(TARGETS test_lib DESTINATION bas COMPONENT libs)
@@ -40,6 +41,10 @@
 set(CPACK_DEBIAN_PACKAGE_NAME "Debuginfo")
 set(CPACK_DEBIAN_LIBS_DEBUGINFO_PACKAGE ON)
 
+# Test that a component with debug info requested but without any debug info produces none
+set(CPACK_RPM_APPHEADERS_DEBUGINFO_PACKAGE ON)
+set(CPACK_DEBIAN_APPHEADERS_DEBUGINFO_PACKAGE ON)
+
 # test debuginfo package rename
 set(CPACK_RPM_DEBUGINFO_FILE_NAME
   "@cpack_component@-DebugInfoPackage.rpm")
diff --git a/Tests/RunCMake/CTest/RunCMakeTest.cmake b/Tests/RunCMake/CTest/RunCMakeTest.cmake
index ffc8f78..b81f319 100644
--- a/Tests/RunCMake/CTest/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CTest/RunCMakeTest.cmake
@@ -5,6 +5,7 @@
 unset(RunCMake_TEST_OPTIONS)
 
 run_cmake(NotOn)
+run_cmake(Site)
 
 function(run_CMakeCTestArguments)
   run_cmake_with_options(CMakeCTestArguments "-DCMAKE_CTEST_ARGUMENTS=--quiet\\;--output-log\\;output-log.txt")
diff --git a/Tests/RunCMake/CTest/Site.cmake b/Tests/RunCMake/CTest/Site.cmake
new file mode 100644
index 0000000..2c96f23
--- /dev/null
+++ b/Tests/RunCMake/CTest/Site.cmake
@@ -0,0 +1,5 @@
+include(CTest)
+get_property(site CACHE SITE PROPERTY VALUE)
+if(NOT "${site}" STREQUAL "${SITE}")
+  message(FATAL_ERROR "SITE is not a cache entry")
+endif()
diff --git a/Tests/RunCMake/CheckModules/CMP0075-stderr.txt b/Tests/RunCMake/CheckModules/CMP0075-stderr.txt
index 960fe94..97833f5 100644
--- a/Tests/RunCMake/CheckModules/CMP0075-stderr.txt
+++ b/Tests/RunCMake/CheckModules/CMP0075-stderr.txt
@@ -47,4 +47,15 @@
 Call Stack \(most recent call first\):
   CMP0075.cmake:41 \(check_include_files\)
   CMakeLists.txt:[0-9]+ \(include\)
-This warning is for project developers.  Use -Wno-dev to suppress it.$
+This warning is for project developers.  Use -Wno-dev to suppress it.
++
+CMake Deprecation Warning at CMP0075.cmake:[0-9]+ \(cmake_policy\):
+  The OLD behavior for policy CMP0075 will be removed from a future version
+  of CMake.
+
+  The cmake-policies\(7\) manual explains that the OLD behaviors of all
+  policies are deprecated and that a policy should be set to OLD only under
+  specific short-term circumstances.  Projects should be ported to the NEW
+  behavior and not rely on setting a policy to OLD.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/ClangTidy/OBJC-Build-stdout.txt b/Tests/RunCMake/ClangTidy/OBJC-Build-stdout.txt
new file mode 100644
index 0000000..571ec02
--- /dev/null
+++ b/Tests/RunCMake/ClangTidy/OBJC-Build-stdout.txt
@@ -0,0 +1 @@
+Tests[/\]RunCMake[/\]ClangTidy[/\]main\.m:0:0: warning: message \[checker\]
diff --git a/Tests/RunCMake/ClangTidy/OBJC-launch-Build-stdout.txt b/Tests/RunCMake/ClangTidy/OBJC-launch-Build-stdout.txt
new file mode 100644
index 0000000..571ec02
--- /dev/null
+++ b/Tests/RunCMake/ClangTidy/OBJC-launch-Build-stdout.txt
@@ -0,0 +1 @@
+Tests[/\]RunCMake[/\]ClangTidy[/\]main\.m:0:0: warning: message \[checker\]
diff --git a/Tests/RunCMake/ClangTidy/OBJC-launch.cmake b/Tests/RunCMake/ClangTidy/OBJC-launch.cmake
new file mode 100644
index 0000000..43e8521
--- /dev/null
+++ b/Tests/RunCMake/ClangTidy/OBJC-launch.cmake
@@ -0,0 +1,3 @@
+set(CTEST_USE_LAUNCHERS 1)
+include(CTestUseLaunchers)
+include(OBJC.cmake)
diff --git a/Tests/RunCMake/ClangTidy/OBJC.cmake b/Tests/RunCMake/ClangTidy/OBJC.cmake
new file mode 100644
index 0000000..43eae30
--- /dev/null
+++ b/Tests/RunCMake/ClangTidy/OBJC.cmake
@@ -0,0 +1,3 @@
+enable_language(OBJC)
+set(CMAKE_OBJC_CLANG_TIDY "${PSEUDO_TIDY}" -some -args)
+add_executable(main main.m)
diff --git a/Tests/RunCMake/ClangTidy/OBJCXX-Build-stdout.txt b/Tests/RunCMake/ClangTidy/OBJCXX-Build-stdout.txt
new file mode 100644
index 0000000..cbc7629
--- /dev/null
+++ b/Tests/RunCMake/ClangTidy/OBJCXX-Build-stdout.txt
@@ -0,0 +1 @@
+Tests[/\]RunCMake[/\]ClangTidy[/\]main\.mm:0:0: warning: message \[checker\]
diff --git a/Tests/RunCMake/ClangTidy/OBJCXX-launch-Build-stdout.txt b/Tests/RunCMake/ClangTidy/OBJCXX-launch-Build-stdout.txt
new file mode 100644
index 0000000..cbc7629
--- /dev/null
+++ b/Tests/RunCMake/ClangTidy/OBJCXX-launch-Build-stdout.txt
@@ -0,0 +1 @@
+Tests[/\]RunCMake[/\]ClangTidy[/\]main\.mm:0:0: warning: message \[checker\]
diff --git a/Tests/RunCMake/ClangTidy/OBJCXX-launch.cmake b/Tests/RunCMake/ClangTidy/OBJCXX-launch.cmake
new file mode 100644
index 0000000..5a54bff
--- /dev/null
+++ b/Tests/RunCMake/ClangTidy/OBJCXX-launch.cmake
@@ -0,0 +1,3 @@
+set(CTEST_USE_LAUNCHERS 1)
+include(CTestUseLaunchers)
+include(OBJCXX.cmake)
diff --git a/Tests/RunCMake/ClangTidy/OBJCXX.cmake b/Tests/RunCMake/ClangTidy/OBJCXX.cmake
new file mode 100644
index 0000000..ccc5c2c
--- /dev/null
+++ b/Tests/RunCMake/ClangTidy/OBJCXX.cmake
@@ -0,0 +1,3 @@
+enable_language(OBJCXX)
+set(CMAKE_OBJCXX_CLANG_TIDY "${PSEUDO_TIDY}" -some -args)
+add_executable(main main.mm)
diff --git a/Tests/RunCMake/ClangTidy/RunCMakeTest.cmake b/Tests/RunCMake/ClangTidy/RunCMakeTest.cmake
index 2f41e50..ee41d94 100644
--- a/Tests/RunCMake/ClangTidy/RunCMakeTest.cmake
+++ b/Tests/RunCMake/ClangTidy/RunCMakeTest.cmake
@@ -16,8 +16,16 @@
 
 run_tidy(C)
 run_tidy(CXX)
+if (APPLE)
+  run_tidy(OBJC)
+  run_tidy(OBJCXX)
+endif()
 if (NOT RunCMake_GENERATOR STREQUAL "Watcom WMake")
   run_tidy(C-launch)
   run_tidy(CXX-launch)
+  if (APPLE)
+    run_tidy(OBJC-launch)
+    run_tidy(OBJCXX-launch)
+  endif()
 endif()
 run_tidy(C-bad)
diff --git a/Tests/RunCMake/ClangTidy/main.m b/Tests/RunCMake/ClangTidy/main.m
new file mode 100644
index 0000000..8488f4e
--- /dev/null
+++ b/Tests/RunCMake/ClangTidy/main.m
@@ -0,0 +1,4 @@
+int main(void)
+{
+  return 0;
+}
diff --git a/Tests/Server/buildsystem1/main.cpp b/Tests/RunCMake/ClangTidy/main.mm
similarity index 95%
rename from Tests/Server/buildsystem1/main.cpp
rename to Tests/RunCMake/ClangTidy/main.mm
index 766b775..f8b643a 100644
--- a/Tests/Server/buildsystem1/main.cpp
+++ b/Tests/RunCMake/ClangTidy/main.mm
@@ -1,4 +1,3 @@
-
 int main()
 {
   return 0;
diff --git a/Tests/RunCMake/CommandLine/E_capabilities-stdout.txt b/Tests/RunCMake/CommandLine/E_capabilities-stdout.txt
index e24e131..a8b6584 100644
--- a/Tests/RunCMake/CommandLine/E_capabilities-stdout.txt
+++ b/Tests/RunCMake/CommandLine/E_capabilities-stdout.txt
@@ -1 +1 @@
-^{"fileApi":{"requests":\[{"kind":"codemodel","version":\[{"major":2,"minor":2}]},{"kind":"cache","version":\[{"major":2,"minor":0}]},{"kind":"cmakeFiles","version":\[{"major":1,"minor":0}]}]},"generators":\[.*\],"serverMode":true,"version":{.*}}$
+^{"fileApi":{"requests":\[{"kind":"codemodel","version":\[{"major":2,"minor":2}]},{"kind":"cache","version":\[{"major":2,"minor":0}]},{"kind":"cmakeFiles","version":\[{"major":1,"minor":0}]}]},"generators":\[.*\],"serverMode":false,"version":{.*}}$
diff --git a/Tests/RunCMake/CommandLine/E_server-arg-stderr.txt b/Tests/RunCMake/CommandLine/E_server-arg-stderr.txt
deleted file mode 100644
index 4dcbab9..0000000
--- a/Tests/RunCMake/CommandLine/E_server-arg-stderr.txt
+++ /dev/null
@@ -1 +0,0 @@
-^CMake Error: Unknown argument for server mode$
diff --git a/Tests/RunCMake/CommandLine/E_server-pipe-result.txt b/Tests/RunCMake/CommandLine/E_server-pipe-result.txt
deleted file mode 100644
index 0cfbf08..0000000
--- a/Tests/RunCMake/CommandLine/E_server-pipe-result.txt
+++ /dev/null
@@ -1 +0,0 @@
-2
diff --git a/Tests/RunCMake/CommandLine/E_server-pipe-stderr.txt b/Tests/RunCMake/CommandLine/E_server-pipe-stderr.txt
deleted file mode 100644
index 7193ba6..0000000
--- a/Tests/RunCMake/CommandLine/E_server-pipe-stderr.txt
+++ /dev/null
@@ -1 +0,0 @@
-^CMake Error: No pipe given after --pipe=$
diff --git a/Tests/RunCMake/CommandLine/E_server-arg-result.txt b/Tests/RunCMake/CommandLine/E_server-result.txt
similarity index 100%
rename from Tests/RunCMake/CommandLine/E_server-arg-result.txt
rename to Tests/RunCMake/CommandLine/E_server-result.txt
diff --git a/Tests/RunCMake/CommandLine/E_server-stderr.txt b/Tests/RunCMake/CommandLine/E_server-stderr.txt
new file mode 100644
index 0000000..0cd0e56
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_server-stderr.txt
@@ -0,0 +1 @@
+^CMake Error: CMake server mode has been removed in favor of the file-api\.$
diff --git a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
index b23c8c2..c438860 100644
--- a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
@@ -25,8 +25,7 @@
 run_cmake_command(E_compare_files-invalid-arguments ${CMAKE_COMMAND} -E compare_files file1.txt file2.txt file3.txt)
 run_cmake_command(E_echo_append ${CMAKE_COMMAND} -E echo_append)
 run_cmake_command(E_rename-no-arg ${CMAKE_COMMAND} -E rename)
-run_cmake_command(E_server-arg ${CMAKE_COMMAND} -E server --extra-arg)
-run_cmake_command(E_server-pipe ${CMAKE_COMMAND} -E server --pipe=)
+run_cmake_command(E_server ${CMAKE_COMMAND} -E server)
 run_cmake_command(E_true ${CMAKE_COMMAND} -E true)
 run_cmake_command(E_true-extraargs ${CMAKE_COMMAND} -E true ignored)
 run_cmake_command(E_false ${CMAKE_COMMAND} -E false)
@@ -202,8 +201,8 @@
   run_cmake_command(BuildDir--build--parallel-large ${CMAKE_COMMAND} -E chdir ..
     ${CMAKE_COMMAND} --build BuildDir-build --parallel 4294967293)
 
-  # No default jobs for Xcode and FreeBSD build command
-  if(NOT RunCMake_GENERATOR MATCHES "Xcode" AND NOT CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
+  # No default jobs for FreeBSD build command
+  if(NOT CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
     run_cmake_command(BuildDir--build-jobs-no-number ${CMAKE_COMMAND} -E chdir ..
       ${CMAKE_COMMAND} --build BuildDir-build -j)
     run_cmake_command(BuildDir--build-jobs-no-number-trailing--target ${CMAKE_COMMAND} -E chdir ..
@@ -790,7 +789,7 @@
         "test.tmp was not deleted")
   endif()
   file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}/ExpandSourceDir")
-  run_cmake_command(llvm_rc_full_run ${CMAKE_COMMAND} -E cmake_llvm_rc ${RunCMake_TEST_BINARY_DIR}/ExpandSourceDir/source_file test.tmp ${CMAKE_COMMAND} -E echo "This is a test" ++ ${CMAKE_COMMAND} -E copy test.tmp SOURCE_DIR/llvmrc.result )
+  run_cmake_command(llvm_rc_full_run ${CMAKE_COMMAND} -E cmake_llvm_rc ${RunCMake_TEST_BINARY_DIR}/ExpandSourceDir/source_file test.tmp ${CMAKE_COMMAND} -E echo "This is a test" ++ ${LLVM_RC} -bad /FO SOURCE_DIR/llvmrc.result test.tmp )
   if(EXISTS ${RunCMake_TEST_BINARY_DIR}/ExpandSourceDir/test.tmp)
       message(SEND_ERROR "${test} - FAILED:\n"
         "test.tmp was not deleted")
diff --git a/Tests/RunCMake/ExternalData/BadArguments-stderr.txt b/Tests/RunCMake/ExternalData/BadArguments-stderr.txt
new file mode 100644
index 0000000..44efe7e
--- /dev/null
+++ b/Tests/RunCMake/ExternalData/BadArguments-stderr.txt
@@ -0,0 +1,7 @@
+CMake Warning \(dev\) at .*/Modules/ExternalData.cmake:[0-9]+ \(message\):
+  Ignoring unrecognized arguments passed to ExternalData_add_target:
+  `UNKNOWN_ARGUMENT`
+Call Stack \(most recent call first\):
+  BadArguments.cmake:[0-9]+ \(ExternalData_Add_Target\)
+  CMakeLists.txt:[0-9]+ \(include\)
+This warning is for project developers.  Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/ExternalData/BadArguments.cmake b/Tests/RunCMake/ExternalData/BadArguments.cmake
new file mode 100644
index 0000000..dad0007
--- /dev/null
+++ b/Tests/RunCMake/ExternalData/BadArguments.cmake
@@ -0,0 +1,5 @@
+include(ExternalData)
+set(ExternalData_URL_TEMPLATES
+  "file:///path/to/%(algo)/%(hash)"
+  )
+ExternalData_Add_Target(Data UNKNOWN_ARGUMENT)
diff --git a/Tests/RunCMake/ExternalData/RunCMakeTest.cmake b/Tests/RunCMake/ExternalData/RunCMakeTest.cmake
index b5ab22d..b4cc95e 100644
--- a/Tests/RunCMake/ExternalData/RunCMakeTest.cmake
+++ b/Tests/RunCMake/ExternalData/RunCMakeTest.cmake
@@ -2,6 +2,7 @@
 
 run_cmake(BadAlgoMap1)
 run_cmake(BadAlgoMap2)
+run_cmake(BadArguments)
 run_cmake(BadCustom1)
 run_cmake(BadCustom2)
 run_cmake(BadCustom3)
diff --git a/Tests/RunCMake/GNUInstallDirs/GetAbs-stderr.txt b/Tests/RunCMake/GNUInstallDirs/GetAbs-stderr.txt
new file mode 100644
index 0000000..ec9a2dd
--- /dev/null
+++ b/Tests/RunCMake/GNUInstallDirs/GetAbs-stderr.txt
@@ -0,0 +1,12 @@
+^PROJ1_FULL_BINDIR='/usr/bin'
+CMake Warning \(dev\) at [^
+]*/Modules/GNUInstallDirs.cmake:[0-9]+ \(message\):
+  GNUInstallDirs_get_absolute_install_dir called without third argument.
+  Using \${dir} from the caller's scope for compatibility with CMake 3.19 and
+  below.
+Call Stack \(most recent call first\):
+  GetAbs.cmake:10 \(GNUInstallDirs_get_absolute_install_dir\)
+  CMakeLists.txt:3 \(include\)
+This warning is for project developers.  Use -Wno-dev to suppress it.
++
+PROJ2_FULL_BINDIR='/usr/bin'$
diff --git a/Tests/RunCMake/GNUInstallDirs/GetAbs.cmake b/Tests/RunCMake/GNUInstallDirs/GetAbs.cmake
new file mode 100644
index 0000000..7d5bfc8
--- /dev/null
+++ b/Tests/RunCMake/GNUInstallDirs/GetAbs.cmake
@@ -0,0 +1,11 @@
+set(CMAKE_SIZEOF_VOID_P 8)
+set(CMAKE_LIBRARY_ARCHITECTURE "arch")
+set(CMAKE_INSTALL_PREFIX /usr)
+include(GNUInstallDirs)
+
+GNUInstallDirs_get_absolute_install_dir(PROJ1_FULL_BINDIR CMAKE_INSTALL_BINDIR BINDIR)
+message("PROJ1_FULL_BINDIR='${PROJ1_FULL_BINDIR}'")
+
+set(dir BINDIR)
+GNUInstallDirs_get_absolute_install_dir(PROJ2_FULL_BINDIR CMAKE_INSTALL_BINDIR)
+message("PROJ2_FULL_BINDIR='${PROJ2_FULL_BINDIR}'")
diff --git a/Tests/RunCMake/GNUInstallDirs/RunCMakeTest.cmake b/Tests/RunCMake/GNUInstallDirs/RunCMakeTest.cmake
index 529e10a..395ff30 100644
--- a/Tests/RunCMake/GNUInstallDirs/RunCMakeTest.cmake
+++ b/Tests/RunCMake/GNUInstallDirs/RunCMakeTest.cmake
@@ -21,4 +21,5 @@
   unset(RunCMake-stderr-file)
 endforeach()
 
+run_cmake(GetAbs)
 run_cmake(NoSystem)
diff --git a/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake b/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake
index 6349112..edeb6bd 100644
--- a/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake
+++ b/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake
@@ -35,6 +35,9 @@
 run_cmake(TARGET_NAME_IF_EXISTS-empty-arg)
 run_cmake(TARGET_NAME_IF_EXISTS)
 run_cmake(TARGET_NAME_IF_EXISTS-not-a-target)
+run_cmake(TARGET_NAME_IF_EXISTS-alias-target)
+run_cmake(TARGET_NAME_IF_EXISTS-imported-target)
+run_cmake(TARGET_NAME_IF_EXISTS-imported-global-target)
 run_cmake(REMOVE_DUPLICATES-empty)
 run_cmake(REMOVE_DUPLICATES-1)
 run_cmake(REMOVE_DUPLICATES-2)
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_NAME_IF_EXISTS-alias-target-check.cmake b/Tests/RunCMake/GeneratorExpression/TARGET_NAME_IF_EXISTS-alias-target-check.cmake
new file mode 100644
index 0000000..8ae2ecc
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/TARGET_NAME_IF_EXISTS-alias-target-check.cmake
@@ -0,0 +1,5 @@
+file(READ "${RunCMake_TEST_BINARY_DIR}/TARGET_NAME_IF_EXISTS-generated-alias.txt" content)
+
+if(NOT content STREQUAL aliasTarget)
+  set(RunCMake_TEST_FAILED "actual content:\n ${content}\nbut expected [[aliasTarget]]")
+endif()
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_NAME_IF_EXISTS-alias-target.cmake b/Tests/RunCMake/GeneratorExpression/TARGET_NAME_IF_EXISTS-alias-target.cmake
new file mode 100644
index 0000000..d3ef0f8
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/TARGET_NAME_IF_EXISTS-alias-target.cmake
@@ -0,0 +1,8 @@
+enable_language(CXX)
+
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/dummy_executable.cpp" "int main(int,char**) { return 0; }\n")
+add_executable(executableTarget "${CMAKE_CURRENT_BINARY_DIR}/dummy_executable.cpp")
+add_executable(aliasTarget ALIAS executableTarget)
+
+cmake_policy(SET CMP0070 NEW)
+file(GENERATE OUTPUT TARGET_NAME_IF_EXISTS-generated-alias.txt CONTENT "$<TARGET_NAME_IF_EXISTS:aliasTarget>")
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_NAME_IF_EXISTS-imported-global-target-check.cmake b/Tests/RunCMake/GeneratorExpression/TARGET_NAME_IF_EXISTS-imported-global-target-check.cmake
new file mode 100644
index 0000000..b14c9e1
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/TARGET_NAME_IF_EXISTS-imported-global-target-check.cmake
@@ -0,0 +1,5 @@
+file(READ "${RunCMake_TEST_BINARY_DIR}/TARGET_NAME_IF_EXISTS-generated-imported-global.txt" content)
+
+if(NOT content STREQUAL importedGlobalTarget)
+  set(RunCMake_TEST_FAILED "actual content:\n ${content}\nbut expected [[importedGlobalTarget]]")
+endif()
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_NAME_IF_EXISTS-imported-global-target.cmake b/Tests/RunCMake/GeneratorExpression/TARGET_NAME_IF_EXISTS-imported-global-target.cmake
new file mode 100644
index 0000000..b685558
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/TARGET_NAME_IF_EXISTS-imported-global-target.cmake
@@ -0,0 +1,4 @@
+add_executable(importedGlobalTarget IMPORTED GLOBAL)
+
+cmake_policy(SET CMP0070 NEW)
+file(GENERATE OUTPUT TARGET_NAME_IF_EXISTS-generated-imported-global.txt CONTENT "$<TARGET_NAME_IF_EXISTS:importedGlobalTarget>")
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_NAME_IF_EXISTS-imported-target-check.cmake b/Tests/RunCMake/GeneratorExpression/TARGET_NAME_IF_EXISTS-imported-target-check.cmake
new file mode 100644
index 0000000..9615893
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/TARGET_NAME_IF_EXISTS-imported-target-check.cmake
@@ -0,0 +1,5 @@
+file(READ "${RunCMake_TEST_BINARY_DIR}/TARGET_NAME_IF_EXISTS-generated-imported.txt" content)
+
+if(NOT content STREQUAL importedTarget)
+  set(RunCMake_TEST_FAILED "actual content:\n ${content}\nbut expected [[importedTarget]]")
+endif()
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_NAME_IF_EXISTS-imported-target.cmake b/Tests/RunCMake/GeneratorExpression/TARGET_NAME_IF_EXISTS-imported-target.cmake
new file mode 100644
index 0000000..2008907
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/TARGET_NAME_IF_EXISTS-imported-target.cmake
@@ -0,0 +1,4 @@
+add_executable(importedTarget IMPORTED)
+
+cmake_policy(SET CMP0070 NEW)
+file(GENERATE OUTPUT TARGET_NAME_IF_EXISTS-generated-imported.txt CONTENT "$<TARGET_NAME_IF_EXISTS:importedTarget>")
diff --git a/Tests/RunCMake/MSVCRuntimeTypeInfo/CMP0117-NEW.cmake b/Tests/RunCMake/MSVCRuntimeTypeInfo/CMP0117-NEW.cmake
new file mode 100644
index 0000000..c8b0a91
--- /dev/null
+++ b/Tests/RunCMake/MSVCRuntimeTypeInfo/CMP0117-NEW.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0117 NEW)
+include(CMP0117-common.cmake)
diff --git a/Tests/RunCMake/MSVCRuntimeTypeInfo/CMP0117-OLD.cmake b/Tests/RunCMake/MSVCRuntimeTypeInfo/CMP0117-OLD.cmake
new file mode 100644
index 0000000..c0a61d0
--- /dev/null
+++ b/Tests/RunCMake/MSVCRuntimeTypeInfo/CMP0117-OLD.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0117 OLD)
+include(CMP0117-common.cmake)
diff --git a/Tests/RunCMake/MSVCRuntimeTypeInfo/CMP0117-WARN.cmake b/Tests/RunCMake/MSVCRuntimeTypeInfo/CMP0117-WARN.cmake
new file mode 100644
index 0000000..37d1b64
--- /dev/null
+++ b/Tests/RunCMake/MSVCRuntimeTypeInfo/CMP0117-WARN.cmake
@@ -0,0 +1,2 @@
+
+include(CMP0117-common.cmake)
diff --git a/Tests/RunCMake/MSVCRuntimeTypeInfo/CMP0117-common.cmake b/Tests/RunCMake/MSVCRuntimeTypeInfo/CMP0117-common.cmake
new file mode 100644
index 0000000..5dda623
--- /dev/null
+++ b/Tests/RunCMake/MSVCRuntimeTypeInfo/CMP0117-common.cmake
@@ -0,0 +1,12 @@
+enable_language(CXX)
+
+cmake_policy(GET CMP0117 cmp0117)
+if(cmp0117 STREQUAL "NEW")
+  if(" ${CMAKE_CXX_FLAGS} " MATCHES " ([/-]GR) ")
+    message(SEND_ERROR "CMAKE_CXX_FLAGS has '${CMAKE_MATCH_1}' under NEW behavior")
+  endif()
+else()
+  if(NOT " ${CMAKE_CXX_FLAGS} " MATCHES " /GR ")
+    message(SEND_ERROR "CMAKE_CXX_FLAGS does not have '/GR' under OLD behavior")
+  endif()
+endif()
diff --git a/Tests/RunCMake/MSVCRuntimeTypeInfo/CMakeLists.txt b/Tests/RunCMake/MSVCRuntimeTypeInfo/CMakeLists.txt
new file mode 100644
index 0000000..3e470a2
--- /dev/null
+++ b/Tests/RunCMake/MSVCRuntimeTypeInfo/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.14)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/MSVCRuntimeTypeInfo/RunCMakeTest.cmake b/Tests/RunCMake/MSVCRuntimeTypeInfo/RunCMakeTest.cmake
new file mode 100644
index 0000000..c870f59
--- /dev/null
+++ b/Tests/RunCMake/MSVCRuntimeTypeInfo/RunCMakeTest.cmake
@@ -0,0 +1,5 @@
+include(RunCMake)
+
+run_cmake(CMP0117-WARN)
+run_cmake(CMP0117-OLD)
+run_cmake(CMP0117-NEW)
diff --git a/Tests/RunCMake/Make/MakefileConflict.cmake b/Tests/RunCMake/Make/MakefileConflict.cmake
new file mode 100644
index 0000000..6a8406f
--- /dev/null
+++ b/Tests/RunCMake/Make/MakefileConflict.cmake
@@ -0,0 +1,5 @@
+add_custom_target(Custom)
+
+# Write a file that GNU make will prefer over "Makefile"
+# if 'cmake --build' does not explicitly specify it.
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/GNUmakefile" "")
diff --git a/Tests/RunCMake/Make/RunCMakeTest.cmake b/Tests/RunCMake/Make/RunCMakeTest.cmake
index 5562aca..b66e30e 100644
--- a/Tests/RunCMake/Make/RunCMakeTest.cmake
+++ b/Tests/RunCMake/Make/RunCMakeTest.cmake
@@ -42,6 +42,14 @@
 run_cmake(CustomCommandDepfile-ERROR)
 run_cmake(IncludeRegexSubdir)
 
+function(run_MakefileConflict)
+  run_cmake(MakefileConflict)
+  set(RunCMake_TEST_NO_CLEAN 1)
+  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/MakefileConflict-build)
+  run_cmake_command(MakefileConflict-build ${CMAKE_COMMAND} --build . --target Custom)
+endfunction()
+run_MakefileConflict()
+
 function(run_CMP0113 val)
   set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/CMP0113-${val}-build)
   run_cmake(CMP0113-${val})
diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandGenerator-debug-in-release-graph-clean-ninja-check.cmake b/Tests/RunCMake/NinjaMultiConfig/CustomCommandGenerator-debug-clean-again-ninja-check.cmake
similarity index 100%
rename from Tests/RunCMake/NinjaMultiConfig/CustomCommandGenerator-debug-in-release-graph-clean-ninja-check.cmake
rename to Tests/RunCMake/NinjaMultiConfig/CustomCommandGenerator-debug-clean-again-ninja-check.cmake
diff --git a/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake b/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake
index 6699a09..2411114 100644
--- a/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake
+++ b/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake
@@ -215,7 +215,7 @@
 run_cmake_build(CustomCommandGenerator release-clean Release clean)
 run_cmake_build(CustomCommandGenerator debug-in-release-graph Release generated:Debug)
 run_cmake_command(CustomCommandGenerator-debug-in-release-graph-generated "${TARGET_FILE_generated_Debug}")
-run_ninja(CustomCommandGenerator debug-in-release-graph-clean build-Debug.ninja clean:Debug)
+run_ninja(CustomCommandGenerator debug-clean-again build-Debug.ninja clean:Debug)
 run_ninja(CustomCommandGenerator release-in-debug-graph build-Debug.ninja generated:Release)
 run_cmake_command(CustomCommandGenerator-release-in-debug-graph-generated "${TARGET_FILE_generated_Release}")
 unset(RunCMake_TEST_NO_CLEAN)
diff --git a/Tests/RunCMake/Syntax/FunctionUnmatched-stderr.txt b/Tests/RunCMake/Syntax/FunctionUnmatched-stderr.txt
index 306c255..87fa746 100644
--- a/Tests/RunCMake/Syntax/FunctionUnmatched-stderr.txt
+++ b/Tests/RunCMake/Syntax/FunctionUnmatched-stderr.txt
@@ -1,8 +1,4 @@
-^CMake Error in FunctionUnmatched.cmake:
-  A logical block opening on the line
-
-    .*/Tests/RunCMake/Syntax/FunctionUnmatched.cmake:[0-9]+ \(function\)
-
-  is not closed.
+^CMake Error at FunctionUnmatched\.cmake:[0-9]+ \(function\):
+  Flow control statements are not properly nested\.
 Call Stack \(most recent call first\):
-  CMakeLists.txt:[0-9]+ \(include\)$
+  CMakeLists\.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/Syntax/FunctionUnmatchedForeach-stderr.txt b/Tests/RunCMake/Syntax/FunctionUnmatchedForeach-stderr.txt
index f4ff709..7904b87 100644
--- a/Tests/RunCMake/Syntax/FunctionUnmatchedForeach-stderr.txt
+++ b/Tests/RunCMake/Syntax/FunctionUnmatchedForeach-stderr.txt
@@ -1,8 +1,4 @@
-^CMake Error at FunctionUnmatchedForeach.cmake:[0-9]+ \(f\):
-  A logical block opening on the line
-
-    .*/Tests/RunCMake/Syntax/FunctionUnmatchedForeach.cmake:[0-9]+ \(foreach\)
-
-  is not closed.
+^CMake Error at FunctionUnmatchedForeach\.cmake:[0-9]+ \(endfunction\):
+  Flow control statements are not properly nested\.
 Call Stack \(most recent call first\):
-  CMakeLists.txt:[0-9]+ \(include\)$
+  CMakeLists\.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/CommandLine/E_server-arg-result.txt b/Tests/RunCMake/Syntax/ImproperNesting-result.txt
similarity index 100%
copy from Tests/RunCMake/CommandLine/E_server-arg-result.txt
copy to Tests/RunCMake/Syntax/ImproperNesting-result.txt
diff --git a/Tests/RunCMake/Syntax/ImproperNesting-stderr.txt b/Tests/RunCMake/Syntax/ImproperNesting-stderr.txt
new file mode 100644
index 0000000..a209ef6
--- /dev/null
+++ b/Tests/RunCMake/Syntax/ImproperNesting-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at ImproperNesting\.cmake:[0-9]+ \(endforeach\):
+  Flow control statements are not properly nested\.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/Syntax/ImproperNesting.cmake b/Tests/RunCMake/Syntax/ImproperNesting.cmake
new file mode 100644
index 0000000..47ff9f9
--- /dev/null
+++ b/Tests/RunCMake/Syntax/ImproperNesting.cmake
@@ -0,0 +1,7 @@
+message(FATAL_ERROR "This should not happen")
+
+foreach(i 1 2)
+  if(1)
+endforeach()
+endif()
+endif()
diff --git a/Tests/RunCMake/Syntax/MacroUnmatched-stderr.txt b/Tests/RunCMake/Syntax/MacroUnmatched-stderr.txt
index 440d863..a7af590 100644
--- a/Tests/RunCMake/Syntax/MacroUnmatched-stderr.txt
+++ b/Tests/RunCMake/Syntax/MacroUnmatched-stderr.txt
@@ -1,8 +1,4 @@
-^CMake Error in MacroUnmatched.cmake:
-  A logical block opening on the line
-
-    .*/Tests/RunCMake/Syntax/MacroUnmatched.cmake:[0-9]+ \(macro\)
-
-  is not closed.
+^CMake Error at MacroUnmatched\.cmake:[0-9]+ \(macro\):
+  Flow control statements are not properly nested\.
 Call Stack \(most recent call first\):
-  CMakeLists.txt:[0-9]+ \(include\)$
+  CMakeLists\.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/Syntax/MacroUnmatchedForeach-stderr.txt b/Tests/RunCMake/Syntax/MacroUnmatchedForeach-stderr.txt
index 820cd2e..30c4a4c 100644
--- a/Tests/RunCMake/Syntax/MacroUnmatchedForeach-stderr.txt
+++ b/Tests/RunCMake/Syntax/MacroUnmatchedForeach-stderr.txt
@@ -1,8 +1,4 @@
-^CMake Error at MacroUnmatchedForeach.cmake:[0-9]+ \(m\):
-  A logical block opening on the line
-
-    .*/Tests/RunCMake/Syntax/MacroUnmatchedForeach.cmake:[0-9]+ \(foreach\)
-
-  is not closed.
+^CMake Error at MacroUnmatchedForeach\.cmake:[0-9]+ \(endmacro\):
+  Flow control statements are not properly nested\.
 Call Stack \(most recent call first\):
-  CMakeLists.txt:[0-9]+ \(include\)$
+  CMakeLists\.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/Syntax/Override.cmake b/Tests/RunCMake/Syntax/Override.cmake
new file mode 100644
index 0000000..af62db1
--- /dev/null
+++ b/Tests/RunCMake/Syntax/Override.cmake
@@ -0,0 +1,6 @@
+function(override)
+  function(${FUNCTION_NAME})
+  endfunction()
+endfunction()
+override()
+message(FATAL_ERROR "This shouldn't happen")
diff --git a/Tests/RunCMake/CommandLine/E_server-arg-result.txt b/Tests/RunCMake/Syntax/OverrideBreak-result.txt
similarity index 100%
copy from Tests/RunCMake/CommandLine/E_server-arg-result.txt
copy to Tests/RunCMake/Syntax/OverrideBreak-result.txt
diff --git a/Tests/RunCMake/CommandLine/E_server-arg-result.txt b/Tests/RunCMake/Syntax/OverrideContinue-result.txt
similarity index 100%
copy from Tests/RunCMake/CommandLine/E_server-arg-result.txt
copy to Tests/RunCMake/Syntax/OverrideContinue-result.txt
diff --git a/Tests/RunCMake/CommandLine/E_server-arg-result.txt b/Tests/RunCMake/Syntax/OverrideElse-result.txt
similarity index 100%
copy from Tests/RunCMake/CommandLine/E_server-arg-result.txt
copy to Tests/RunCMake/Syntax/OverrideElse-result.txt
diff --git a/Tests/RunCMake/CommandLine/E_server-arg-result.txt b/Tests/RunCMake/Syntax/OverrideElseIf-result.txt
similarity index 100%
copy from Tests/RunCMake/CommandLine/E_server-arg-result.txt
copy to Tests/RunCMake/Syntax/OverrideElseIf-result.txt
diff --git a/Tests/RunCMake/cmake_path/CONCAT-wrong-path-result.txt b/Tests/RunCMake/Syntax/OverrideEndForeach-result.txt
similarity index 100%
copy from Tests/RunCMake/cmake_path/CONCAT-wrong-path-result.txt
copy to Tests/RunCMake/Syntax/OverrideEndForeach-result.txt
diff --git a/Tests/RunCMake/cmake_path/CONCAT-wrong-path-result.txt b/Tests/RunCMake/Syntax/OverrideEndFunction-result.txt
similarity index 100%
copy from Tests/RunCMake/cmake_path/CONCAT-wrong-path-result.txt
copy to Tests/RunCMake/Syntax/OverrideEndFunction-result.txt
diff --git a/Tests/RunCMake/CommandLine/E_server-arg-result.txt b/Tests/RunCMake/Syntax/OverrideEndIf-result.txt
similarity index 100%
copy from Tests/RunCMake/CommandLine/E_server-arg-result.txt
copy to Tests/RunCMake/Syntax/OverrideEndIf-result.txt
diff --git a/Tests/RunCMake/CommandLine/E_server-arg-result.txt b/Tests/RunCMake/Syntax/OverrideEndMacro-result.txt
similarity index 100%
copy from Tests/RunCMake/CommandLine/E_server-arg-result.txt
copy to Tests/RunCMake/Syntax/OverrideEndMacro-result.txt
diff --git a/Tests/RunCMake/CommandLine/E_server-arg-result.txt b/Tests/RunCMake/Syntax/OverrideEndWhile-result.txt
similarity index 100%
copy from Tests/RunCMake/CommandLine/E_server-arg-result.txt
copy to Tests/RunCMake/Syntax/OverrideEndWhile-result.txt
diff --git a/Tests/RunCMake/cmake_path/CONCAT-wrong-path-result.txt b/Tests/RunCMake/Syntax/OverrideForeach-result.txt
similarity index 100%
rename from Tests/RunCMake/cmake_path/CONCAT-wrong-path-result.txt
rename to Tests/RunCMake/Syntax/OverrideForeach-result.txt
diff --git a/Tests/RunCMake/CommandLine/E_server-arg-result.txt b/Tests/RunCMake/Syntax/OverrideFunction-result.txt
similarity index 100%
copy from Tests/RunCMake/CommandLine/E_server-arg-result.txt
copy to Tests/RunCMake/Syntax/OverrideFunction-result.txt
diff --git a/Tests/RunCMake/CommandLine/E_server-arg-result.txt b/Tests/RunCMake/Syntax/OverrideIf-result.txt
similarity index 100%
copy from Tests/RunCMake/CommandLine/E_server-arg-result.txt
copy to Tests/RunCMake/Syntax/OverrideIf-result.txt
diff --git a/Tests/RunCMake/CommandLine/E_server-arg-result.txt b/Tests/RunCMake/Syntax/OverrideMacro-result.txt
similarity index 100%
copy from Tests/RunCMake/CommandLine/E_server-arg-result.txt
copy to Tests/RunCMake/Syntax/OverrideMacro-result.txt
diff --git a/Tests/RunCMake/CommandLine/E_server-arg-result.txt b/Tests/RunCMake/Syntax/OverrideReturn-result.txt
similarity index 100%
copy from Tests/RunCMake/CommandLine/E_server-arg-result.txt
copy to Tests/RunCMake/Syntax/OverrideReturn-result.txt
diff --git a/Tests/RunCMake/CommandLine/E_server-arg-result.txt b/Tests/RunCMake/Syntax/OverrideWhile-result.txt
similarity index 100%
copy from Tests/RunCMake/CommandLine/E_server-arg-result.txt
copy to Tests/RunCMake/Syntax/OverrideWhile-result.txt
diff --git a/Tests/RunCMake/Syntax/RunCMakeTest.cmake b/Tests/RunCMake/Syntax/RunCMakeTest.cmake
index 8d74dc1..4d24657 100644
--- a/Tests/RunCMake/Syntax/RunCMakeTest.cmake
+++ b/Tests/RunCMake/Syntax/RunCMakeTest.cmake
@@ -72,6 +72,7 @@
 run_cmake(UnterminatedBracket0)
 run_cmake(UnterminatedBracket1)
 run_cmake(UnterminatedBracketComment)
+run_cmake(ImproperNesting)
 
 # Variable expansion tests
 run_cmake(ExpandInAt)
@@ -122,3 +123,30 @@
 run_cmake(FunctionUnmatchedForeach)
 run_cmake(MacroUnmatched)
 run_cmake(MacroUnmatchedForeach)
+
+function(run_override name)
+  string(TOLOWER "${name}" lname)
+  set(RunCMake_DEFAULT_stderr "^CMake Error at [^
+]*/Tests/RunCMake/Syntax/Override\\.cmake:[0-9]+ \\(function\\):
+  Built-in flow control command \"${lname}\" cannot be overridden\\.
+Call Stack \\(most recent call first\\):
+  [^
+]*/Tests/RunCMake/Syntax/Override\\.cmake:[0-9]+ \\(override\\)$")
+  run_cmake_command(Override${name} "${CMAKE_COMMAND}" -DFUNCTION_NAME=${name} -P "${RunCMake_SOURCE_DIR}/Override.cmake")
+endfunction()
+
+run_override(Break)
+run_override(Continue)
+run_override(Else)
+run_override(ElseIf)
+run_override(EndForeach)
+run_override(EndFunction)
+run_override(EndIf)
+run_override(EndMacro)
+run_override(EndWhile)
+run_override(Foreach)
+run_override(Function)
+run_override(If)
+run_override(Macro)
+run_override(Return)
+run_override(While)
diff --git a/Tests/RunCMake/TargetSources/AddCustomTargetCheckProperty.cmake b/Tests/RunCMake/TargetSources/AddCustomTargetCheckProperty.cmake
new file mode 100644
index 0000000..1787e87
--- /dev/null
+++ b/Tests/RunCMake/TargetSources/AddCustomTargetCheckProperty.cmake
@@ -0,0 +1,16 @@
+add_custom_target(target1 ALL)
+target_sources(target1 PRIVATE main.cpp)
+get_property(actualProp1 TARGET target1 PROPERTY SOURCES)
+set(desiredProp1 main.cpp)
+if(NOT desiredProp1 STREQUAL actualProp1)
+  message("source property not set. desired: \"${desiredProp1}\" actual: \"${actualProp1}\"")
+endif()
+
+add_custom_target(target2 ALL SOURCES main.cpp)
+target_sources(target2 PRIVATE empty_1.cpp empty_2.cpp)
+target_sources(target2 PRIVATE empty_3.cpp)
+get_property(actualProp2 TARGET target2 PROPERTY SOURCES)
+set(desiredProp2 main.cpp empty_1.cpp empty_2.cpp empty_3.cpp)
+if (NOT desiredProp2 STREQUAL actualProp2)
+  message("source property not set. desired: \"${desiredProp2}\" actual: \"${actualProp2}\"")
+endif()
diff --git a/Tests/RunCMake/TargetSources/AddCustomTargetGenx.cmake b/Tests/RunCMake/TargetSources/AddCustomTargetGenx.cmake
new file mode 100644
index 0000000..0078eab
--- /dev/null
+++ b/Tests/RunCMake/TargetSources/AddCustomTargetGenx.cmake
@@ -0,0 +1,2 @@
+add_custom_target(target ALL)
+target_sources(target PRIVATE $<IF:1,${CMAKE_CURRENT_LIST_DIR}/main.cpp,${CMAKE_CURRENT_LIST_DIR}/empty_1.cpp>)
diff --git a/Tests/RunCMake/CommandLine/E_server-arg-result.txt b/Tests/RunCMake/TargetSources/AddCustomTargetInterfaceSources-result.txt
similarity index 100%
copy from Tests/RunCMake/CommandLine/E_server-arg-result.txt
copy to Tests/RunCMake/TargetSources/AddCustomTargetInterfaceSources-result.txt
diff --git a/Tests/RunCMake/TargetSources/AddCustomTargetInterfaceSources-stderr.txt b/Tests/RunCMake/TargetSources/AddCustomTargetInterfaceSources-stderr.txt
new file mode 100644
index 0000000..9334bf6
--- /dev/null
+++ b/Tests/RunCMake/TargetSources/AddCustomTargetInterfaceSources-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at AddCustomTargetInterfaceSources.cmake:2 \(target_sources\):
+  target_sources may only set PRIVATE properties on custom targets
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/TargetSources/AddCustomTargetInterfaceSources.cmake b/Tests/RunCMake/TargetSources/AddCustomTargetInterfaceSources.cmake
new file mode 100644
index 0000000..42a8ca2
--- /dev/null
+++ b/Tests/RunCMake/TargetSources/AddCustomTargetInterfaceSources.cmake
@@ -0,0 +1,2 @@
+add_custom_target(target ALL)
+target_sources(target INTERFACE main.cpp)
diff --git a/Tests/RunCMake/TargetSources/AddCustomTargetPrivateSources.cmake b/Tests/RunCMake/TargetSources/AddCustomTargetPrivateSources.cmake
new file mode 100644
index 0000000..11f0258
--- /dev/null
+++ b/Tests/RunCMake/TargetSources/AddCustomTargetPrivateSources.cmake
@@ -0,0 +1,2 @@
+add_custom_target(target ALL)
+target_sources(target PRIVATE main.cpp)
diff --git a/Tests/RunCMake/CommandLine/E_server-arg-result.txt b/Tests/RunCMake/TargetSources/AddCustomTargetPublicSources-result.txt
similarity index 100%
copy from Tests/RunCMake/CommandLine/E_server-arg-result.txt
copy to Tests/RunCMake/TargetSources/AddCustomTargetPublicSources-result.txt
diff --git a/Tests/RunCMake/TargetSources/AddCustomTargetPublicSources-stderr.txt b/Tests/RunCMake/TargetSources/AddCustomTargetPublicSources-stderr.txt
new file mode 100644
index 0000000..afba4be
--- /dev/null
+++ b/Tests/RunCMake/TargetSources/AddCustomTargetPublicSources-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at AddCustomTargetPublicSources.cmake:2 \(target_sources\):
+  target_sources may only set PRIVATE properties on custom targets
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/TargetSources/AddCustomTargetPublicSources.cmake b/Tests/RunCMake/TargetSources/AddCustomTargetPublicSources.cmake
new file mode 100644
index 0000000..d9e82c0
--- /dev/null
+++ b/Tests/RunCMake/TargetSources/AddCustomTargetPublicSources.cmake
@@ -0,0 +1,2 @@
+add_custom_target(target ALL)
+target_sources(target PUBLIC main.cpp)
diff --git a/Tests/RunCMake/CommandLine/E_server-arg-result.txt b/Tests/RunCMake/TargetSources/AddCustomTargetSources-result.txt
similarity index 100%
copy from Tests/RunCMake/CommandLine/E_server-arg-result.txt
copy to Tests/RunCMake/TargetSources/AddCustomTargetSources-result.txt
diff --git a/Tests/RunCMake/TargetSources/AddCustomTargetSources-stderr.txt b/Tests/RunCMake/TargetSources/AddCustomTargetSources-stderr.txt
new file mode 100644
index 0000000..4a153e9
--- /dev/null
+++ b/Tests/RunCMake/TargetSources/AddCustomTargetSources-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at AddCustomTargetSources.cmake:2 \(target_sources\):
+  target_sources called with invalid arguments
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/TargetSources/AddCustomTargetSources.cmake b/Tests/RunCMake/TargetSources/AddCustomTargetSources.cmake
new file mode 100644
index 0000000..dd688d3
--- /dev/null
+++ b/Tests/RunCMake/TargetSources/AddCustomTargetSources.cmake
@@ -0,0 +1,2 @@
+add_custom_target(target ALL)
+target_sources(target main.cpp)
diff --git a/Tests/RunCMake/TargetSources/RunCMakeTest.cmake b/Tests/RunCMake/TargetSources/RunCMakeTest.cmake
index 0d462ba..b56ee44 100644
--- a/Tests/RunCMake/TargetSources/RunCMakeTest.cmake
+++ b/Tests/RunCMake/TargetSources/RunCMakeTest.cmake
@@ -14,3 +14,9 @@
 run_cmake(RelativePathInSubdirPrivate)
 run_cmake(RelativePathInSubdirInclude)
 run_cmake(ExportBuild)
+run_cmake(AddCustomTargetPublicSources)
+run_cmake(AddCustomTargetPrivateSources)
+run_cmake(AddCustomTargetInterfaceSources)
+run_cmake(AddCustomTargetSources)
+run_cmake(AddCustomTargetCheckProperty)
+run_cmake(AddCustomTargetGenx)
diff --git a/Tests/RunCMake/ToolchainFile/CheckLanguage-stdout.txt b/Tests/RunCMake/ToolchainFile/CheckLanguage-stdout.txt
new file mode 100644
index 0000000..b96eee6
--- /dev/null
+++ b/Tests/RunCMake/ToolchainFile/CheckLanguage-stdout.txt
@@ -0,0 +1 @@
+-- Looking for a C compiler - NOTFOUND
diff --git a/Tests/RunCMake/ToolchainFile/CheckLanguage-toolchain.cmake b/Tests/RunCMake/ToolchainFile/CheckLanguage-toolchain.cmake
new file mode 100644
index 0000000..081f905
--- /dev/null
+++ b/Tests/RunCMake/ToolchainFile/CheckLanguage-toolchain.cmake
@@ -0,0 +1,4 @@
+get_property(in_try_compile GLOBAL PROPERTY IN_TRY_COMPILE)
+if(in_try_compile)
+  message(FATAL_ERROR "Toolchain file included")
+endif()
diff --git a/Tests/RunCMake/ToolchainFile/CheckLanguage.cmake b/Tests/RunCMake/ToolchainFile/CheckLanguage.cmake
new file mode 100644
index 0000000..854b3d4
--- /dev/null
+++ b/Tests/RunCMake/ToolchainFile/CheckLanguage.cmake
@@ -0,0 +1,2 @@
+include(CheckLanguage)
+check_language(C)
diff --git a/Tests/RunCMake/ToolchainFile/RunCMakeTest.cmake b/Tests/RunCMake/ToolchainFile/RunCMakeTest.cmake
index 7eb4485..659523c 100644
--- a/Tests/RunCMake/ToolchainFile/RunCMakeTest.cmake
+++ b/Tests/RunCMake/ToolchainFile/RunCMakeTest.cmake
@@ -7,6 +7,7 @@
 
 run_cmake_toolchain(CallEnableLanguage)
 run_cmake_toolchain(CallProject)
+run_cmake_toolchain(CheckLanguage)
 run_cmake_toolchain(FlagsInit)
 run_cmake_toolchain(LinkFlagsInit)
 
diff --git a/Tests/RunCMake/TransformDepfile/RunCMakeTest.cmake b/Tests/RunCMake/TransformDepfile/RunCMakeTest.cmake
new file mode 100644
index 0000000..cb75eb0
--- /dev/null
+++ b/Tests/RunCMake/TransformDepfile/RunCMakeTest.cmake
@@ -0,0 +1,21 @@
+include(RunCMake)
+
+function(run_transform_depfile name)
+  set(RunCMake-check-file gccdepfile.cmake)
+  run_cmake_command(${name}-gcc
+    ${CMAKE_COMMAND} -E cmake_transform_depfile gccdepfile ../ ${CMAKE_CURRENT_LIST_DIR}/${name}.d out.d
+    )
+  set(RunCMake-check-file vstlog.cmake)
+  run_cmake_command(${name}-tlog
+    ${CMAKE_COMMAND} -E cmake_transform_depfile vstlog ../ ${CMAKE_CURRENT_LIST_DIR}/${name}.d out.tlog
+    )
+endfunction()
+
+if(WIN32)
+  run_transform_depfile(deps-windows)
+else()
+  run_transform_depfile(deps-unix)
+endif()
+run_transform_depfile(noexist)
+run_transform_depfile(empty)
+run_transform_depfile(invalid)
diff --git a/Tests/RunCMake/TransformDepfile/deps-unix.d b/Tests/RunCMake/TransformDepfile/deps-unix.d
new file mode 100644
index 0000000..5da5be8
--- /dev/null
+++ b/Tests/RunCMake/TransformDepfile/deps-unix.d
@@ -0,0 +1,6 @@
+out1 /home/build/out2: in1 /home/build/in2
+
+out3 \
+  /home/build/out4: \
+  in3 \
+  /home/build/in4
diff --git a/Tests/RunCMake/TransformDepfile/deps-unix.d.txt b/Tests/RunCMake/TransformDepfile/deps-unix.d.txt
new file mode 100644
index 0000000..58770f2
--- /dev/null
+++ b/Tests/RunCMake/TransformDepfile/deps-unix.d.txt
@@ -0,0 +1,8 @@
+../out1 \
+  /home/build/out2: \
+  ../in1 \
+  /home/build/in2
+../out3 \
+  /home/build/out4: \
+  ../in3 \
+  /home/build/in4
diff --git a/Tests/RunCMake/TransformDepfile/deps-unix.tlog.txt b/Tests/RunCMake/TransformDepfile/deps-unix.tlog.txt
new file mode 100644
index 0000000..2a26edf
--- /dev/null
+++ b/Tests/RunCMake/TransformDepfile/deps-unix.tlog.txt
@@ -0,0 +1,6 @@
+^../out1|/home/build/out2
+../in1
+/home/build/in2
+^../out3|/home/build/out4
+../in3
+/home/build/in4
diff --git a/Tests/RunCMake/TransformDepfile/deps-windows.d b/Tests/RunCMake/TransformDepfile/deps-windows.d
new file mode 100644
index 0000000..c926670
--- /dev/null
+++ b/Tests/RunCMake/TransformDepfile/deps-windows.d
@@ -0,0 +1,6 @@
+out1 C:/build/out2: in1 C:/build/in2
+
+out3 \
+  C:/build/out4: \
+  in3 \
+  C:/build/in4
diff --git a/Tests/RunCMake/TransformDepfile/deps-windows.d.txt b/Tests/RunCMake/TransformDepfile/deps-windows.d.txt
new file mode 100644
index 0000000..47b3ebf
--- /dev/null
+++ b/Tests/RunCMake/TransformDepfile/deps-windows.d.txt
@@ -0,0 +1,8 @@
+../out1 \
+  C:/build/out2: \
+  ../in1 \
+  C:/build/in2
+../out3 \
+  C:/build/out4: \
+  ../in3 \
+  C:/build/in4
diff --git a/Tests/RunCMake/TransformDepfile/deps-windows.tlog.txt b/Tests/RunCMake/TransformDepfile/deps-windows.tlog.txt
new file mode 100644
index 0000000..1e6024d
--- /dev/null
+++ b/Tests/RunCMake/TransformDepfile/deps-windows.tlog.txt
@@ -0,0 +1,6 @@
+^..\out1|C:\build\out2
+..\in1
+C:\build\in2
+^..\out3|C:\build\out4
+..\in3
+C:\build\in4
diff --git a/Tests/RunCMake/TransformDepfile/empty.d b/Tests/RunCMake/TransformDepfile/empty.d
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/TransformDepfile/empty.d
diff --git a/Tests/RunCMake/TransformDepfile/empty.d.txt b/Tests/RunCMake/TransformDepfile/empty.d.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/TransformDepfile/empty.d.txt
diff --git a/Tests/RunCMake/TransformDepfile/empty.tlog.txt b/Tests/RunCMake/TransformDepfile/empty.tlog.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/TransformDepfile/empty.tlog.txt
diff --git a/Tests/RunCMake/TransformDepfile/gccdepfile.cmake b/Tests/RunCMake/TransformDepfile/gccdepfile.cmake
new file mode 100644
index 0000000..be1e210
--- /dev/null
+++ b/Tests/RunCMake/TransformDepfile/gccdepfile.cmake
@@ -0,0 +1,16 @@
+if(EXISTS "${RunCMake_SOURCE_DIR}/${name}.d.txt")
+  file(READ "${RunCMake_SOURCE_DIR}/${name}.d.txt" expected_contents)
+
+  if(EXISTS "${RunCMake_TEST_BINARY_DIR}/out.d")
+    file(READ "${RunCMake_TEST_BINARY_DIR}/out.d" actual_contents)
+    if(NOT actual_contents STREQUAL expected_contents)
+      string(REPLACE "\n" "\n  " p_expected_contents "${expected_contents}")
+      string(REPLACE "\n" "\n  " p_actual_contents "${actual_contents}")
+      string(APPEND RunCMake_TEST_FAILED "Expected contents of ${RunCMake_TEST_BINARY_DIR}/out.d:\n  ${p_expected_contents}\nActual contents:\n  ${p_actual_contents}")
+    endif()
+  else()
+    string(APPEND RunCMake_TEST_FAILED "${RunCMake_TEST_BINARY_DIR}/out.d should exist\n")
+  endif()
+elseif(EXISTS "${RunCMake_TEST_BINARY_DIR}/out.d")
+  string(APPEND RunCMake_TEST_FAILED "${RunCMake_TEST_BINARY_DIR}/out.d should not exist\n")
+endif()
diff --git a/Tests/RunCMake/CommandLine/E_server-arg-result.txt b/Tests/RunCMake/TransformDepfile/invalid-gcc-result.txt
similarity index 100%
copy from Tests/RunCMake/CommandLine/E_server-arg-result.txt
copy to Tests/RunCMake/TransformDepfile/invalid-gcc-result.txt
diff --git a/Tests/RunCMake/CommandLine/E_server-arg-result.txt b/Tests/RunCMake/TransformDepfile/invalid-tlog-result.txt
similarity index 100%
copy from Tests/RunCMake/CommandLine/E_server-arg-result.txt
copy to Tests/RunCMake/TransformDepfile/invalid-tlog-result.txt
diff --git a/Tests/RunCMake/TransformDepfile/invalid.d b/Tests/RunCMake/TransformDepfile/invalid.d
new file mode 100644
index 0000000..9977a28
--- /dev/null
+++ b/Tests/RunCMake/TransformDepfile/invalid.d
@@ -0,0 +1 @@
+invalid
diff --git a/Tests/RunCMake/TransformDepfile/noexist.d.txt b/Tests/RunCMake/TransformDepfile/noexist.d.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/TransformDepfile/noexist.d.txt
diff --git a/Tests/RunCMake/TransformDepfile/noexist.tlog.txt b/Tests/RunCMake/TransformDepfile/noexist.tlog.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/TransformDepfile/noexist.tlog.txt
diff --git a/Tests/RunCMake/TransformDepfile/vstlog.cmake b/Tests/RunCMake/TransformDepfile/vstlog.cmake
new file mode 100644
index 0000000..afa78d0
--- /dev/null
+++ b/Tests/RunCMake/TransformDepfile/vstlog.cmake
@@ -0,0 +1,16 @@
+if(EXISTS "${RunCMake_SOURCE_DIR}/${name}.tlog.txt")
+  file(READ "${RunCMake_SOURCE_DIR}/${name}.tlog.txt" expected_contents)
+
+  if(EXISTS "${RunCMake_TEST_BINARY_DIR}/out.tlog")
+    file(READ "${RunCMake_TEST_BINARY_DIR}/out.tlog" actual_contents)
+    if(NOT actual_contents STREQUAL expected_contents)
+      string(REPLACE "\n" "\n  " p_expected_contents "${expected_contents}")
+      string(REPLACE "\n" "\n  " p_actual_contents "${actual_contents}")
+      string(APPEND RunCMake_TEST_FAILED "Expected contents of ${RunCMake_TEST_BINARY_DIR}/out.tlog:\n  ${p_expected_contents}\nActual contents:\n  ${p_actual_contents}")
+    endif()
+  else()
+    string(APPEND RunCMake_TEST_FAILED "${RunCMake_TEST_BINARY_DIR}/out.tlog should exist\n")
+  endif()
+elseif(EXISTS "${RunCMake_TEST_BINARY_DIR}/out.tlog")
+  string(APPEND RunCMake_TEST_FAILED "${RunCMake_TEST_BINARY_DIR}/out.tlog should not exist\n")
+endif()
diff --git a/Tests/RunCMake/add_custom_command/AppendNotOutput-stderr.txt b/Tests/RunCMake/add_custom_command/AppendNotOutput-stderr.txt
index b7ee23a..9324302 100644
--- a/Tests/RunCMake/add_custom_command/AppendNotOutput-stderr.txt
+++ b/Tests/RunCMake/add_custom_command/AppendNotOutput-stderr.txt
@@ -1,5 +1,5 @@
 CMake Error at AppendNotOutput.cmake:1 \(add_custom_command\):
-  add_custom_command given APPEND option with output
+  Attempt to APPEND to custom command with output
 
     .*RunCMake/add_custom_command/AppendNotOutput-build/out
 
diff --git a/Tests/RunCMake/add_library/CMP0073-stderr.txt b/Tests/RunCMake/add_library/CMP0073-stderr.txt
new file mode 100644
index 0000000..7f43fd7
--- /dev/null
+++ b/Tests/RunCMake/add_library/CMP0073-stderr.txt
@@ -0,0 +1,10 @@
+^CMake Deprecation Warning at CMP0073.cmake:[0-9]+ \(cmake_policy\):
+  The OLD behavior for policy CMP0073 will be removed from a future version
+  of CMake.
+
+  The cmake-policies\(7\) manual explains that the OLD behaviors of all
+  policies are deprecated and that a policy should be set to OLD only under
+  specific short-term circumstances.  Projects should be ported to the NEW
+  behavior and not rely on setting a policy to OLD.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/cmake_path/CONCAT-OUTPUT_VARIABLE-invalid-arg-result.txt b/Tests/RunCMake/cmake_path/APPEND_STRING-OUTPUT_VARIABLE-invalid-arg-result.txt
similarity index 100%
rename from Tests/RunCMake/cmake_path/CONCAT-OUTPUT_VARIABLE-invalid-arg-result.txt
rename to Tests/RunCMake/cmake_path/APPEND_STRING-OUTPUT_VARIABLE-invalid-arg-result.txt
diff --git a/Tests/RunCMake/cmake_path/CMAKE_PATH-OUTPUT_VARIABLE-no-arg-result.txt b/Tests/RunCMake/cmake_path/APPEND_STRING-OUTPUT_VARIABLE-no-arg-result.txt
similarity index 100%
rename from Tests/RunCMake/cmake_path/CMAKE_PATH-OUTPUT_VARIABLE-no-arg-result.txt
rename to Tests/RunCMake/cmake_path/APPEND_STRING-OUTPUT_VARIABLE-no-arg-result.txt
diff --git a/Tests/RunCMake/cmake_path/CMAKE_PATH-wrong-path-result.txt b/Tests/RunCMake/cmake_path/APPEND_STRING-wrong-path-result.txt
similarity index 100%
rename from Tests/RunCMake/cmake_path/CMAKE_PATH-wrong-path-result.txt
rename to Tests/RunCMake/cmake_path/APPEND_STRING-wrong-path-result.txt
diff --git a/Tests/RunCMake/cmake_path/CONCAT.cmake b/Tests/RunCMake/cmake_path/APPEND_STRING.cmake
similarity index 73%
rename from Tests/RunCMake/cmake_path/CONCAT.cmake
rename to Tests/RunCMake/cmake_path/APPEND_STRING.cmake
index 62b5eb0..ea5f2dd 100644
--- a/Tests/RunCMake/cmake_path/CONCAT.cmake
+++ b/Tests/RunCMake/cmake_path/APPEND_STRING.cmake
@@ -3,13 +3,13 @@
 unset (errors)
 
 set (path "/a/b")
-cmake_path (CONCAT path "cd")
+cmake_path (APPEND_STRING path "cd")
 if (NOT path STREQUAL "/a/bcd")
   list (APPEND errors "'${path}' instead of 'a/bcd'")
 endif()
 
 set (path "/a/b")
-cmake_path (CONCAT path "cd" "ef" OUTPUT_VARIABLE output)
+cmake_path (APPEND_STRING path "cd" "ef" OUTPUT_VARIABLE output)
 if (NOT path STREQUAL "/a/b")
   list (APPEND errors "input changed unexpectedly")
 endif()
@@ -17,4 +17,4 @@
   list (APPEND errors "'${output}' instead of 'a/bcdef'")
 endif()
 
-check_errors (CONCAT ${errors})
+check_errors (APPEND_STRING ${errors})
diff --git a/Tests/RunCMake/cmake_path/CMAKE_PATH-invalid-output-result.txt b/Tests/RunCMake/cmake_path/CMAKE_PATH-invalid-output-result.txt
deleted file mode 100644
index d00491f..0000000
--- a/Tests/RunCMake/cmake_path/CMAKE_PATH-invalid-output-result.txt
+++ /dev/null
@@ -1 +0,0 @@
-1
diff --git a/Tests/RunCMake/cmake_path/COMPARE-EQUAL-wrong-path-result.txt b/Tests/RunCMake/cmake_path/COMPARE-EQUAL-wrong-path-result.txt
deleted file mode 100644
index d00491f..0000000
--- a/Tests/RunCMake/cmake_path/COMPARE-EQUAL-wrong-path-result.txt
+++ /dev/null
@@ -1 +0,0 @@
-1
diff --git a/Tests/RunCMake/cmake_path/COMPARE-NOT_EQUAL-wrong-path-result.txt b/Tests/RunCMake/cmake_path/COMPARE-NOT_EQUAL-wrong-path-result.txt
deleted file mode 100644
index d00491f..0000000
--- a/Tests/RunCMake/cmake_path/COMPARE-NOT_EQUAL-wrong-path-result.txt
+++ /dev/null
@@ -1 +0,0 @@
-1
diff --git a/Tests/RunCMake/cmake_path/COMPARE.cmake b/Tests/RunCMake/cmake_path/COMPARE.cmake
index bc6b9b4..ecf7c82 100644
--- a/Tests/RunCMake/cmake_path/COMPARE.cmake
+++ b/Tests/RunCMake/cmake_path/COMPARE.cmake
@@ -2,19 +2,19 @@
 include ("${RunCMake_SOURCE_DIR}/check_errors.cmake")
 unset (errors)
 
-set (path "a///b/c")
-cmake_path(COMPARE path EQUAL "a/b/c" output)
+set(path "a///b/c")
+cmake_path(COMPARE "${path}" EQUAL "a/b/c" output)
 if (NOT output)
   list (APPEND errors "'${path}' not equal to 'a/b/c'")
 endif()
 
 set (path "a/b/d/../c")
-cmake_path(COMPARE path NOT_EQUAL "a/b/c" output)
+cmake_path(COMPARE "${path}" NOT_EQUAL "a/b/c" output)
 if (NOT output)
   list (APPEND errors "'${path}' equal to 'a/b/c'")
 endif()
 cmake_path(NORMAL_PATH path)
-cmake_path(COMPARE path EQUAL "a/b/c" output)
+cmake_path(COMPARE "${path}" EQUAL "a/b/c" output)
 if (NOT output)
   list (APPEND errors "'${path}' not equal to 'a/b/c'")
 endif()
diff --git a/Tests/RunCMake/cmake_path/CONCAT-OUTPUT_VARIABLE-no-arg-result.txt b/Tests/RunCMake/cmake_path/CONCAT-OUTPUT_VARIABLE-no-arg-result.txt
deleted file mode 100644
index d00491f..0000000
--- a/Tests/RunCMake/cmake_path/CONCAT-OUTPUT_VARIABLE-no-arg-result.txt
+++ /dev/null
@@ -1 +0,0 @@
-1
diff --git a/Tests/RunCMake/cmake_path/PROXIMATE_PATH.cmake b/Tests/RunCMake/cmake_path/PROXIMATE_PATH.cmake
deleted file mode 100644
index ad23377..0000000
--- a/Tests/RunCMake/cmake_path/PROXIMATE_PATH.cmake
+++ /dev/null
@@ -1,41 +0,0 @@
-
-include ("${RunCMake_SOURCE_DIR}/check_errors.cmake")
-unset (errors)
-
-if (WIN32)
-  set (path "c:/a/d")
-  cmake_path(PROXIMATE_PATH path BASE_DIRECTORY "e/d/c")
-  if (NOT path STREQUAL "c:/a/d")
-    list (APPEND errors "'${path}' instead of 'c:/a/d'")
-  endif()
-else()
-  set (path "/a/d")
-  cmake_path(PROXIMATE_PATH path BASE_DIRECTORY "e/d/c")
-  if (NOT path STREQUAL "/a/d")
-    list (APPEND errors "'${path}' instead of '/a/d'")
-  endif()
-endif()
-
-set (path "/a/d")
-cmake_path(PROXIMATE_PATH path BASE_DIRECTORY "/a/b/c" OUTPUT_VARIABLE output)
-if (NOT path STREQUAL "/a/d")
-  list (APPEND errors "input changed unexpectedly")
-endif()
-if (NOT output STREQUAL "../../d")
-  list (APPEND errors "'${output}' instead of '../../d'")
-endif()
-
-set (path "${CMAKE_CURRENT_SOURCE_DIR}/a/d")
-cmake_path(PROXIMATE_PATH path)
-if (NOT path STREQUAL "a/d")
-  list (APPEND errors "'${path}' instead of 'a/d'")
-endif()
-
-set (path "a/b/c")
-cmake_path(PROXIMATE_PATH path)
-if (NOT path STREQUAL "a/b/c")
-  list (APPEND errors "'${path}' instead of 'a/b/c'")
-endif()
-
-
-check_errors (PROXIMATE_PATH ${errors})
diff --git a/Tests/RunCMake/cmake_path/RunCMakeTest.cmake b/Tests/RunCMake/cmake_path/RunCMakeTest.cmake
index ca9cba6..4edfb1a 100644
--- a/Tests/RunCMake/cmake_path/RunCMakeTest.cmake
+++ b/Tests/RunCMake/cmake_path/RunCMakeTest.cmake
@@ -11,14 +11,9 @@
   run_cmake_command (GET-${subcommand}-wrong-path "${CMAKE_COMMAND}" "-DCMAKE_PATH_ARGUMENTS=GET wrong_path ${subcommand} output" -P "${RunCMake_SOURCE_DIR}/call-cmake_path.cmake")
 endforeach()
 
-### COMPARE sub-command
-foreach (subcommand IN ITEMS EQUAL NOT_EQUAL)
-  run_cmake_command (COMPARE-${subcommand}-wrong-path "${CMAKE_COMMAND}" "-DCMAKE_PATH_ARGUMENTS=COMPARE wrong_path ${subcommand} path2 output" -P "${RunCMake_SOURCE_DIR}/call-cmake_path.cmake")
-endforeach()
-
-foreach (command IN ITEMS CONCAT REMOVE_FILENAME REPLACE_FILENAME
+foreach (command IN ITEMS APPEND_STRING REMOVE_FILENAME REPLACE_FILENAME
                           REMOVE_EXTENSION REPLACE_EXTENSION NORMAL_PATH
-                          RELATIVE_PATH PROXIMATE_PATH ABSOLUTE_PATH)
+                          RELATIVE_PATH ABSOLUTE_PATH)
   run_cmake_command (${command}-wrong-path "${CMAKE_COMMAND}" "-DCMAKE_PATH_ARGUMENTS=${command} wrong_path" -P "${RunCMake_SOURCE_DIR}/call-cmake_path.cmake")
 endforeach()
 
@@ -55,7 +50,7 @@
   run_cmake_command (COMPARE-${subcommand}-missing-output "${CMAKE_COMMAND}" "-DCMAKE_PATH_ARGUMENTS=COMPARE path ${subcommand} path2" -P "${RunCMake_SOURCE_DIR}/call-cmake_path.cmake")
 endforeach()
 
-foreach (command IN ITEMS CMAKE_PATH NATIVE_PATH
+foreach (command IN ITEMS SET NATIVE_PATH
                           HAS_ROOT_NAME HAS_ROOT_DIRECTORY HAS_ROOT_PATH
                           HAS_FILENAME HAS_EXTENSION HAS_STEM
                           HAS_RELATIVE_PATH HAS_PARENT_PATH
@@ -72,9 +67,9 @@
 ## OUTPUT_VARIABLE without argument
 set (RunCMake-stderr-file "OUTPUT_VARIABLE-no-arg-stderr.txt")
 
-foreach (command IN ITEMS APPEND CONCAT REMOVE_FILENAME REPLACE_FILENAME
+foreach (command IN ITEMS APPEND APPEND_STRING REMOVE_FILENAME REPLACE_FILENAME
                           REMOVE_EXTENSION REPLACE_EXTENSION NORMAL_PATH
-                          RELATIVE_PATH PROXIMATE_PATH ABSOLUTE_PATH)
+                          RELATIVE_PATH ABSOLUTE_PATH)
   run_cmake_command (${command}-OUTPUT_VARIABLE-no-arg "${CMAKE_COMMAND}" "-DCMAKE_PATH_ARGUMENTS=${command} path OUTPUT_VARIABLE" -P "${RunCMake_SOURCE_DIR}/call-cmake_path.cmake")
 endforeach()
 
@@ -98,7 +93,7 @@
   run_cmake_command (COMPARE-${subcommand}-invalid-output "${CMAKE_COMMAND}" "-DCMAKE_PATH_ARGUMENTS=COMPARE path ${subcommand} path2" -DCHECK_INVALID_OUTPUT=ON -P "${RunCMake_SOURCE_DIR}/call-cmake_path.cmake")
 endforeach()
 
-foreach (command IN ITEMS CMAKE_PATH NATIVE_PATH
+foreach (command IN ITEMS NATIVE_PATH
                           HAS_ROOT_NAME HAS_ROOT_DIRECTORY HAS_ROOT_PATH
                           HAS_FILENAME HAS_EXTENSION HAS_STEM
                           HAS_RELATIVE_PATH HAS_PARENT_PATH
@@ -111,9 +106,9 @@
   run_cmake_command (${command}-invalid-output "${CMAKE_COMMAND}" "-DCMAKE_PATH_ARGUMENTS=${command} path ${extra_args}" -DCHECK_INVALID_OUTPUT=ON -P "${RunCMake_SOURCE_DIR}/call-cmake_path.cmake")
 endforeach()
 
-foreach (command IN ITEMS APPEND CONCAT REMOVE_FILENAME REPLACE_FILENAME
+foreach (command IN ITEMS APPEND APPEND_STRING REMOVE_FILENAME REPLACE_FILENAME
                           REMOVE_EXTENSION REPLACE_EXTENSION NORMAL_PATH
-                          RELATIVE_PATH PROXIMATE_PATH ABSOLUTE_PATH)
+                          RELATIVE_PATH ABSOLUTE_PATH)
   run_cmake_command (${command}-OUTPUT_VARIABLE-invalid-arg "${CMAKE_COMMAND}" "-DCMAKE_PATH_ARGUMENTS=${command} path OUTPUT_VARIABLE" -DCHECK_INVALID_OUTPUT=ON -P "${RunCMake_SOURCE_DIR}/call-cmake_path.cmake")
 endforeach()
 
@@ -139,7 +134,7 @@
 
 foreach (command IN ITEMS REMOVE_FILENAME REPLACE_FILENAME
                           REMOVE_EXTENSION REPLACE_EXTENSION NORMAL_PATH
-                          RELATIVE_PATH PROXIMATE_PATH ABSOLUTE_PATH)
+                          RELATIVE_PATH ABSOLUTE_PATH)
   if (command STREQUAL "REPLACE_FILENAME" OR command STREQUAL "REPLACE_EXTENSION")
     set (extra_args input)
   else()
@@ -148,7 +143,7 @@
   run_cmake_command (${command}-unexpected-arg "${CMAKE_COMMAND}" "-DCMAKE_PATH_ARGUMENTS=${command} path ${extra_args} unexpected" -P "${RunCMake_SOURCE_DIR}/call-cmake_path.cmake")
 endforeach()
 
-foreach (command IN ITEMS CMAKE_PATH NATIVE_PATH
+foreach (command IN ITEMS SET NATIVE_PATH
                           HAS_ROOT_NAME HAS_ROOT_DIRECTORY HAS_ROOT_PATH
                           HAS_FILENAME HAS_EXTENSION HAS_STEM
                           HAS_RELATIVE_PATH HAS_PARENT_PATH
@@ -170,17 +165,16 @@
 set (RunCMake_TEST_OPTIONS "-DRunCMake_SOURCE_DIR=${RunCMake_SOURCE_DIR}")
 
 run_cmake(GET)
+run_cmake(SET)
 run_cmake(APPEND)
-run_cmake(CONCAT)
+run_cmake(APPEND_STRING)
 run_cmake(REMOVE_FILENAME)
 run_cmake(REPLACE_FILENAME)
 run_cmake(REMOVE_EXTENSION)
 run_cmake(REPLACE_EXTENSION)
 run_cmake(NORMAL_PATH)
 run_cmake(RELATIVE_PATH)
-run_cmake(PROXIMATE_PATH)
 run_cmake(ABSOLUTE_PATH)
-run_cmake(CMAKE_PATH)
 run_cmake(NATIVE_PATH)
 run_cmake(CONVERT)
 run_cmake(COMPARE)
diff --git a/Tests/RunCMake/cmake_path/CMAKE_PATH-missing-output-result.txt b/Tests/RunCMake/cmake_path/SET-missing-output-result.txt
similarity index 100%
rename from Tests/RunCMake/cmake_path/CMAKE_PATH-missing-output-result.txt
rename to Tests/RunCMake/cmake_path/SET-missing-output-result.txt
diff --git a/Tests/RunCMake/cmake_path/CMAKE_PATH-unexpected-arg-result.txt b/Tests/RunCMake/cmake_path/SET-unexpected-arg-result.txt
similarity index 100%
rename from Tests/RunCMake/cmake_path/CMAKE_PATH-unexpected-arg-result.txt
rename to Tests/RunCMake/cmake_path/SET-unexpected-arg-result.txt
diff --git a/Tests/RunCMake/cmake_path/CMAKE_PATH.cmake b/Tests/RunCMake/cmake_path/SET.cmake
similarity index 65%
rename from Tests/RunCMake/cmake_path/CMAKE_PATH.cmake
rename to Tests/RunCMake/cmake_path/SET.cmake
index b9320f3..445783e 100644
--- a/Tests/RunCMake/cmake_path/CMAKE_PATH.cmake
+++ b/Tests/RunCMake/cmake_path/SET.cmake
@@ -2,42 +2,42 @@
 include ("${RunCMake_SOURCE_DIR}/check_errors.cmake")
 unset (errors)
 
-cmake_path(CMAKE_PATH path "/x/y/z/../../a/d")
+cmake_path(SET path "/x/y/z/../../a/d")
 if (NOT path STREQUAL "/x/y/z/../../a/d")
   list (APPEND errors "'${path}' instead of '/x/y/z/../../a/d'")
 endif()
-cmake_path(CMAKE_PATH path NORMALIZE "/x/y/z/../../a/d")
+cmake_path(SET path NORMALIZE "/x/y/z/../../a/d")
 if (NOT path STREQUAL "/x/a/d")
   list (APPEND errors "'${path}' instead of '/x/a/d'")
 endif()
 
 if (WIN32)
-  cmake_path(CMAKE_PATH path "/x\\y/z\\..\\../a/d")
+  cmake_path(SET path "/x\\y/z\\..\\../a/d")
   if (NOT path STREQUAL "/x/y/z/../../a/d")
     list (APPEND errors "'${path}' instead of '/x/y/z/../../a/d'")
   endif()
-  cmake_path(CMAKE_PATH path NORMALIZE "/x\\y/z\\..\\../a/d")
+  cmake_path(SET path NORMALIZE "/x\\y/z\\..\\../a/d")
   if (NOT path STREQUAL "/x/a/d")
     list (APPEND errors "'${path}' instead of '/x/a/d'")
   endif()
 
-  cmake_path(CMAKE_PATH path "//?/c:/x\\y/z\\..\\../a/d")
+  cmake_path(SET path "//?/c:/x\\y/z\\..\\../a/d")
   if (NOT path STREQUAL "c:/x/y/z/../../a/d")
     list (APPEND errors "'${path}' instead of 'c:/x/y/z/../../a/d'")
   endif()
-  cmake_path(CMAKE_PATH path NORMALIZE "//?/c:/x\\y/z\\..\\../a/d")
+  cmake_path(SET path NORMALIZE "//?/c:/x\\y/z\\..\\../a/d")
   if (NOT path STREQUAL "c:/x/a/d")
     list (APPEND errors "'${path}' instead of 'c:/x/a/d'")
   endif()
 
-  cmake_path(CMAKE_PATH path "\\\\?\\UNC/host/x\\y/z\\..\\../a/d")
+  cmake_path(SET path "\\\\?\\UNC/host/x\\y/z\\..\\../a/d")
   if (NOT path STREQUAL "//host/x/y/z/../../a/d")
     list (APPEND errors "'${path}' instead of '//host/x/y/z/../../a/d'")
   endif()
-  cmake_path(CMAKE_PATH path NORMALIZE "\\\\?\\UNC\\host/x\\y/z\\..\\../a/d")
+  cmake_path(SET path NORMALIZE "\\\\?\\UNC\\host/x\\y/z\\..\\../a/d")
   if (NOT path STREQUAL "//host/x/a/d")
     list (APPEND errors "'${path}' instead of '//host/x/a/d'")
   endif()
 endif()
 
-check_errors (CMAKE_PATH ${errors})
+check_errors (SET ${errors})
diff --git a/Tests/RunCMake/configure_file/RunCMakeTest.cmake b/Tests/RunCMake/configure_file/RunCMakeTest.cmake
index 71694fb..0a2e3f9 100644
--- a/Tests/RunCMake/configure_file/RunCMakeTest.cmake
+++ b/Tests/RunCMake/configure_file/RunCMakeTest.cmake
@@ -16,6 +16,13 @@
 run_cmake(NewLineStyle-ValidArg)
 run_cmake(NewLineStyle-COPYONLY)
 run_cmake(NoSourcePermissions)
+run_cmake(SourcePermissionsInvalidArg-1)
+run_cmake(SourcePermissionsInvalidArg-2)
+run_cmake(SourcePermissionsInvalidArg-3)
+run_cmake(SourcePermissionsInvalidArg-4)
+run_cmake(SourcePermissionsInvalidArg-5)
+run_cmake(UseSourcePermissions)
+run_cmake(SourcePermissions)
 
 if(RunCMake_GENERATOR MATCHES "Make")
   # Use a single build tree for a few tests without cleaning.
diff --git a/Tests/RunCMake/configure_file/SourcePermissions-result.txt b/Tests/RunCMake/configure_file/SourcePermissions-result.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/configure_file/SourcePermissions-result.txt
diff --git a/Tests/RunCMake/configure_file/SourcePermissions-stderr.txt b/Tests/RunCMake/configure_file/SourcePermissions-stderr.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/configure_file/SourcePermissions-stderr.txt
diff --git a/Tests/RunCMake/configure_file/SourcePermissions.cmake b/Tests/RunCMake/configure_file/SourcePermissions.cmake
new file mode 100644
index 0000000..50330fc
--- /dev/null
+++ b/Tests/RunCMake/configure_file/SourcePermissions.cmake
@@ -0,0 +1,34 @@
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/sourcefile.txt
+    ${CMAKE_CURRENT_BINARY_DIR}/sourcefile-source-permissions.txt
+    FILE_PERMISSIONS
+        OWNER_READ OWNER_EXECUTE
+        GROUP_READ GROUP_EXECUTE
+        WORLD_READ
+)
+
+if (UNIX)
+  find_program(STAT_EXECUTABLE NAMES stat)
+  if(NOT STAT_EXECUTABLE)
+    return()
+  endif()
+
+  if (CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
+    execute_process(COMMAND "${STAT_EXECUTABLE}" -f %Lp "${CMAKE_CURRENT_BINARY_DIR}/sourcefile-source-permissions.txt"
+      OUTPUT_VARIABLE output
+    )
+  elseif(CMAKE_SYSTEM_NAME MATCHES "Darwin")
+    execute_process(COMMAND "${STAT_EXECUTABLE}" -f %A "${CMAKE_CURRENT_BINARY_DIR}/sourcefile-source-permissions.txt"
+      OUTPUT_VARIABLE output
+    )
+  else()
+    execute_process(COMMAND "${STAT_EXECUTABLE}" -c %a "${CMAKE_CURRENT_BINARY_DIR}/sourcefile-source-permissions.txt"
+      OUTPUT_VARIABLE output
+    )
+  endif()
+
+  if (NOT output EQUAL "554")
+    message(FATAL_ERROR "configure file has different permissions than "
+        "desired, generated permissions: ${output}")
+  endif()
+
+endif()
diff --git a/Tests/RunCMake/CommandLine/E_server-arg-result.txt b/Tests/RunCMake/configure_file/SourcePermissionsInvalidArg-1-result.txt
similarity index 100%
copy from Tests/RunCMake/CommandLine/E_server-arg-result.txt
copy to Tests/RunCMake/configure_file/SourcePermissionsInvalidArg-1-result.txt
diff --git a/Tests/RunCMake/configure_file/SourcePermissionsInvalidArg-1-stderr.txt b/Tests/RunCMake/configure_file/SourcePermissionsInvalidArg-1-stderr.txt
new file mode 100644
index 0000000..d483d34
--- /dev/null
+++ b/Tests/RunCMake/configure_file/SourcePermissionsInvalidArg-1-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at SourcePermissionsInvalidArg-1.cmake:1 \(configure_file\):
+  configure_file given both USE_SOURCE_PERMISSIONS and NO_SOURCE_PERMISSIONS.
+  Only one option allowed.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/configure_file/SourcePermissionsInvalidArg-1.cmake b/Tests/RunCMake/configure_file/SourcePermissionsInvalidArg-1.cmake
new file mode 100644
index 0000000..4969880
--- /dev/null
+++ b/Tests/RunCMake/configure_file/SourcePermissionsInvalidArg-1.cmake
@@ -0,0 +1,5 @@
+configure_file(sourcefile.txt
+    ${CMAKE_CURRENT_BINARY_DIR}/sourcefile.txt
+    NO_SOURCE_PERMISSIONS
+    USE_SOURCE_PERMISSIONS
+)
diff --git a/Tests/RunCMake/CommandLine/E_server-arg-result.txt b/Tests/RunCMake/configure_file/SourcePermissionsInvalidArg-2-result.txt
similarity index 100%
copy from Tests/RunCMake/CommandLine/E_server-arg-result.txt
copy to Tests/RunCMake/configure_file/SourcePermissionsInvalidArg-2-result.txt
diff --git a/Tests/RunCMake/configure_file/SourcePermissionsInvalidArg-2-stderr.txt b/Tests/RunCMake/configure_file/SourcePermissionsInvalidArg-2-stderr.txt
new file mode 100644
index 0000000..2fcfe58
--- /dev/null
+++ b/Tests/RunCMake/configure_file/SourcePermissionsInvalidArg-2-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at SourcePermissionsInvalidArg-2.cmake:1 \(configure_file\):
+  configure_file given both FILE_PERMISSIONS and NO_SOURCE_PERMISSIONS.  Only
+  one option allowed.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/configure_file/SourcePermissionsInvalidArg-2.cmake b/Tests/RunCMake/configure_file/SourcePermissionsInvalidArg-2.cmake
new file mode 100644
index 0000000..8a3fb87
--- /dev/null
+++ b/Tests/RunCMake/configure_file/SourcePermissionsInvalidArg-2.cmake
@@ -0,0 +1,5 @@
+configure_file(sourcefile.txt
+    ${CMAKE_CURRENT_BINARY_DIR}/sourcefile.txt
+    NO_SOURCE_PERMISSIONS
+    FILE_PERMISSIONS OWNER_READ
+)
diff --git a/Tests/RunCMake/CommandLine/E_server-arg-result.txt b/Tests/RunCMake/configure_file/SourcePermissionsInvalidArg-3-result.txt
similarity index 100%
copy from Tests/RunCMake/CommandLine/E_server-arg-result.txt
copy to Tests/RunCMake/configure_file/SourcePermissionsInvalidArg-3-result.txt
diff --git a/Tests/RunCMake/configure_file/SourcePermissionsInvalidArg-3-stderr.txt b/Tests/RunCMake/configure_file/SourcePermissionsInvalidArg-3-stderr.txt
new file mode 100644
index 0000000..29fae1b
--- /dev/null
+++ b/Tests/RunCMake/configure_file/SourcePermissionsInvalidArg-3-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at SourcePermissionsInvalidArg-3.cmake:1 \(configure_file\):
+  configure_file given both FILE_PERMISSIONS and USE_SOURCE_PERMISSIONS.
+  Only one option allowed.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/configure_file/SourcePermissionsInvalidArg-3.cmake b/Tests/RunCMake/configure_file/SourcePermissionsInvalidArg-3.cmake
new file mode 100644
index 0000000..78ecb0f
--- /dev/null
+++ b/Tests/RunCMake/configure_file/SourcePermissionsInvalidArg-3.cmake
@@ -0,0 +1,5 @@
+configure_file(sourcefile.txt
+    ${CMAKE_CURRENT_BINARY_DIR}/sourcefile.txt
+    USE_SOURCE_PERMISSIONS
+    FILE_PERMISSIONS OWNER_READ
+)
diff --git a/Tests/RunCMake/CommandLine/E_server-arg-result.txt b/Tests/RunCMake/configure_file/SourcePermissionsInvalidArg-4-result.txt
similarity index 100%
copy from Tests/RunCMake/CommandLine/E_server-arg-result.txt
copy to Tests/RunCMake/configure_file/SourcePermissionsInvalidArg-4-result.txt
diff --git a/Tests/RunCMake/configure_file/SourcePermissionsInvalidArg-4-stderr.txt b/Tests/RunCMake/configure_file/SourcePermissionsInvalidArg-4-stderr.txt
new file mode 100644
index 0000000..7d477cb
--- /dev/null
+++ b/Tests/RunCMake/configure_file/SourcePermissionsInvalidArg-4-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at SourcePermissionsInvalidArg-4.cmake:1 \(configure_file\):
+  configure_file given FILE_PERMISSIONS without any options.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/configure_file/SourcePermissionsInvalidArg-4.cmake b/Tests/RunCMake/configure_file/SourcePermissionsInvalidArg-4.cmake
new file mode 100644
index 0000000..308b455
--- /dev/null
+++ b/Tests/RunCMake/configure_file/SourcePermissionsInvalidArg-4.cmake
@@ -0,0 +1,4 @@
+configure_file(sourcefile.txt
+    ${CMAKE_CURRENT_BINARY_DIR}/sourcefile.txt
+    FILE_PERMISSIONS
+)
diff --git a/Tests/RunCMake/CommandLine/E_server-arg-result.txt b/Tests/RunCMake/configure_file/SourcePermissionsInvalidArg-5-result.txt
similarity index 100%
copy from Tests/RunCMake/CommandLine/E_server-arg-result.txt
copy to Tests/RunCMake/configure_file/SourcePermissionsInvalidArg-5-result.txt
diff --git a/Tests/RunCMake/configure_file/SourcePermissionsInvalidArg-5-stderr.txt b/Tests/RunCMake/configure_file/SourcePermissionsInvalidArg-5-stderr.txt
new file mode 100644
index 0000000..7cab120
--- /dev/null
+++ b/Tests/RunCMake/configure_file/SourcePermissionsInvalidArg-5-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at SourcePermissionsInvalidArg-5.cmake:1 \(configure_file\):
+  configure_file given invalid permission "OWNER_RX","GROUP_RWX".
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/configure_file/SourcePermissionsInvalidArg-5.cmake b/Tests/RunCMake/configure_file/SourcePermissionsInvalidArg-5.cmake
new file mode 100644
index 0000000..15c6f9a
--- /dev/null
+++ b/Tests/RunCMake/configure_file/SourcePermissionsInvalidArg-5.cmake
@@ -0,0 +1,6 @@
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/sourcefile.txt
+    ${CMAKE_CURRENT_BINARY_DIR}/sourcefile-source-permissions.txt
+    FILE_PERMISSIONS
+        OWNER_READ OWNER_RX
+        GROUP_RWX
+)
diff --git a/Tests/RunCMake/configure_file/UseSourcePermissions.cmake b/Tests/RunCMake/configure_file/UseSourcePermissions.cmake
new file mode 100644
index 0000000..f7aedd1
--- /dev/null
+++ b/Tests/RunCMake/configure_file/UseSourcePermissions.cmake
@@ -0,0 +1,40 @@
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/sourcefile.txt
+    ${CMAKE_CURRENT_BINARY_DIR}/sourcefile-use-source-permissions.txt
+    USE_SOURCE_PERMISSIONS
+)
+
+if (UNIX)
+  find_program(STAT_EXECUTABLE NAMES stat)
+  if(NOT STAT_EXECUTABLE)
+    return()
+  endif()
+
+  if (CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
+    execute_process(COMMAND "${STAT_EXECUTABLE}" -f %Lp "${CMAKE_CURRENT_SOURCE_DIR}/sourcefile.txt"
+      OUTPUT_VARIABLE output1
+    )
+    execute_process(COMMAND "${STAT_EXECUTABLE}" -f %Lp "${CMAKE_CURRENT_BINARY_DIR}/sourcefile-use-source-permissions.txt"
+      OUTPUT_VARIABLE output2
+    )
+  elseif (CMAKE_SYSTEM_NAME MATCHES "Darwin")
+    execute_process(COMMAND "${STAT_EXECUTABLE}" -f %A "${CMAKE_CURRENT_SOURCE_DIR}/sourcefile.txt"
+      OUTPUT_VARIABLE output1
+    )
+    execute_process(COMMAND "${STAT_EXECUTABLE}" -f %A "${CMAKE_CURRENT_BINARY_DIR}/sourcefile-use-source-permissions.txt"
+      OUTPUT_VARIABLE output2
+    )
+  else()
+    execute_process(COMMAND "${STAT_EXECUTABLE}" -c %a "${CMAKE_CURRENT_SOURCE_DIR}/sourcefile.txt"
+      OUTPUT_VARIABLE output1
+    )
+    execute_process(COMMAND "${STAT_EXECUTABLE}" -c %a "${CMAKE_CURRENT_BINARY_DIR}/sourcefile-use-source-permissions.txt"
+      OUTPUT_VARIABLE output2
+    )
+  endif()
+
+  if (NOT output1 EQUAL output2)
+    message(FATAL_ERROR "configure file has different permissions source "
+        "permissions: ${output1} generated permissions: ${output2}")
+  endif()
+
+endif()
diff --git a/Tests/RunCMake/configure_file/sourcefile.txt b/Tests/RunCMake/configure_file/sourcefile.txt
new file mode 100644
index 0000000..2296808
--- /dev/null
+++ b/Tests/RunCMake/configure_file/sourcefile.txt
@@ -0,0 +1 @@
+an empty file
diff --git a/Tests/RunCMake/if/duplicate-deep-else-stderr.txt b/Tests/RunCMake/if/duplicate-deep-else-stderr.txt
index ac2335c..ee886e0 100644
--- a/Tests/RunCMake/if/duplicate-deep-else-stderr.txt
+++ b/Tests/RunCMake/if/duplicate-deep-else-stderr.txt
@@ -1,4 +1,4 @@
-CMake Error at duplicate-deep-else.cmake:[0-9]+ \(else\):
-  A duplicate ELSE command was found inside an IF block.
+CMake Error at duplicate-deep-else\.cmake:[0-9]+ \(else\):
+  Flow control statements are not properly nested\.
 Call Stack \(most recent call first\):
-  CMakeLists.txt:3 \(include\)
+  CMakeLists\.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/if/duplicate-else-after-elseif-stderr.txt b/Tests/RunCMake/if/duplicate-else-after-elseif-stderr.txt
index ba6765c..60c8484 100644
--- a/Tests/RunCMake/if/duplicate-else-after-elseif-stderr.txt
+++ b/Tests/RunCMake/if/duplicate-else-after-elseif-stderr.txt
@@ -1,4 +1,4 @@
-CMake Error at duplicate-else-after-elseif.cmake:[0-9]+ \(else\):
-  A duplicate ELSE command was found inside an IF block.
+CMake Error at duplicate-else-after-elseif\.cmake:[0-9]+ \(else\):
+  Flow control statements are not properly nested\.
 Call Stack \(most recent call first\):
-  CMakeLists.txt:3 \(include\)
+  CMakeLists\.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/if/duplicate-else-stderr.txt b/Tests/RunCMake/if/duplicate-else-stderr.txt
index e0dd01f..518c43f 100644
--- a/Tests/RunCMake/if/duplicate-else-stderr.txt
+++ b/Tests/RunCMake/if/duplicate-else-stderr.txt
@@ -1,4 +1,4 @@
-CMake Error at duplicate-else.cmake:[0-9]+ \(else\):
-  A duplicate ELSE command was found inside an IF block.
+CMake Error at duplicate-else\.cmake:[0-9]+ \(else\):
+  Flow control statements are not properly nested\.
 Call Stack \(most recent call first\):
-  CMakeLists.txt:3 \(include\)
+  CMakeLists\.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/if/misplaced-elseif-stderr.txt b/Tests/RunCMake/if/misplaced-elseif-stderr.txt
index c4b0266..5138f11 100644
--- a/Tests/RunCMake/if/misplaced-elseif-stderr.txt
+++ b/Tests/RunCMake/if/misplaced-elseif-stderr.txt
@@ -1,4 +1,4 @@
-CMake Error at misplaced-elseif.cmake:[0-9]+ \(elseif\):
-  An ELSEIF command was found after an ELSE command.
+CMake Error at misplaced-elseif\.cmake:[0-9]+ \(elseif\):
+  Flow control statements are not properly nested\.
 Call Stack \(most recent call first\):
-  CMakeLists.txt:3 \(include\)
+  CMakeLists\.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/include/ExportExportInclude-stderr.txt b/Tests/RunCMake/include/ExportExportInclude-stderr.txt
index 70d013c..6d5c02f 100644
--- a/Tests/RunCMake/include/ExportExportInclude-stderr.txt
+++ b/Tests/RunCMake/include/ExportExportInclude-stderr.txt
@@ -1,5 +1,5 @@
 CMake Error at ExportExportInclude.cmake:6 \(include\):
-  include could not find load file:
+  include could not find requested file:
 
     .*/Tests/RunCMake/include/ExportExportInclude-build/theTargets.cmake
 Call Stack \(most recent call first\):
diff --git a/Tests/RunCMake/CommandLine/E_server-arg-result.txt b/Tests/RunCMake/include/IncludeIsDirectory-result.txt
similarity index 100%
copy from Tests/RunCMake/CommandLine/E_server-arg-result.txt
copy to Tests/RunCMake/include/IncludeIsDirectory-result.txt
diff --git a/Tests/RunCMake/include/IncludeIsDirectory-stderr.txt b/Tests/RunCMake/include/IncludeIsDirectory-stderr.txt
new file mode 100644
index 0000000..5735c29
--- /dev/null
+++ b/Tests/RunCMake/include/IncludeIsDirectory-stderr.txt
@@ -0,0 +1,6 @@
+CMake Error at IncludeIsDirectory.cmake:1 \(include\):
+  include requested file is a directory:
+
+    .*/Tests/RunCMake/include/IncludeIsDirectory-build
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/include/IncludeIsDirectory.cmake b/Tests/RunCMake/include/IncludeIsDirectory.cmake
new file mode 100644
index 0000000..74189e3
--- /dev/null
+++ b/Tests/RunCMake/include/IncludeIsDirectory.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_BINARY_DIR}")
diff --git a/Tests/RunCMake/CommandLine/E_server-arg-result.txt b/Tests/RunCMake/include/IncludeMalformed-result.txt
similarity index 100%
copy from Tests/RunCMake/CommandLine/E_server-arg-result.txt
copy to Tests/RunCMake/include/IncludeMalformed-result.txt
diff --git a/Tests/RunCMake/include/IncludeMalformed-stderr.txt b/Tests/RunCMake/include/IncludeMalformed-stderr.txt
new file mode 100644
index 0000000..fc75549
--- /dev/null
+++ b/Tests/RunCMake/include/IncludeMalformed-stderr.txt
@@ -0,0 +1,13 @@
+CMake Error at malformedInclude.cmake:1:
+  Parse error.  Function missing ending "\)".  End of file reached.
+Call Stack \(most recent call first\):
+  IncludeMalformed.cmake:1 \(include\)
+  CMakeLists.txt:3 \(include\)
+
+
+CMake Error at IncludeMalformed.cmake:1 \(include\):
+  include could not load requested file:
+
+    malformedInclude.cmake
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/include/IncludeMalformed.cmake b/Tests/RunCMake/include/IncludeMalformed.cmake
new file mode 100644
index 0000000..9560142
--- /dev/null
+++ b/Tests/RunCMake/include/IncludeMalformed.cmake
@@ -0,0 +1 @@
+include("malformedInclude.cmake")
diff --git a/Tests/RunCMake/include/RunCMakeTest.cmake b/Tests/RunCMake/include/RunCMakeTest.cmake
index bea7d5c..8fb7201 100644
--- a/Tests/RunCMake/include/RunCMakeTest.cmake
+++ b/Tests/RunCMake/include/RunCMakeTest.cmake
@@ -5,3 +5,5 @@
 run_cmake(CMP0024-WARN)
 run_cmake(CMP0024-NEW)
 run_cmake(ExportExportInclude)
+run_cmake(IncludeIsDirectory)
+run_cmake(IncludeMalformed)
diff --git a/Tests/RunCMake/include/malformedInclude.cmake b/Tests/RunCMake/include/malformedInclude.cmake
new file mode 100644
index 0000000..3cec3ad
--- /dev/null
+++ b/Tests/RunCMake/include/malformedInclude.cmake
@@ -0,0 +1 @@
+if(
diff --git a/Tests/RunCMake/pseudo_llvm-rc.c b/Tests/RunCMake/pseudo_llvm-rc.c
new file mode 100644
index 0000000..7acb2a3
--- /dev/null
+++ b/Tests/RunCMake/pseudo_llvm-rc.c
@@ -0,0 +1,30 @@
+#include <stdio.h>
+#include <string.h>
+
+int main(int argc, char* argv[])
+{
+  FILE* source;
+  FILE* target;
+  int i;
+  for (i = 1; i < argc; ++i) {
+    if (strcmp(argv[i], "-bad") == 0) {
+      fprintf(stdout, "stdout from bad command line arg '-bad'\n");
+      fprintf(stderr, "stderr from bad command line arg '-bad'\n");
+      return 1;
+    }
+  }
+  source = fopen(argv[argc - 1], "rb");
+  if (source == NULL) {
+    return 1;
+  }
+  target = fopen(argv[argc - 2], "wb");
+  if (target != NULL) {
+    char buffer[500];
+    size_t n = fread(buffer, 1, sizeof(buffer), source);
+    fwrite(buffer, 1, n, target);
+    fclose(source);
+    fclose(target);
+    return 0;
+  }
+  return 1;
+}
diff --git a/Tests/RunCMake/separate_arguments/ProgramCommand.cmake b/Tests/RunCMake/separate_arguments/ProgramCommand.cmake
index 8325def..bdf5810 100644
--- a/Tests/RunCMake/separate_arguments/ProgramCommand.cmake
+++ b/Tests/RunCMake/separate_arguments/ProgramCommand.cmake
@@ -7,7 +7,7 @@
 set (TEST_EXE_DIR "${CMAKE_CURRENT_BINARY_DIR}/TestExe")
 file(MAKE_DIRECTORY "${TEST_EXE_DIR}")
 file(COPY "${CMAKE_COMMAND}" DESTINATION "${TEST_EXE_DIR}")
-get_filename_component (cmake_exe "${CMAKE_COMMAND}" NAME)
+cmake_path (GET CMAKE_COMMAND FILENAME cmake_exe)
 
 set (ENV{PATH} "${TEST_EXE_DIR}")
 
diff --git a/Tests/RunCMake/separate_arguments/ProgramCommandWithSeparateArgs.cmake b/Tests/RunCMake/separate_arguments/ProgramCommandWithSeparateArgs.cmake
index 07572ba..2826cc9 100644
--- a/Tests/RunCMake/separate_arguments/ProgramCommandWithSeparateArgs.cmake
+++ b/Tests/RunCMake/separate_arguments/ProgramCommandWithSeparateArgs.cmake
@@ -7,7 +7,7 @@
 set (TEST_EXE_DIR "${CMAKE_CURRENT_BINARY_DIR}/TestExe")
 file(MAKE_DIRECTORY "${TEST_EXE_DIR}")
 file(COPY "${CMAKE_COMMAND}" DESTINATION "${TEST_EXE_DIR}")
-get_filename_component (cmake_exe "${CMAKE_COMMAND}" NAME)
+cmake_path (GET CMAKE_COMMAND FILENAME cmake_exe)
 
 set (ENV{PATH} "${TEST_EXE_DIR}")
 
diff --git a/Tests/RunCMake/while/EndAlone-stderr.txt b/Tests/RunCMake/while/EndAlone-stderr.txt
index 5fe6655..3195fa0 100644
--- a/Tests/RunCMake/while/EndAlone-stderr.txt
+++ b/Tests/RunCMake/while/EndAlone-stderr.txt
@@ -1,5 +1,4 @@
-^CMake Error at EndAlone.cmake:1 \(endwhile\):
-  endwhile An ENDWHILE command was found outside of a proper WHILE ENDWHILE
-  structure.  Or its arguments did not match the opening WHILE command.
+^CMake Error at EndAlone\.cmake:[0-9]+ \(endwhile\):
+  Flow control statements are not properly nested\.
 Call Stack \(most recent call first\):
-  CMakeLists.txt:3 \(include\)$
+  CMakeLists\.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/while/EndAloneArgs-stderr.txt b/Tests/RunCMake/while/EndAloneArgs-stderr.txt
index a8c043d..1634e3b 100644
--- a/Tests/RunCMake/while/EndAloneArgs-stderr.txt
+++ b/Tests/RunCMake/while/EndAloneArgs-stderr.txt
@@ -1,5 +1,4 @@
-^CMake Error at EndAloneArgs.cmake:1 \(endwhile\):
-  endwhile An ENDWHILE command was found outside of a proper WHILE ENDWHILE
-  structure.  Or its arguments did not match the opening WHILE command.
+^CMake Error at EndAloneArgs\.cmake:[0-9]+ \(endwhile\):
+  Flow control statements are not properly nested\.
 Call Stack \(most recent call first\):
-  CMakeLists.txt:3 \(include\)$
+  CMakeLists\.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/while/EndMissing-stderr.txt b/Tests/RunCMake/while/EndMissing-stderr.txt
index 964792f..1e3be4d 100644
--- a/Tests/RunCMake/while/EndMissing-stderr.txt
+++ b/Tests/RunCMake/while/EndMissing-stderr.txt
@@ -1,8 +1,4 @@
-^CMake Error in EndMissing.cmake:
-  A logical block opening on the line
-
-    .*/Tests/RunCMake/while/EndMissing.cmake:1 \(while\)
-
-  is not closed.
+^CMake Error at EndMissing\.cmake:[0-9]+ \(while\):
+  Flow control statements are not properly nested\.
 Call Stack \(most recent call first\):
-  CMakeLists.txt:[0-9]+ \(include\)$
+  CMakeLists\.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/while/MissingArgument-stderr.txt b/Tests/RunCMake/while/MissingArgument-stderr.txt
index 7ff0971..59e8ee3 100644
--- a/Tests/RunCMake/while/MissingArgument-stderr.txt
+++ b/Tests/RunCMake/while/MissingArgument-stderr.txt
@@ -1,4 +1,11 @@
-^CMake Error at MissingArgument.cmake:1 \(while\):
+^CMake Error at MissingArgument\.cmake:[0-9]+ \(while\):
   while called with incorrect number of arguments
 Call Stack \(most recent call first\):
-  CMakeLists.txt:3 \(include\)$
+  CMakeLists\.txt:[0-9]+ \(include\)
+
+
+CMake Error at MissingArgument\.cmake:[0-9]+ \(endwhile\):
+  endwhile An ENDWHILE command was found outside of a proper WHILE ENDWHILE
+  structure\.  Or its arguments did not match the opening WHILE command\.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/while/MissingArgument.cmake b/Tests/RunCMake/while/MissingArgument.cmake
index 32eaa26..3fe2d97 100644
--- a/Tests/RunCMake/while/MissingArgument.cmake
+++ b/Tests/RunCMake/while/MissingArgument.cmake
@@ -1 +1,2 @@
 while()
+endwhile()
diff --git a/Tests/Server/CMakeLists.txt b/Tests/Server/CMakeLists.txt
deleted file mode 100644
index 8321edb..0000000
--- a/Tests/Server/CMakeLists.txt
+++ /dev/null
@@ -1,28 +0,0 @@
-cmake_minimum_required(VERSION 3.4)
-project(Server CXX)
-
-find_package(Python REQUIRED)
-
-macro(do_test bsname file type)
-  execute_process(COMMAND ${Python_EXECUTABLE}
-    -B # no .pyc files
-    "${CMAKE_SOURCE_DIR}/${type}-test.py"
-    "${CMAKE_COMMAND}"
-    "${CMAKE_SOURCE_DIR}/${file}"
-    "${CMAKE_SOURCE_DIR}"
-    "${CMAKE_BINARY_DIR}"
-    "${CMAKE_GENERATOR}"
-    RESULT_VARIABLE test_result
-    )
-
-  if (NOT test_result EQUAL 0)
-    message(SEND_ERROR "TEST FAILED: ${test_result}")
-  endif()
-endmacro()
-
-do_test("test_cache" "tc_cache.json" "server")
-do_test("test_handshake" "tc_handshake.json" "server")
-do_test("test_globalSettings" "tc_globalSettings.json" "server")
-do_test("test_buildsystem1" "tc_buildsystem1.json" "server")
-
-add_executable(Server empty.cpp)
diff --git a/Tests/Server/buildsystem1/CMakeLists.txt b/Tests/Server/buildsystem1/CMakeLists.txt
deleted file mode 100644
index d690472..0000000
--- a/Tests/Server/buildsystem1/CMakeLists.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-cmake_minimum_required(VERSION 3.4)
-
-project(buildsystem2)
-
-set(var1 123)
-
-set(var2 345)
-
-add_executable(main main.cpp)
-
-add_executable(m_other main.cpp)
-
-add_library(foo foo.cpp)
-
-function(f1)
-endfunction()
-
-set(var3 345)
-
-add_library(someImportedLib UNKNOWN IMPORTED)
-
-add_subdirectory(subdir)
diff --git a/Tests/Server/buildsystem1/foo.cpp b/Tests/Server/buildsystem1/foo.cpp
deleted file mode 100644
index 7f39d71..0000000
--- a/Tests/Server/buildsystem1/foo.cpp
+++ /dev/null
@@ -1,5 +0,0 @@
-
-int foo()
-{
-  return 0;
-}
diff --git a/Tests/Server/buildsystem1/subdir/CMakeLists.txt b/Tests/Server/buildsystem1/subdir/CMakeLists.txt
deleted file mode 100644
index 9157312..0000000
--- a/Tests/Server/buildsystem1/subdir/CMakeLists.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-set(bar4 something)
-
-set(bar5 more)
-
-add_executable(ooo empty.cpp)
diff --git a/Tests/Server/buildsystem1/subdir/empty.cpp b/Tests/Server/buildsystem1/subdir/empty.cpp
deleted file mode 100644
index 7f39d71..0000000
--- a/Tests/Server/buildsystem1/subdir/empty.cpp
+++ /dev/null
@@ -1,5 +0,0 @@
-
-int foo()
-{
-  return 0;
-}
diff --git a/Tests/Server/cmakelib.py b/Tests/Server/cmakelib.py
deleted file mode 100644
index 546ae4c..0000000
--- a/Tests/Server/cmakelib.py
+++ /dev/null
@@ -1,380 +0,0 @@
-from __future__ import print_function
-import sys, subprocess, json, os, select, shutil, time, socket
-
-termwidth = 150
-
-print_communication = True
-
-def ordered(obj):
-  if isinstance(obj, dict):
-    return sorted((k, ordered(v)) for k, v in obj.items())
-  if isinstance(obj, list):
-    return sorted(ordered(x) for x in obj)
-  else:
-    return obj
-
-def col_print(title, array):
-  print()
-  print()
-  print(title)
-
-  indentwidth = 4
-  indent = " " * indentwidth
-
-  if not array:
-    print(indent + "<None>")
-    return
-
-  padwidth = 2
-
-  maxitemwidth = len(max(array, key=len))
-
-  numCols = max(1, int((termwidth - indentwidth + padwidth) / (maxitemwidth + padwidth)))
-
-  numRows = len(array) // numCols + 1
-
-  pad = " " * padwidth
-
-  for index in range(numRows):
-    print(indent + pad.join(item.ljust(maxitemwidth) for item in array[index::numRows]))
-
-filterPacket = lambda x: x
-
-STDIN = 0
-PIPE = 1
-
-communicationMethods = [STDIN]
-
-if hasattr(socket, 'AF_UNIX'):
-  communicationMethods.append(PIPE)
-
-def defaultExitWithError(proc):
-  data = ""
-  try:
-    while select.select([proc.outPipe], [], [], 3.)[0]:
-      data = data + proc.outPipe.read(1)
-    if len(data):
-      print("Rest of raw buffer from server:")
-      printServer(data)
-  except:
-    pass
-  proc.outPipe.close()
-  proc.inPipe.close()
-  proc.kill()
-  sys.exit(1)
-
-exitWithError = lambda proc: defaultExitWithError(proc)
-
-serverTag = "SERVER"
-
-def printServer(*args):
-    print(serverTag + ">", *args)
-    print()
-    sys.stdout.flush()
-
-def printClient(*args):
-    print("CLIENT>", *args)
-    print()
-    sys.stdout.flush()
-
-def waitForRawMessage(cmakeCommand):
-  stdoutdata = ""
-  payload = ""
-  while not cmakeCommand.poll():
-    stdoutdataLine = cmakeCommand.outPipe.readline()
-    if stdoutdataLine:
-      stdoutdata += stdoutdataLine.decode('utf-8')
-    else:
-      break
-    begin = stdoutdata.find('[== "CMake Server" ==[\n')
-    end = stdoutdata.find(']== "CMake Server" ==]')
-
-    if begin != -1 and end != -1:
-      begin += len('[== "CMake Server" ==[\n')
-      payload = stdoutdata[begin:end]
-      jsonPayload = json.loads(payload)
-      filteredPayload = filterPacket(jsonPayload)
-      if print_communication and filteredPayload:
-        printServer(filteredPayload)
-      if filteredPayload is not None or jsonPayload is None:
-          return jsonPayload
-      stdoutdata = stdoutdata[(end+len(']== "CMake Server" ==]')):]
-
-# Python2 has no problem writing the output of encodes directly,
-# but Python3 returns only 'int's for encode and so must be turned
-# into bytes. We use the existence of 'to_bytes' on an int to
-# determine which behavior is appropriate. It might be more clear
-# to do this in the code which uses the flag, but introducing
-# this lookup cost at every byte sent isn't ideal.
-has_to_bytes = "to_bytes" in dir(10)
-
-def writeRawData(cmakeCommand, content):
-  writeRawData.counter += 1
-  payload = """
-[== "CMake Server" ==[
-%s
-]== "CMake Server" ==]
-""" % content
-
-  rn = ( writeRawData.counter % 2 ) == 0
-
-  if rn:
-    payload = payload.replace('\n', '\r\n')
-
-  if print_communication:
-    printClient(content, "(Use \\r\\n:", rn, ")")
-
-  # To stress test how cmake deals with fragmentation in the
-  # communication channel, we send only one byte at a time.
-  # Certain communication methods / platforms might still buffer
-  # it all into one message since its so close together, but in
-  # general this will catch places where we assume full buffers
-  # come in all at once.
-  encoded_payload = payload.encode('utf-8')
-
-  # Python version 3+ can't write ints directly; but 'to_bytes'
-  # for int was only added in python 3.2. If this is a 3+ version
-  # of python without that conversion function; just write the whole
-  # thing out at once.
-  if sys.version_info[0] > 2 and not has_to_bytes:
-    cmakeCommand.write(encoded_payload)
-  else:
-    for c in encoded_payload:
-      if has_to_bytes:
-        c = c.to_bytes(1, byteorder='big')
-      cmakeCommand.write(c)
-
-writeRawData.counter = 0
-
-def writePayload(cmakeCommand, obj):
-  writeRawData(cmakeCommand, json.dumps(obj))
-
-def getPipeName():
-  return "/tmp/server-test-socket"
-
-def attachPipe(cmakeCommand, pipeName):
-  time.sleep(1)
-  sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
-  sock.connect(pipeName)
-  global serverTag
-  serverTag = "SERVER(PIPE)"
-  cmakeCommand.outPipe = sock.makefile()
-  cmakeCommand.inPipe = sock
-  cmakeCommand.write = cmakeCommand.inPipe.sendall
-
-def writeAndFlush(pipe, val):
-  pipe.write(val)
-  pipe.flush()
-
-def initServerProc(cmakeCommand, comm):
-  if comm == PIPE:
-    pipeName = getPipeName()
-    cmakeCommand = subprocess.Popen([cmakeCommand, "-E", "server", "--experimental", "--pipe=" + pipeName])
-    attachPipe(cmakeCommand, pipeName)
-  else:
-    cmakeCommand = subprocess.Popen([cmakeCommand, "-E", "server", "--experimental", "--debug"],
-                                    stdin=subprocess.PIPE,
-                                    stdout=subprocess.PIPE)
-    cmakeCommand.outPipe = cmakeCommand.stdout
-    cmakeCommand.inPipe = cmakeCommand.stdin
-    cmakeCommand.write = lambda val: writeAndFlush(cmakeCommand.inPipe, val)
-
-  packet = waitForRawMessage(cmakeCommand)
-  if packet == None:
-    print("Not in server mode")
-    sys.exit(2)
-
-  if packet['type'] != 'hello':
-    print("No hello message")
-    sys.exit(3)
-
-  return cmakeCommand
-
-def exitProc(cmakeCommand):
-  # Tell the server to exit.
-  cmakeCommand.stdin.close()
-  cmakeCommand.stdout.close()
-
-  # Wait for the server to exit.
-  # If this version of python supports it, terminate the server after a timeout.
-  try:
-    cmakeCommand.wait(timeout=5)
-  except TypeError:
-    cmakeCommand.wait()
-  except:
-    cmakeCommand.terminate()
-    raise
-
-def waitForMessage(cmakeCommand, expected):
-  data = ordered(expected)
-  packet = ordered(waitForRawMessage(cmakeCommand))
-
-  if packet != data:
-    print ("Received unexpected message; test failed")
-    exitWithError(cmakeCommand)
-  return packet
-
-def waitForReply(cmakeCommand, originalType, cookie, skipProgress):
-  gotResult = False
-  while True:
-    packet = waitForRawMessage(cmakeCommand)
-    t = packet['type']
-    if packet['cookie'] != cookie or packet['inReplyTo'] != originalType:
-      print("cookie or inReplyTo mismatch")
-      sys.exit(4)
-    if t == 'message' or t == 'progress':
-      if skipProgress:
-        continue
-    if t == 'reply':
-        break
-    print("Unrecognized message", packet)
-    sys.exit(5)
-
-  return packet
-
-def waitForError(cmakeCommand, originalType, cookie, message):
-  packet = waitForRawMessage(cmakeCommand)
-  if packet['cookie'] != cookie or packet['type'] != 'error' or packet['inReplyTo'] != originalType or packet['errorMessage'] != message:
-    sys.exit(6)
-
-def waitForProgress(cmakeCommand, originalType, cookie, current, message):
-  packet = waitForRawMessage(cmakeCommand)
-  if packet['cookie'] != cookie or packet['type'] != 'progress' or packet['inReplyTo'] != originalType or packet['progressCurrent'] != current or packet['progressMessage'] != message:
-    sys.exit(7)
-
-def handshake(cmakeCommand, major, minor, source, build, generator, extraGenerator):
-  version = { 'major': major }
-  if minor >= 0:
-    version['minor'] = minor
-
-  writePayload(cmakeCommand, { 'type': 'handshake', 'protocolVersion': version,
-    'cookie': 'TEST_HANDSHAKE', 'sourceDirectory': source, 'buildDirectory': build,
-    'generator': generator, 'extraGenerator': extraGenerator })
-  waitForReply(cmakeCommand, 'handshake', 'TEST_HANDSHAKE', False)
-
-def validateGlobalSettings(cmakeCommand, cmakeCommandPath, data):
-  packet = waitForReply(cmakeCommand, 'globalSettings', '', False)
-
-  capabilities = packet['capabilities']
-
-  # validate version:
-  cmakeoutput = subprocess.check_output([ cmakeCommandPath, "--version" ], universal_newlines=True)
-  cmakeVersion = cmakeoutput.splitlines()[0][14:]
-
-  version = capabilities['version']
-  versionString = version['string']
-  vs = str(version['major']) + '.' + str(version['minor']) + '.' + str(version['patch'])
-  if (versionString != vs and not versionString.startswith(vs + '-')):
-    sys.exit(8)
-  if (versionString != cmakeVersion):
-    sys.exit(9)
-
-  # validate generators:
-  generatorObjects = capabilities['generators']
-
-  cmakeoutput = subprocess.check_output([ cmakeCommandPath, "--help" ], universal_newlines=True)
-  index = cmakeoutput.index('\nGenerators\n\n')
-  cmakeGenerators = []
-  for line in cmakeoutput[index + 12:].splitlines():
-    if not line:
-      continue
-    if line[0] == '*': # default generator marker
-      line = ' ' + line[1:]
-    if not line.startswith('  '):
-      continue
-    if line.startswith('    '):
-      continue
-    equalPos = line.find('=')
-    tmp = ''
-    if (equalPos > 0):
-      tmp = line[2:equalPos].strip()
-    else:
-      tmp = line.strip()
-    if tmp.endswith(" [arch]"):
-      tmp = tmp[0:len(tmp) - 7]
-    if (len(tmp) > 0) and (" - " not in tmp):
-      cmakeGenerators.append(tmp)
-
-  generators = []
-  for genObj in generatorObjects:
-    generators.append(genObj['name'])
-
-  generators.sort()
-  cmakeGenerators.sort()
-
-  for gen in cmakeGenerators:
-    if (not gen in generators):
-        sys.exit(10)
-
-  gen = packet['generator']
-  if (gen != '' and not (gen in generators)):
-    sys.exit(11)
-
-  for i in data:
-    print("Validating", i)
-    if (packet[i] != data[i]):
-      sys.exit(12)
-
-def validateCache(cmakeCommand, data):
-  packet = waitForReply(cmakeCommand, 'cache', '', False)
-
-  cache = packet['cache']
-
-  if (data['isEmpty']):
-    if (cache != []):
-      print('Expected empty cache, but got data.\n')
-      sys.exit(1)
-    return;
-
-  if (cache == []):
-    print('Expected cache contents, but got none.\n')
-    sys.exit(1)
-
-  hadHomeDir = False
-  for value in cache:
-    if (value['key'] == 'CMAKE_HOME_DIRECTORY'):
-      hadHomeDir = True
-
-  if (not hadHomeDir):
-    print('No CMAKE_HOME_DIRECTORY found in cache.')
-    sys.exit(1)
-
-def handleBasicMessage(proc, obj, debug):
-  if 'sendRaw' in obj:
-    data = obj['sendRaw']
-    if debug: print("Sending raw:", data)
-    writeRawData(proc, data)
-    return True
-  elif 'send' in obj:
-    data = obj['send']
-    if debug: print("Sending:", json.dumps(data))
-    writePayload(proc, data)
-    return True
-  elif 'recv' in obj:
-    data = obj['recv']
-    if debug: print("Waiting for:", json.dumps(data))
-    waitForMessage(proc, data)
-    return True
-  elif 'message' in obj:
-    print("MESSAGE:", obj["message"])
-    sys.stdout.flush()
-    return True
-  return False
-
-def shutdownProc(proc):
-  # Tell the server to exit.
-  proc.inPipe.close()
-  proc.outPipe.close()
-
-  # Wait for the server to exit.
-  # If this version of python supports it, terminate the server after a timeout.
-  try:
-    proc.wait(timeout=5)
-  except TypeError:
-    proc.wait()
-  except:
-    proc.terminate()
-    raise
-
-  print('cmake-server exited: %d' % proc.returncode)
-  sys.exit(proc.returncode)
diff --git a/Tests/Server/empty.cpp b/Tests/Server/empty.cpp
deleted file mode 100644
index 766b775..0000000
--- a/Tests/Server/empty.cpp
+++ /dev/null
@@ -1,5 +0,0 @@
-
-int main()
-{
-  return 0;
-}
diff --git a/Tests/Server/server-test.py b/Tests/Server/server-test.py
deleted file mode 100644
index 701c6e9..0000000
--- a/Tests/Server/server-test.py
+++ /dev/null
@@ -1,105 +0,0 @@
-from __future__ import print_function
-import sys, cmakelib, json, os, shutil
-
-debug = True
-
-cmakeCommand = sys.argv[1]
-testFile = sys.argv[2]
-sourceDir = sys.argv[3]
-buildDir = sys.argv[4] + "/" + os.path.splitext(os.path.basename(testFile))[0]
-cmakeGenerator = sys.argv[5]
-
-print("Server Test:", testFile,
-      "\n-- SourceDir:", sourceDir,
-      "\n-- BuildDir:", buildDir,
-      "\n-- Generator:", cmakeGenerator)
-
-if os.path.exists(buildDir):
-    shutil.rmtree(buildDir)
-
-cmakelib.filterBase = sourceDir
-
-with open(testFile) as f:
-    testData = json.loads(f.read())
-
-for communicationMethod in cmakelib.communicationMethods:
-    proc = cmakelib.initServerProc(cmakeCommand, communicationMethod)
-    if proc is None:
-        continue
-
-    for obj in testData:
-        if cmakelib.handleBasicMessage(proc, obj, debug):
-            pass
-        elif 'reply' in obj:
-            data = obj['reply']
-            if debug: print("Waiting for reply:", json.dumps(data))
-            originalType = ""
-            cookie = ""
-            skipProgress = False;
-            if 'cookie' in data: cookie = data['cookie']
-            if 'type' in data: originalType = data['type']
-            if 'skipProgress' in data: skipProgress = data['skipProgress']
-            cmakelib.waitForReply(proc, originalType, cookie, skipProgress)
-        elif 'error' in obj:
-            data = obj['error']
-            if debug: print("Waiting for error:", json.dumps(data))
-            originalType = ""
-            cookie = ""
-            message = ""
-            if 'cookie' in data: cookie = data['cookie']
-            if 'type' in data: originalType = data['type']
-            if 'message' in data: message = data['message']
-            cmakelib.waitForError(proc, originalType, cookie, message)
-        elif 'progress' in obj:
-            data = obj['progress']
-            if debug: print("Waiting for progress:", json.dumps(data))
-            originalType = ''
-            cookie = ""
-            current = 0
-            message = ""
-            if 'cookie' in data: cookie = data['cookie']
-            if 'type' in data: originalType = data['type']
-            if 'current' in data: current = data['current']
-            if 'message' in data: message = data['message']
-            cmakelib.waitForProgress(proc, originalType, cookie, current, message)
-        elif 'handshake' in obj:
-            data = obj['handshake']
-            if debug: print("Doing handshake:", json.dumps(data))
-            major = -1
-            minor = -1
-            generator = cmakeGenerator
-            extraGenerator = ''
-            sourceDirectory = sourceDir
-            buildDirectory = buildDir
-            if 'major' in data: major = data['major']
-            if 'minor' in data: minor = data['minor']
-            if 'buildDirectory' in data: buildDirectory = data['buildDirectory']
-            if 'sourceDirectory' in data: sourceDirectory = data['sourceDirectory']
-            if 'generator' in data: generator = data['generator']
-            if 'extraGenerator' in data: extraGenerator = data['extraGenerator']
-
-            if not os.path.isabs(buildDirectory):
-                buildDirectory = buildDir + "/" + buildDirectory
-            if sourceDirectory != '' and not os.path.isabs(sourceDirectory):
-                sourceDirectory = sourceDir + "/" + sourceDirectory
-            cmakelib.handshake(proc, major, minor, sourceDirectory, buildDirectory,
-                               generator, extraGenerator)
-        elif 'validateGlobalSettings' in obj:
-            data = obj['validateGlobalSettings']
-            if not 'buildDirectory' in data: data['buildDirectory'] = buildDir
-            if not 'sourceDirectory' in data: data['sourceDirectory'] = sourceDir
-            if not 'generator' in data: data['generator'] = cmakeGenerator
-            if not 'extraGenerator' in data: data['extraGenerator'] = ''
-            cmakelib.validateGlobalSettings(proc, cmakeCommand, data)
-        elif 'validateCache' in obj:
-            data = obj['validateCache']
-            if not 'isEmpty' in data: data['isEmpty'] = false
-            cmakelib.validateCache(proc, data)
-        elif 'reconnect' in obj:
-            cmakelib.exitProc(proc)
-            proc = cmakelib.initServerProc(cmakeCommand, communicationMethod)
-        else:
-            print("Unknown command:", json.dumps(obj))
-            sys.exit(2)
-    cmakelib.shutdownProc(proc)
-    print("Completed")
diff --git a/Tests/Server/tc_buildsystem1.json b/Tests/Server/tc_buildsystem1.json
deleted file mode 100644
index 08831b7..0000000
--- a/Tests/Server/tc_buildsystem1.json
+++ /dev/null
@@ -1,27 +0,0 @@
-[
-{ "message": "Testing globalSettings" },
-
-{ "handshake": {"major": 1, "sourceDirectory":"buildsystem1","buildDirectory":"buildsystem1"} },
-
-{ "message": "Configure:" },
-{ "send": { "type": "configure", "cookie":"CONFIG" } },
-{ "reply": { "type": "configure", "cookie":"CONFIG", "skipProgress":true } },
-
-{ "message": "Compute:" },
-{ "send": { "type": "compute", "cookie":"COMPUTE" } },
-{ "reply": { "type": "compute", "cookie":"COMPUTE", "skipProgress":true } },
-
-{ "message": "Codemodel:" },
-{ "send": { "type": "codemodel", "cookie":"CODEMODEL" } },
-{ "reply": { "type": "codemodel", "cookie":"CODEMODEL" } },
-
-{ "message": "CMake Inputs:"},
-{ "send": { "type": "cmakeInputs", "cookie":"INPUTS" } },
-{ "reply": { "type": "cmakeInputs", "cookie":"INPUTS" } },
-
-{ "message": "Cache:"},
-{ "send": { "type": "cache", "cookie":"CACHE" } },
-{ "reply": { "type": "cache", "cookie":"CACHE" } },
-
-{ "message": "Everything ok." }
-]
diff --git a/Tests/Server/tc_cache.json b/Tests/Server/tc_cache.json
deleted file mode 100644
index 74af6d9..0000000
--- a/Tests/Server/tc_cache.json
+++ /dev/null
@@ -1,24 +0,0 @@
-[
-{ "message": "Testing cache" },
-
-{ "message": "Cache after first handshake is empty:" },
-{ "handshake": {"major": 1, "sourceDirectory": "buildsystem1", "buildDirectory": "buildsystem1"} },
-{ "send": { "type": "cache" } },
-{ "validateCache": { "isEmpty": true } },
-
-{ "message": "Cache after configure is populated:" },
-{ "send": { "type": "configure" } },
-{ "reply": { "type": "configure", "skipProgress":true } },
-{ "send": { "type": "cache" } },
-{ "validateCache": { "isEmpty": false } },
-
-{ "message": "Handshake for existing cache requires buildDirectory only:" },
-{ "reconnect": {} },
-{ "handshake": {"major": 1, "sourceDirectory": "", "buildDirectory": "buildsystem1"} },
-
-{ "message": "Cache after reconnect is again populated:" },
-{ "send": { "type": "cache" } },
-{ "validateCache": { "isEmpty": false } },
-
-{ "message": "Everything ok." }
-]
diff --git a/Tests/Server/tc_globalSettings.json b/Tests/Server/tc_globalSettings.json
deleted file mode 100644
index d72fb41..0000000
--- a/Tests/Server/tc_globalSettings.json
+++ /dev/null
@@ -1,140 +0,0 @@
-[
-{ "message": "Testing globalSettings" },
-
-{ "handshake": {"major": 1} },
-
-{ "send": { "type": "globalSettings"} },
-{ "validateGlobalSettings": { "warnUnused": false, "debugOutput": false, "warnUninitialized": false, "traceExpand": false, "trace": false, "warnUnusedCli": true, "checkSystemVars": false } },
-
-
-
-{ "message": "Change settings:" },
-
-{ "send": { "type": "setGlobalSettings", "warnUnused": true } },
-{ "reply": { "type": "setGlobalSettings" } },
-
-{ "send": { "type": "globalSettings"} },
-{ "validateGlobalSettings": { "warnUnused": true, "debugOutput": false, "warnUninitialized": false, "traceExpand": false, "trace": false, "warnUnusedCli": true, "checkSystemVars": false } },
-
-{ "send": { "type": "setGlobalSettings", "warnUnused": false } },
-{ "reply": { "type": "setGlobalSettings" } },
-
-{ "send": { "type": "globalSettings"} },
-{ "validateGlobalSettings": { "warnUnused": false, "debugOutput": false, "warnUninitialized": false, "traceExpand": false, "trace": false, "warnUnusedCli": true, "checkSystemVars": false } },
-
-{ "send": { "type": "setGlobalSettings", "debugOutput": true } },
-{ "reply": { "type": "setGlobalSettings" } },
-
-{ "send": { "type": "globalSettings"} },
-{ "validateGlobalSettings": { "warnUnused": false, "debugOutput": true, "warnUninitialized": false, "traceExpand": false, "trace": false, "warnUnusedCli": true, "checkSystemVars": false } },
-
-{ "send": { "type": "setGlobalSettings", "debugOutput": false } },
-{ "reply": { "type": "setGlobalSettings" } },
-
-{ "send": { "type": "globalSettings"} },
-{ "validateGlobalSettings": { "warnUnused": false, "debugOutput": false, "warnUninitialized": false, "traceExpand": false, "trace": false, "warnUnusedCli": true, "checkSystemVars": false } },
-
-{ "send": { "type": "setGlobalSettings", "warnUninitialized": true } },
-{ "reply": { "type": "setGlobalSettings" } },
-
-{ "send": { "type": "globalSettings"} },
-{ "validateGlobalSettings": { "warnUnused": false, "debugOutput": false, "warnUninitialized": true, "traceExpand": false, "trace": false, "warnUnusedCli": true, "checkSystemVars": false } },
-
-{ "send": { "type": "setGlobalSettings", "warnUninitialized": false } },
-{ "reply": { "type": "setGlobalSettings" } },
-
-{ "send": { "type": "globalSettings"} },
-{ "validateGlobalSettings": { "warnUnused": false, "debugOutput": false, "warnUninitialized": false, "traceExpand": false, "trace": false, "warnUnusedCli": true, "checkSystemVars": false } },
-
-{ "send": { "type": "setGlobalSettings", "traceExpand": true } },
-{ "reply": { "type": "setGlobalSettings" } },
-
-{ "send": { "type": "globalSettings"} },
-{ "validateGlobalSettings": { "warnUnused": false, "debugOutput": false, "warnUninitialized": false, "traceExpand": true, "trace": false, "warnUnusedCli": true, "checkSystemVars": false } },
-
-{ "send": { "type": "setGlobalSettings", "traceExpand": false } },
-{ "reply": { "type": "setGlobalSettings" } },
-
-{ "send": { "type": "globalSettings"} },
-{ "validateGlobalSettings": { "warnUnused": false, "debugOutput": false, "warnUninitialized": false, "traceExpand": false, "trace": false, "warnUnusedCli": true, "checkSystemVars": false } },
-
-
-
-{ "send": { "type": "setGlobalSettings", "trace": true } },
-{ "reply": { "type": "setGlobalSettings" } },
-
-{ "send": { "type": "globalSettings"} },
-{ "validateGlobalSettings": { "warnUnused": false, "debugOutput": false, "warnUninitialized": false, "traceExpand": false, "trace": true, "warnUnusedCli": true, "checkSystemVars": false } },
-
-{ "send": { "type": "setGlobalSettings", "trace": false } },
-{ "reply": { "type": "setGlobalSettings" } },
-
-{ "send": { "type": "globalSettings"} },
-{ "validateGlobalSettings": { "warnUnused": false, "debugOutput": false, "warnUninitialized": false, "traceExpand": false, "trace": false, "warnUnusedCli": true, "checkSystemVars": false } },
-
-{ "send": { "type": "setGlobalSettings", "warnUnusedCli": false } },
-{ "reply": { "type": "setGlobalSettings" } },
-
-{ "send": { "type": "globalSettings"} },
-{ "validateGlobalSettings": { "warnUnused": false, "debugOutput": false, "warnUninitialized": false, "traceExpand": false, "trace": false, "warnUnusedCli": false, "checkSystemVars": false } },
-
-{ "send": { "type": "setGlobalSettings", "warnUnusedCli": true } },
-{ "reply": { "type": "setGlobalSettings" } },
-
-{ "send": { "type": "globalSettings"} },
-{ "validateGlobalSettings": { "warnUnused": false, "debugOutput": false, "warnUninitialized": false, "traceExpand": false, "trace": false, "warnUnusedCli": true, "checkSystemVars": false } },
-
-{ "send": { "type": "setGlobalSettings", "checkSystemVars": true } },
-{ "reply": { "type": "setGlobalSettings" } },
-
-{ "send": { "type": "globalSettings"} },
-{ "validateGlobalSettings": { "warnUnused": false, "debugOutput": false, "warnUninitialized": false, "traceExpand": false, "trace": false, "warnUnusedCli": true, "checkSystemVars": true } },
-
-{ "send": { "type": "setGlobalSettings", "checkSystemVars": false } },
-{ "reply": { "type": "setGlobalSettings" } },
-
-{ "send": { "type": "globalSettings"} },
-{ "validateGlobalSettings": { "warnUnused": false, "debugOutput": false, "warnUninitialized": false, "traceExpand": false, "trace": false, "warnUnusedCli": true, "checkSystemVars": false } },
-
-{ "send": { "type": "setGlobalSettings", "warnUnused": true, "debugOutput": true, "warnUninitialized": true, "traceExpand": true, "trace": true, "warnUnusedCli": false, "checkSystemVars": true } },
-{ "reply": { "type": "setGlobalSettings" } },
-
-{ "send": { "type": "globalSettings"} },
-{ "validateGlobalSettings": { "warnUnused": true, "debugOutput": true, "warnUninitialized": true, "traceExpand": true, "trace": true, "warnUnusedCli": false, "checkSystemVars": true } },
-
-{ "message": "Ignore unknown/readonly" },
-
-{ "send": { "type": "setGlobalSettings", "unknownKey": "unknownValue", "extraGenerator": "XXX", "generator": "YYY", "sourceDirectory": "/tmp/source", "buildDirectory": "/tmp/build" } },
-{ "reply": { "type": "setGlobalSettings" } },
-
-{ "send": { "type": "globalSettings"} },
-{ "validateGlobalSettings": { "warnUnused": true, "debugOutput": true, "warnUninitialized": true, "traceExpand": true, "trace": true, "warnUnusedCli": false, "checkSystemVars": true } },
-
-{ "message": "Error paths:" },
-
-{ "send": { "type": "setGlobalSettings", "debugOutput": true, "warnUnused": 1 } },
-{ "error": { "type": "setGlobalSettings", "message": "\"warnUnused\" must be unset or a bool value." } },
-
-{ "send": { "type": "setGlobalSettings", "warnUnused": true, "debugOutput": 1 } },
-{ "error": { "type": "setGlobalSettings", "message": "\"debugOutput\" must be unset or a bool value." } },
-
-{ "send": { "type": "setGlobalSettings", "warnUninitialized": 1, "warnUnused": true, "debugOutput": true } },
-{ "error": { "type": "setGlobalSettings", "message": "\"warnUninitialized\" must be unset or a bool value." } },
-
-{ "send": { "type": "setGlobalSettings", "warnUnused": true, "debugOutput": true, "traceExpand": 1 } },
-{ "error": { "type": "setGlobalSettings", "message": "\"traceExpand\" must be unset or a bool value." } },
-
-{ "send": { "type": "setGlobalSettings", "debugOutput": true, "trace": 1, "warnUnused": true } },
-{ "error": { "type": "setGlobalSettings", "message": "\"trace\" must be unset or a bool value." } },
-
-{ "send": { "type": "setGlobalSettings", "warnUnused": true, "debugOutput": true, "warnUnusedCli": 1.0 } },
-{ "error": { "type": "setGlobalSettings", "message": "\"warnUnusedCli\" must be unset or a bool value." } },
-
-{ "send": { "type": "setGlobalSettings", "warnUnused": true, "debugOutput": true, "checkSystemVars": "some string" } },
-{ "error": { "type": "setGlobalSettings", "message": "\"checkSystemVars\" must be unset or a bool value." } },
-
-{ "send": { "type": "globalSettings"} },
-{ "validateGlobalSettings": { "warnUnused": true, "debugOutput": true, "warnUninitialized": true, "traceExpand": true, "trace": true, "warnUnusedCli": false, "checkSystemVars": true } },
-
-{ "message": "Everything ok." }
-]
diff --git a/Tests/Server/tc_handshake.json b/Tests/Server/tc_handshake.json
deleted file mode 100644
index 4bb7fa7..0000000
--- a/Tests/Server/tc_handshake.json
+++ /dev/null
@@ -1,75 +0,0 @@
-[
-{ "message": "Testing basic message handling:" },
-
-{ "sendRaw": "Sometext"},
-{ "recv": {"cookie":"","errorMessage":"Failed to parse JSON input.","inReplyTo":"","type":"error"} },
-
-{ "message": "Testing invalid json input"},
-{ "send": { "test": "sometext" } },
-{ "recv": {"cookie":"","errorMessage":"No type given in request.","inReplyTo":"","type":"error"} },
-
-{ "send": {"test": "sometext","cookie":"monster"} },
-{ "recv": {"cookie":"monster","errorMessage":"No type given in request.","inReplyTo":"","type":"error"} },
-
-{ "message": "Testing commands before handshake" },
-{ "send": {"type": "cache","cookie":"monster"} },
-{ "recv": {"cookie":"monster","errorMessage":"Waiting for type \"handshake\".","inReplyTo":"cache","type":"error"} },
-
-{ "message": "Testing handshake" },
-{ "send": {"type": "sometype","cookie":"monster2"} },
-{ "recv": {"cookie":"monster2","errorMessage":"Waiting for type \"handshake\".","inReplyTo":"sometype","type":"error"} },
-
-{ "send": {"type": "handshake"} },
-{ "recv": {"cookie":"","errorMessage":"\"protocolVersion\" is required for \"handshake\".","inReplyTo":"handshake","type":"error"} },
-
-{ "send": {"type": "handshake","foo":"bar"} },
-{ "recv": {"cookie":"","errorMessage":"\"protocolVersion\" is required for \"handshake\".","inReplyTo":"handshake","type":"error"} },
-
-{ "send": {"type": "handshake","protocolVersion":"bar"} },
-{ "recv": {"cookie":"","errorMessage":"\"protocolVersion\" must be a JSON object.","inReplyTo":"handshake","type":"error"} },
-
-{ "send": {"type": "handshake","protocolVersion":{}} },
-{ "recv": {"cookie":"","errorMessage":"\"major\" must be set and an integer.","inReplyTo":"handshake","type":"error"} },
-
-{ "send": {"type": "handshake","protocolVersion":{"major":"foo"}} },
-{ "recv": {"cookie":"","errorMessage":"\"major\" must be set and an integer.","inReplyTo":"handshake","type":"error"} },
-
-{ "send": {"type": "handshake","protocolVersion":{"major":1, "minor":"foo"}} },
-{ "recv": {"cookie":"","errorMessage":"\"minor\" must be unset or an integer.","inReplyTo":"handshake","type":"error"} },
-
-{ "send": {"type": "handshake","protocolVersion":{"major":-1, "minor":-1}} },
-{ "recv": {"cookie":"","errorMessage":"\"major\" must be >= 0.","inReplyTo":"handshake","type":"error"} },
-
-{ "send": {"type": "handshake","protocolVersion":{"major":10, "minor":-1}} },
-{ "recv": {"cookie":"","errorMessage":"\"minor\" must be >= 0 when set.","inReplyTo":"handshake","type":"error"} },
-
-{ "send": {"type": "handshake","protocolVersion":{"major":10000}} },
-{ "recv": {"cookie":"","errorMessage":"Protocol version not supported.","inReplyTo":"handshake","type":"error"} },
-
-{ "send": {"type": "handshake","protocolVersion":{"major":1, "minor":10000}} },
-{ "recv": {"cookie":"","errorMessage":"Protocol version not supported.","inReplyTo":"handshake","type":"error"} },
-
-{ "send": {"cookie":"zimtstern","type": "handshake","protocolVersion":{"major":1}} },
-{ "recv": {"cookie":"zimtstern","inReplyTo":"handshake","type":"error","errorMessage":"Failed to activate protocol version: \"buildDirectory\" is missing."} },
-
-{ "message": "Testing protocol version specific options (1.0):" },
-{ "send": {"cookie":"zimtstern","type": "handshake","protocolVersion":{"major":1},"sourceDirectory":"/tmp/src"} },
-{ "recv": {"cookie":"zimtstern","inReplyTo":"handshake","type":"error","errorMessage":"Failed to activate protocol version: \"buildDirectory\" is missing."} },
-
-{ "send": {"cookie":"zimtstern","type": "handshake","protocolVersion":{"major":1},"sourceDirectory":"/tmp/src","buildDirectory":"/tmp/build"} },
-{ "recv": {"cookie":"zimtstern","inReplyTo":"handshake","type":"error","errorMessage":"Failed to activate protocol version: \"sourceDirectory\" is not a directory."} },
-
-{ "send": {"cookie":"zimtstern","type": "handshake","protocolVersion":{"major":1},"sourceDirectory":".","buildDirectory":"/tmp/build","extraGenerator":"CodeBlocks"} },
-{ "recv": {"cookie":"zimtstern","inReplyTo":"handshake","type":"error","errorMessage":"Failed to activate protocol version: \"generator\" is unset but required."} },
-
-{ "send": {"cookie":"zimtstern","type": "handshake","protocolVersion":{"major":1},"sourceDirectory":".","buildDirectory":"/tmp/build","generator":"XXXX","extraGenerator":"CodeBlocks"} },
-{ "recv": {"cookie":"zimtstern","inReplyTo":"handshake","type":"error","errorMessage":"Failed to activate protocol version: Generator \"XXXX\" not supported."} },
-
-{ "send": {"cookie":"zimtstern","type": "handshake","protocolVersion":{"major":1},"sourceDirectory":".","buildDirectory":"/tmp/build","generator":"Ninja","extraGenerator":"XXXX"} },
-{ "recv": {"cookie":"zimtstern","inReplyTo":"handshake","type":"error","errorMessage":"Failed to activate protocol version: The combination of generator \"Ninja\" and extra generator \"XXXX\" is not supported."} },
-
-{ "send": {"cookie":"zimtstern","type": "handshake","protocolVersion":{"major":1},"sourceDirectory":".","buildDirectory":"/tmp/build","generator":"Ninja","extraGenerator":"CodeBlocks"} },
-{ "recv": {"cookie":"zimtstern","inReplyTo":"handshake","type":"reply"} },
-
-{ "message": "Everything ok." }
-]
diff --git a/Utilities/Doxygen/CMakeLists.txt b/Utilities/Doxygen/CMakeLists.txt
index 5bf13f3..a880f7a 100644
--- a/Utilities/Doxygen/CMakeLists.txt
+++ b/Utilities/Doxygen/CMakeLists.txt
@@ -3,7 +3,7 @@
 
 if(NOT CMake_SOURCE_DIR)
   set(CMakeDeveloperReference_STANDALONE 1)
-  cmake_minimum_required(VERSION 3.1...3.15 FATAL_ERROR)
+  cmake_minimum_required(VERSION 3.1...3.18 FATAL_ERROR)
   get_filename_component(tmp "${CMAKE_CURRENT_SOURCE_DIR}" PATH)
   get_filename_component(CMake_SOURCE_DIR "${tmp}" PATH)
   include(${CMake_SOURCE_DIR}/Modules/CTestUseLaunchers.cmake)
diff --git a/Utilities/Sphinx/CMakeLists.txt b/Utilities/Sphinx/CMakeLists.txt
index e5be43a..f989907 100644
--- a/Utilities/Sphinx/CMakeLists.txt
+++ b/Utilities/Sphinx/CMakeLists.txt
@@ -3,7 +3,7 @@
 
 if(NOT CMake_SOURCE_DIR)
   set(CMakeHelp_STANDALONE 1)
-  cmake_minimum_required(VERSION 3.1...3.15 FATAL_ERROR)
+  cmake_minimum_required(VERSION 3.1...3.18 FATAL_ERROR)
   get_filename_component(tmp "${CMAKE_CURRENT_SOURCE_DIR}" PATH)
   get_filename_component(CMake_SOURCE_DIR "${tmp}" PATH)
   include(${CMake_SOURCE_DIR}/Modules/CTestUseLaunchers.cmake)
diff --git a/Utilities/std/cm/optional b/Utilities/std/cm/optional
index 9a5d840..0defae1 100644
--- a/Utilities/std/cm/optional
+++ b/Utilities/std/cm/optional
@@ -68,16 +68,22 @@
 
   optional& operator=(nullopt_t) noexcept;
   optional& operator=(const optional& other);
-  optional& operator=(optional&& other) noexcept;
 
-  template <
-    typename U = T,
-    typename = typename std::enable_if<
-      !std::is_same<typename std::decay<U>::type, cm::optional<T>>::value &&
-      std::is_constructible<T, U>::value && std::is_assignable<T&, U>::value &&
+  template <typename U = T>
+  typename std::enable_if<std::is_constructible<T, U&&>::value &&
+                            std::is_assignable<T&, U&&>::value,
+                          optional&>::type
+  operator=(optional<U>&& other) noexcept;
+
+  template <typename U = T>
+  typename std::enable_if<
+    !std::is_same<typename std::decay<U>::type, cm::optional<T>>::value &&
+      std::is_constructible<T, U&&>::value &&
+      std::is_assignable<T&, U&&>::value &&
       (!std::is_scalar<T>::value ||
-       !std::is_same<typename std::decay<U>::type, T>::value)>::type>
-  optional& operator=(U&& v);
+       !std::is_same<typename std::decay<U>::type, T>::value),
+    optional&>::type
+  operator=(U&& v);
 
   const T* operator->() const;
   T* operator->();
@@ -134,19 +140,24 @@
 
 template <typename T>
 optional<T>::optional(nullopt_t) noexcept
+  : optional()
 {
 }
 
 template <typename T>
 optional<T>::optional(const optional& other)
 {
-  *this = other;
+  if (other.has_value()) {
+    this->emplace(*other);
+  }
 }
 
 template <typename T>
 optional<T>::optional(optional&& other) noexcept
 {
-  *this = std::move(other);
+  if (other.has_value()) {
+    this->emplace(std::move(*other));
+  }
 }
 
 template <typename T>
@@ -192,7 +203,11 @@
 }
 
 template <typename T>
-optional<T>& optional<T>::operator=(optional&& other) noexcept
+template <typename U>
+typename std::enable_if<std::is_constructible<T, U&&>::value &&
+                          std::is_assignable<T&, U&&>::value,
+                        optional<T>&>::type
+optional<T>::operator=(optional<U>&& other) noexcept
 {
   if (other.has_value()) {
     if (this->has_value()) {
@@ -207,8 +222,15 @@
 }
 
 template <typename T>
-template <typename U, typename>
-optional<T>& optional<T>::operator=(U&& v)
+template <typename U>
+typename std::enable_if<
+  !std::is_same<typename std::decay<U>::type, cm::optional<T>>::value &&
+    std::is_constructible<T, U&&>::value &&
+    std::is_assignable<T&, U&&>::value &&
+    (!std::is_scalar<T>::value ||
+     !std::is_same<typename std::decay<U>::type, T>::value),
+  optional<T>&>::type
+optional<T>::operator=(U&& v)
 {
   if (this->has_value()) {
     this->value() = v;
diff --git a/bootstrap b/bootstrap
index 7ec3687..b7fcd7e 100755
--- a/bootstrap
+++ b/bootstrap
@@ -289,6 +289,7 @@
   cmBuildCommand \
   cmCMakeMinimumRequired \
   cmCMakePath \
+  cmCMakePathCommand \
   cmCMakePolicyCommand \
   cmCPackPropertiesGenerator \
   cmCacheManager \
@@ -307,6 +308,7 @@
   cmContinueCommand \
   cmCoreTryCompile \
   cmCreateTestSourceList \
+  cmCryptoHash \
   cmCustomCommand \
   cmCustomCommandGenerator \
   cmCustomCommandLines \
@@ -412,6 +414,8 @@
   cmProjectCommand \
   cmPropertyDefinition \
   cmPropertyMap \
+  cmGccDepfileLexerHelper \
+  cmGccDepfileReader \
   cmReturnCommand \
   cmRulePlaceholderExpander \
   cmRuntimeDependencyArchive \
@@ -452,6 +456,7 @@
   cmTest \
   cmTestGenerator \
   cmTimestamp \
+  cmTransformDepfile \
   cmTryCompileCommand \
   cmTryRunCommand \
   cmUnsetCommand \
@@ -491,6 +496,7 @@
   cmCommandArgumentParser \
   cmExprLexer \
   cmExprParser \
+  cmGccDepfileLexer \
 "
 
 LexerParser_C_SOURCES="\
@@ -535,6 +541,18 @@
   SystemTools.hxx \
   Terminal.h"
 
+LIBRHASH_C_SOURCES="\
+  librhash/algorithms.c \
+  librhash/byte_order.c \
+  librhash/hex.c \
+  librhash/md5.c \
+  librhash/rhash.c \
+  librhash/sha1.c \
+  librhash/sha256.c \
+  librhash/sha3.c \
+  librhash/sha512.c \
+  "
+
 if ${cmake_system_mingw}; then
   LIBUV_C_SOURCES="\
     src/fs-poll.c \
@@ -1012,7 +1030,6 @@
 # Add generator-specific files
 if test "${cmake_bootstrap_generator}" = "Ninja"; then
   CMAKE_CXX_SOURCES="${CMAKE_CXX_SOURCES} \
-    cmCryptoHash \
     cmFortranParserImpl \
     cmGlobalNinjaGenerator \
     cmLocalNinjaGenerator \
@@ -1033,18 +1050,6 @@
     src/lib_json/json_value.cpp \
     src/lib_json/json_writer.cpp \
     "
-
-  LIBRHASH_C_SOURCES="\
-    librhash/algorithms.c \
-    librhash/byte_order.c \
-    librhash/hex.c \
-    librhash/md5.c \
-    librhash/rhash.c \
-    librhash/sha1.c \
-    librhash/sha256.c \
-    librhash/sha3.c \
-    librhash/sha512.c \
-    "
 else
   CMAKE_CXX_SOURCES="${CMAKE_CXX_SOURCES} \
     cmDepends \
@@ -1058,7 +1063,6 @@
     "
 
   JSONCPP_CXX_SOURCES=
-  LIBRHASH_C_SOURCES=
 fi
 
 # Add Cygwin-specific flags
@@ -1628,17 +1632,17 @@
     objs="${objs} uv-`cmake_obj ${a}`"
   done
 fi
+if test "x${bootstrap_system_librhash}" = "x"; then
+  for a in ${LIBRHASH_C_SOURCES}; do
+    objs="${objs} rhash-`cmake_obj ${a}`"
+  done
+fi
 if test "${cmake_bootstrap_generator}" = "Ninja"; then
   if test "x${bootstrap_system_jsoncpp}" = "x"; then
     for a in ${JSONCPP_CXX_SOURCES}; do
       objs="${objs} jsoncpp-`cmake_obj ${a}`"
     done
   fi
-  if test "x${bootstrap_system_librhash}" = "x"; then
-    for a in ${LIBRHASH_C_SOURCES}; do
-      objs="${objs} rhash-`cmake_obj ${a}`"
-    done
-  fi
 fi
 
 libs=""
@@ -1698,6 +1702,15 @@
   libs="${libs} -luv"
 fi
 
+if test "x${bootstrap_system_librhash}" != "x"; then
+  if test `which pkg-config`; then
+    use_librhash_flags="`pkg-config --cflags librhash`"
+    cmake_c_flags="${cmake_c_flags} ${use_librhash_flags}"
+    cmake_cxx_flags="${cmake_cxx_flags} ${use_librhash_flags}"
+  fi
+  libs="${libs} -lrhash"
+fi
+
 if test "${cmake_bootstrap_generator}" = "Ninja"; then
   jsoncpp_cxx_flags=
   if test "x${bootstrap_system_jsoncpp}" = "x"; then
@@ -1709,15 +1722,6 @@
     fi
     libs="${libs} -ljsoncpp"
   fi
-
-  if test "x${bootstrap_system_librhash}" != "x"; then
-    if test `which pkg-config`; then
-      use_librhash_flags="`pkg-config --cflags librhash`"
-      cmake_c_flags="${cmake_c_flags} ${use_librhash_flags}"
-      cmake_cxx_flags="${cmake_cxx_flags} ${use_librhash_flags}"
-    fi
-    libs="${libs} -lrhash"
-  fi
 fi
 
 if test "x${cmake_ansi_cxx_flags}" != "x"; then
@@ -1841,6 +1845,12 @@
     write_source_rule "c" "uv-`cmake_obj ${a}`" "${src}" "${uv_c_flags}"
   done
 fi
+if test "x${bootstrap_system_librhash}" = "x"; then
+  for a in ${LIBRHASH_C_SOURCES}; do
+    src=`cmake_escape_artifact "${cmake_source_dir}/Utilities/cmlibrhash/${a}"`
+    write_source_rule "c" "rhash-`cmake_obj ${a}`" "${src}" ""
+  done
+fi
 if test "${cmake_bootstrap_generator}" = "Ninja"; then
   if test "x${bootstrap_system_jsoncpp}" = "x"; then
     for a in ${JSONCPP_CXX_SOURCES}; do
@@ -1848,12 +1858,6 @@
       write_source_rule "cxx" "jsoncpp-`cmake_obj ${a}`" "${src}" "${jsoncpp_cxx_flags}"
     done
   fi
-  if test "x${bootstrap_system_librhash}" = "x"; then
-    for a in ${LIBRHASH_C_SOURCES}; do
-      src=`cmake_escape_artifact "${cmake_source_dir}/Utilities/cmlibrhash/${a}"`
-      write_source_rule "c" "rhash-`cmake_obj ${a}`" "${src}" ""
-    done
-  fi
 fi
 if test "${cmake_bootstrap_generator}" = "Ninja"; then
   echo "