Merge topic 'correct_msvc_cuda_flag_warning' into release-3.19

2b0d3c3524 CUDA: Use MSVC version to determine supported C++ standard levels

Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !5423
diff --git a/.gitlab/ci/configure_fedora31_common.cmake b/.gitlab/ci/configure_fedora31_common.cmake
index dc068d5..c343833 100644
--- a/.gitlab/ci/configure_fedora31_common.cmake
+++ b/.gitlab/ci/configure_fedora31_common.cmake
@@ -1,4 +1,5 @@
 set(BUILD_CursesDialog ON CACHE BOOL "")
 set(BUILD_QtDialog ON CACHE BOOL "")
+set(CMake_TEST_JSON_SCHEMA ON CACHE BOOL "")
 
 include("${CMAKE_CURRENT_LIST_DIR}/configure_common.cmake")
diff --git a/.gitlab/ci/docker/fedora31/install_deps.sh b/.gitlab/ci/docker/fedora31/install_deps.sh
index 8de213a..fa57f61 100755
--- a/.gitlab/ci/docker/fedora31/install_deps.sh
+++ b/.gitlab/ci/docker/fedora31/install_deps.sh
@@ -65,6 +65,7 @@
     pypy3 pypy3-devel \
     python2 python2-devel python2-numpy \
     python3 python3-devel python3-numpy \
+    python3-jsmin python3-jsonschema \
     ruby rubygems ruby-devel \
     SDL-devel \
     sqlite-devel \
diff --git a/.gitlab/ci/download_python3.cmake b/.gitlab/ci/download_python3.cmake
new file mode 100644
index 0000000..0f5b18b
--- /dev/null
+++ b/.gitlab/ci/download_python3.cmake
@@ -0,0 +1,41 @@
+cmake_minimum_required(VERSION 3.17)
+
+set(version "3.8.6")
+set(sha256sum "376e18eef7e3ea467f0e3af041b01fc7e2f12855506c2ab2653ceb5e0951212e")
+set(dirname "python-${version}-embed-win-x86_64")
+set(tarball "${dirname}.tar.xz")
+
+# Download the file.
+file(DOWNLOAD
+  "https://cmake.org/files/dependencies/${tarball}"
+  ".gitlab/${tarball}"
+  STATUS download_status
+  EXPECTED_HASH "SHA256=${sha256sum}")
+
+# Check the download status.
+list(GET download_status 0 res)
+if (res)
+  list(GET download_status 1 err)
+  message(FATAL_ERROR
+    "Failed to download ${tarball}: ${err}")
+endif ()
+
+# Extract the file.
+execute_process(
+  COMMAND
+    "${CMAKE_COMMAND}"
+    -E tar
+    xzf "${tarball}"
+  WORKING_DIRECTORY ".gitlab"
+  RESULT_VARIABLE res
+  ERROR_VARIABLE err
+  ERROR_STRIP_TRAILING_WHITESPACE)
+if (res)
+  message(FATAL_ERROR
+    "Failed to extract ${tarball}: ${err}")
+endif ()
+
+# Move to a predictable directory.
+file(RENAME
+  ".gitlab/${dirname}"
+  ".gitlab/python3")
diff --git a/.gitlab/ci/sccache.sh b/.gitlab/ci/sccache.sh
index f7d51ff..af24710 100755
--- a/.gitlab/ci/sccache.sh
+++ b/.gitlab/ci/sccache.sh
@@ -2,17 +2,17 @@
 
 set -e
 
-readonly version="0.2.13"
-
 case "$( uname -s )" in
     Linux)
+        version="0.2.13"
         shatool="sha256sum"
         sha256sum="28a5499e340865b08b632306b435913beb590fbd7b49a3f887a623b459fabdeb"
         platform="x86_64-unknown-linux-musl"
         ;;
     Darwin)
+        version="gfe63078"
         shatool="shasum -a 256"
-        sha256sum="f564e948abadfc9e409eb1cd7babf24c6784057d5506c3b0a04cdd37cd830ae9"
+        sha256sum="60a0302b1d7227f7ef56abd82266353f570d27c6e850c56c6448bf62def38888"
         platform="x86_64-apple-darwin"
         ;;
     *)
@@ -20,6 +20,7 @@
         exit 1
         ;;
 esac
+readonly version
 readonly shatool
 readonly sha256sum
 readonly platform
@@ -27,10 +28,17 @@
 readonly filename="sccache-$version-$platform"
 readonly tarball="$filename.tar.gz"
 
+if [ "$( uname -s )" = "Darwin" ]; then
+    url="https://paraview.org/files/dependencies"
+else
+    url="https://github.com/mozilla/sccache/releases/download/$version"
+fi
+readonly url
+
 cd .gitlab
 
 echo "$sha256sum  $tarball" > sccache.sha256sum
-curl -OL "https://github.com/mozilla/sccache/releases/download/$version/$tarball"
+curl -OL "$url/$tarball"
 $shatool --check sccache.sha256sum
 tar xf "$tarball"
 mv "$filename/sccache" .
diff --git a/.gitlab/os-linux.yml b/.gitlab/os-linux.yml
index 8e7a854..9438676 100644
--- a/.gitlab/os-linux.yml
+++ b/.gitlab/os-linux.yml
@@ -49,7 +49,7 @@
 ### Fedora
 
 .fedora31:
-    image: "kitware/cmake:ci-fedora31-x86_64-2020-10-03"
+    image: "kitware/cmake:ci-fedora31-x86_64-2020-10-20"
 
     variables:
         GIT_CLONE_PATH: "$CI_BUILDS_DIR/cmake ci"
diff --git a/.gitlab/os-windows.yml b/.gitlab/os-windows.yml
index 61a2018..6830b8a 100644
--- a/.gitlab/os-windows.yml
+++ b/.gitlab/os-windows.yml
@@ -82,6 +82,9 @@
     - ninja --version
     - cmake -P .gitlab/ci/download_qt.cmake
     - Set-Item -Force -Path "env:PATH" -Value "$pwdpath\.gitlab\qt\bin;$env:PATH"
+    - cmake -P .gitlab/ci/download_python3.cmake
+    - Set-Item -Force -Path "env:PATH" -Value "$pwdpath\.gitlab\python3;$env:PATH"
+    - python --version
 
 .cmake_build_windows:
     stage: build
diff --git a/Help/command/cmake_language.rst b/Help/command/cmake_language.rst
index 00e1a69..40a45e3 100644
--- a/Help/command/cmake_language.rst
+++ b/Help/command/cmake_language.rst
@@ -134,14 +134,14 @@
 
 ``ID <id>``
   Specify an identification for the deferred call.
-  The id may not be empty and may not begin in a capital letter ``A-Z``.
-  The id may begin in a ``_`` only if it was generated by another call
-  that used ``ID_VAR`` to get the id.
+  The ``<id>`` may not be empty and may not begin with a capital letter ``A-Z``.
+  The ``<id>`` may begin with an underscore (``_``) only if it was generated
+  automatically by an earlier call that used ``ID_VAR`` to get the id.
 
 ``ID_VAR <var>``
-  Sepcify a variable in which to store the identification for the
+  Specify a variable in which to store the identification for the
   deferred call.  If ``ID <id>`` is not given, a new identification
-  will be generated starting in a ``_``.
+  will be generated and the generated id will start with an underscore (``_``).
 
 The currently scheduled list of deferred calls may be retrieved:
 
@@ -149,7 +149,7 @@
 
   cmake_language(DEFER [DIRECTORY <dir>] GET_CALL_IDS <var>)
 
-This will store in ``<var>`` a :ref:`Semicolon-separated list <CMake Language
+This will store in ``<var>`` a :ref:`semicolon-separated list <CMake Language
 Lists>` of deferred call ids.
 
 Details of a specific call may be retrieved from its id:
@@ -158,7 +158,7 @@
 
   cmake_language(DEFER [DIRECTORY <dir>] GET_CALL <id> <var>)
 
-This will store in ``<var>`` a :ref:`Semicolon-separated list <CMake Language
+This will store in ``<var>`` a :ref:`semicolon-separated list <CMake Language
 Lists>` in which the first element is the name of the command to be
 called, and the remaining elements are its unevaluated arguments (any
 contained ``;`` characters are included literally and cannot be distinguished
diff --git a/Help/command/configure_file.rst b/Help/command/configure_file.rst
index 46d1a05..c59995a 100644
--- a/Help/command/configure_file.rst
+++ b/Help/command/configure_file.rst
@@ -83,7 +83,7 @@
   Restrict variable replacement to references of the form ``@VAR@``.
   This is useful for configuring scripts that use ``${VAR}`` syntax.
 
- ``NO_SOURCE_PERMISSIONS``
+``NO_SOURCE_PERMISSIONS``
   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--).
diff --git a/Help/command/execute_process.rst b/Help/command/execute_process.rst
index a6f141a..268c307 100644
--- a/Help/command/execute_process.rst
+++ b/Help/command/execute_process.rst
@@ -118,9 +118,17 @@
   This is analogous to the ``tee`` Unix command.
 
 ``COMMAND_ERROR_IS_FATAL <ANY|LAST>``
-  ``COMMAND_ERROR_IS_FATAL ANY`` option stops processing if any command fails.
-  ``COMMAND_ERROR_IS_FATAL LAST`` option stops processing if the last command
-  in the command list fails.
+  The option following ``COMMAND_ERROR_IS_FATAL`` determines the behavior when
+  an error is encountered:
+
+    ``ANY``
+    If any of the commands in the list of commands fail, the
+    ``execute_process()`` command halts with an error.
+
+    ``LAST``
+    If the last command in the list of commands fails, the
+    ``execute_process()`` command halts with an error.  Commands earlier in the
+    list will not cause a fatal error.
 
 If more than one ``OUTPUT_*`` or ``ERROR_*`` option is given for the
 same pipe the precedence is not specified.
diff --git a/Help/command/file.rst b/Help/command/file.rst
index 4210bd4..b406e10 100644
--- a/Help/command/file.rst
+++ b/Help/command/file.rst
@@ -54,7 +54,7 @@
     file({`TO_CMAKE_PATH`_ | `TO_NATIVE_PATH`_} <path> <out-var>)
 
   `Transfer`_
-    file(`DOWNLOAD`_ <url> <file> [...])
+    file(`DOWNLOAD`_ <url> [<file>] [...])
     file(`UPLOAD`_ <file> <url> [...])
 
   `Locking`_
@@ -498,8 +498,9 @@
   See policy :policy:`CMP0070`.
 
 ``TARGET <target>``
-  Specify target which to use when evaluating generator expressions.  Enables
-  use of generator expressions requiring a target.
+  Specify which target to use when evaluating generator expressions that
+  require a target for evaluation (e.g. ``$<COMPILE_FEATURES:...>``,
+  ``$<TARGET_PROPERTY:prop>``).
 
 Exactly one ``CONTENT`` or ``INPUT`` option must be given.  A specific
 ``OUTPUT`` file may be named by at most one invocation of ``file(GENERATE)``.
@@ -763,7 +764,8 @@
 
 .. code-block:: cmake
 
-  file(CHMOD <files>... <directories>... [PERMISSIONS <permissions>...]
+  file(CHMOD <files>... <directories>...
+      [PERMISSIONS <permissions>...]
       [FILE_PERMISSIONS <permissions>...]
       [DIRECTORY_PERMISSIONS <permissions>...])
 
@@ -775,34 +777,36 @@
 Valid combination of keywords are:
 
 ``PERMISSIONS``
-  all items are changed
+  All items are changed.
 
 ``FILE_PERMISSIONS``
-  only files are changed
+  Only files are changed.
 
 ``DIRECTORY_PERMISSIONS``
-  only directories are changed
+  Only directories are changed.
 
 ``PERMISSIONS`` and ``FILE_PERMISSIONS``
-  ``FILE_PERMISSIONS`` overrides ``PERMISSIONS`` for files
+  ``FILE_PERMISSIONS`` overrides ``PERMISSIONS`` for files.
 
 ``PERMISSIONS`` and ``DIRECTORY_PERMISSIONS``
-  ``DIRECTORY_PERMISSIONS`` overrides ``PERMISSIONS`` for directories
+  ``DIRECTORY_PERMISSIONS`` overrides ``PERMISSIONS`` for directories.
 
 ``FILE_PERMISSIONS`` and ``DIRECTORY_PERMISSIONS``
-  use ``FILE_PERMISSIONS`` for files and ``DIRECTORY_PERMISSIONS`` for
-  directories
+  Use ``FILE_PERMISSIONS`` for files and ``DIRECTORY_PERMISSIONS`` for
+  directories.
 
 
 .. _CHMOD_RECURSE:
 
 .. code-block:: cmake
 
-  file(CHMOD_RECURSE <files>... <directories>... PERMISSIONS <permissions>...
-       FILE_PERMISSIONS <permissions>... DIRECTORY_PERMISSIONS <permissions>...)
+  file(CHMOD_RECURSE <files>... <directories>...
+       [PERMISSIONS <permissions>...]
+       [FILE_PERMISSIONS <permissions>...]
+       [DIRECTORY_PERMISSIONS <permissions>...])
 
 Same as `CHMOD`_, but change the permissions of files and directories present in
-the ``<directories>..`` recursively.
+the ``<directories>...`` recursively.
 
 Path Conversion
 ^^^^^^^^^^^^^^^
@@ -859,11 +863,11 @@
   file(DOWNLOAD <url> [<file>] [<options>...])
   file(UPLOAD   <file> <url> [<options>...])
 
-The ``DOWNLOAD`` mode 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 ``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>``.
 
 Options to both ``DOWNLOAD`` and ``UPLOAD`` are:
 
@@ -986,8 +990,7 @@
   file(ARCHIVE_CREATE OUTPUT <archive>
     PATHS <paths>...
     [FORMAT <format>]
-    [COMPRESSION <compression>]
-    [COMPRESSION_LEVEL <compression level>]
+    [COMPRESSION <compression> [COMPRESSION_LEVEL <compression-level>]]
     [MTIME <mtime>]
     [VERBOSE])
 
@@ -1005,9 +1008,9 @@
 directed to do so with the ``COMPRESSION`` option.  Valid values for
 ``<compression>`` are ``None``, ``BZip2``, ``GZip``, ``XZ``, and ``Zstd``.
 
-Compression level can be specied by using ``COMPRESSION_LEVEL`` option.
-Compression level should be between 0-9. 0 is the default compression.
-``COMPRESSION`` option must be specified for ``COMPRESSION_LEVEL``.
+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
diff --git a/Help/command/find_package.rst b/Help/command/find_package.rst
index 87265ce..1be2e09 100644
--- a/Help/command/find_package.rst
+++ b/Help/command/find_package.rst
@@ -44,7 +44,8 @@
   * A version range with the format ``versionMin...[<]versionMax`` where
     ``versionMin`` and ``versionMax`` have the same format as the single
     version.  By default, both end points are included.  By specifying ``<``,
-    the upper end point will be excluded.
+    the upper end point will be excluded.  Version ranges are only supported
+    with CMake 3.19 or later.
 
 The ``EXACT`` option requests that the version be matched exactly. This option
 is incompatible with the specification of a version range.
diff --git a/Help/command/separate_arguments.rst b/Help/command/separate_arguments.rst
index 3c094aa..69fb726 100644
--- a/Help/command/separate_arguments.rst
+++ b/Help/command/separate_arguments.rst
@@ -37,7 +37,7 @@
 
 ``PROGRAM``
   The first item in ``<args>`` is assumed to be an executable and will be
-  search in the system search path or left as a full path. If not found,
+  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
   elements:
 
diff --git a/Help/command/string.rst b/Help/command/string.rst
index 0bc2b48..0c2f57e 100644
--- a/Help/command/string.rst
+++ b/Help/command/string.rst
@@ -484,12 +484,12 @@
 Where required, an uppercase representation can be requested
 with the optional ``UPPER`` flag.
 
+.. _JSON:
+
 JSON
 ^^^^
 
-.. _JSON:
-
-Functionality for querying a JSON string
+Functionality for querying a JSON string.
 
 .. _GET:
 .. code-block:: cmake
@@ -522,7 +522,7 @@
          MEMBER <json-string>
          [<member|index> ...] <index>)
 
-Get the name of the ``<index>``:th member in ``<json-string>`` at the location
+Get the name of the ``<index>``-th member in ``<json-string>`` at the location
 given by the list of ``<member|index>`` arguments.
 Requires an element of object type.
 
@@ -534,7 +534,7 @@
 
 Get the length of an element in ``<json-string>`` at the location
 given by the list of ``<member|index>`` arguments.
-Required an element of array or object type.
+Requires an element of array or object type.
 
 .. _REMOVE:
 .. code-block:: cmake
@@ -544,7 +544,7 @@
 
 Remove an element from ``<json-string>`` at the location
 given by the list of ``<member|index>`` arguments. The JSON string
-without the removed element will we written in ``<out-var>``.
+without the removed element will be stored in ``<out-var>``.
 
 .. _SET:
 .. code-block:: cmake
@@ -566,8 +566,8 @@
 for equality
 
 
-If the optional ``ERROR_VARIABLE`` argument is given errors will be
-reported in ``<error-variable>``. If no error occurs the ``<error-variable>``
+If the optional ``ERROR_VARIABLE`` argument is given, errors will be
+reported in ``<error-variable>``. If no error occurs, the ``<error-variable>``
 will be set to ``NOTFOUND``. If ``ERROR_VARIABLE`` is not set a CMake error
 will be issued.
 When an error occurs the ``<out-var>`` will be set to
diff --git a/Help/cpack_gen/external.rst b/Help/cpack_gen/external.rst
index 7ef1071..e54b356 100644
--- a/Help/cpack_gen/external.rst
+++ b/Help/cpack_gen/external.rst
@@ -285,6 +285,6 @@
 .. variable:: CPACK_EXTERNAL_BUILT_PACKAGES
 
   The ``CPACK_EXTERNAL_PACKAGE_SCRIPT`` script may set this list variable to the
-  full paths of generated package files.  CPack copy these files from the stage
-  directory back to the top build directory and possibly produce checksum files
-  if the :variable:`CPACK_PACKAGE_CHECKSUM` is set.
+  full paths of generated package files.  CPack will copy these files from the
+  staging directory back to the top build directory and possibly produce
+  checksum files if the :variable:`CPACK_PACKAGE_CHECKSUM` is set.
diff --git a/Help/guide/ide-integration/index.rst b/Help/guide/ide-integration/index.rst
index b1b9fc4..8ea31a0 100644
--- a/Help/guide/ide-integration/index.rst
+++ b/Help/guide/ide-integration/index.rst
@@ -69,6 +69,9 @@
 straightforward, it is not trivial. In addition to the documentation, IDE
 vendors may also wish to refer to the CMake source code and test cases for a
 better understanding of how to implement the format.
+:download:`This file </manual/presets/schema.json>` provides a machine-readable
+JSON schema for the ``CMakePresets.json`` format that IDE vendors may find
+useful for validation and providing editing assistance.
 
 Configuring
 ===========
diff --git a/Help/guide/user-interaction/index.rst b/Help/guide/user-interaction/index.rst
index 4bde0be..9e9f2a5 100644
--- a/Help/guide/user-interaction/index.rst
+++ b/Help/guide/user-interaction/index.rst
@@ -421,7 +421,7 @@
 variables, environment variables, and other command-line
 options. All of these options can be overridden by the
 user. The full details of the ``CMakePresets.json`` format
-are listed in the :manual:`cmake(1)` manual.
+are listed in the :manual:`cmake-presets(7)` manual.
 
 Using presets on the command-line
 ---------------------------------
diff --git a/Help/index.rst b/Help/index.rst
index 6d87f71..fdbf847 100644
--- a/Help/index.rst
+++ b/Help/index.rst
@@ -66,6 +66,7 @@
    /manual/cmake-modules.7
    /manual/cmake-packages.7
    /manual/cmake-policies.7
+   /manual/cmake-presets.7
    /manual/cmake-properties.7
    /manual/cmake-qt.7
    /manual/cmake-server.7
diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst
index 0392325..fa10f66 100644
--- a/Help/manual/cmake-policies.7.rst
+++ b/Help/manual/cmake-policies.7.rst
@@ -60,7 +60,7 @@
    CMP0114: ExternalProject step targets fully adopt their steps. </policy/CMP0114>
    CMP0113: Makefile generators do not repeat custom commands from target dependencies. </policy/CMP0113>
    CMP0112: Target file component generator expressions do not add target dependencies. </policy/CMP0112>
-   CMP0111: An imported target with a missing location fails during generation. </policy/CMP0111>
+   CMP0111: An imported target missing its location property fails during generation. </policy/CMP0111>
    CMP0110: add_test() supports arbitrary characters in test names. </policy/CMP0110>
    CMP0109: find_program() requires permission to execute but not to read. </policy/CMP0109>
 
diff --git a/Help/manual/cmake-presets.7.rst b/Help/manual/cmake-presets.7.rst
new file mode 100644
index 0000000..62c4b7c
--- /dev/null
+++ b/Help/manual/cmake-presets.7.rst
@@ -0,0 +1,368 @@
+.. cmake-manual-description: CMakePresets.json
+
+cmake-presets(7)
+****************
+
+.. only:: html
+
+   .. contents::
+
+Introduction
+============
+
+One problem that CMake users often face is sharing settings with other people
+for common ways to configure a project. This may be done to support CI builds,
+or for users who frequently use the same build. CMake supports two files,
+``CMakePresets.json`` and ``CMakeUserPresets.json``, that allow users to
+specify common configure options and share them with others.
+
+``CMakePresets.json`` and ``CMakeUserPresets.json`` live in the project's root
+directory. They both have exactly the same format, and both are optional
+(though at least one must be present if ``--preset`` is specified.)
+``CMakePresets.json`` is meant to save project-wide builds, while
+``CMakeUserPresets.json`` is meant for developers to save their own local
+builds. ``CMakePresets.json`` may be checked into a version control system, and
+``CMakeUserPresets.json`` should NOT be checked in. For example, if a project
+is using Git, ``CMakePresets.json`` may be tracked, and
+``CMakeUserPresets.json`` should be added to the ``.gitignore``.
+
+Format
+======
+
+  The files are a JSON document with an object as the root:
+
+  .. literalinclude:: presets/example.json
+    :language: json
+
+  The root object recognizes the following fields:
+
+  ``version``
+
+    A required integer representing the version of the JSON schema. Currently,
+    the only supported version is 1.
+
+  ``cmakeMinimumRequired``
+
+    An optional object representing the minimum version of CMake needed to
+    build this project. This object consists of the following fields:
+
+    ``major``
+
+      An optional integer representing the major version.
+
+    ``minor``
+
+      An optional integer representing the minor version.
+
+    ``patch``
+
+      An optional integer representing the patch version.
+
+  ``vendor``
+
+    An optional map containing vendor-specific information. CMake does not
+    interpret the contents of this field except to verify that it is a map if
+    it does exist. However, the keys should be a vendor-specific domain name
+    followed by a ``/``-separated path. For example, the Example IDE 1.0 could
+    use ``example.com/ExampleIDE/1.0``. The value of each field can be anything
+    desired by the vendor, though will typically be a map.
+
+  ``configurePresets``
+
+    An optional array of configure preset objects. Each preset may contain the
+    following fields:
+
+    ``name``
+
+      A required string representing the machine-friendly name of the preset.
+      This identifier is used in the ``--preset`` argument. There must not be
+      two presets in the union of ``CMakePresets.json`` and
+      ``CMakeUserPresets.json`` in the same directory with the same name.
+
+    ``hidden``
+
+      An optional boolean specifying whether or not a preset should be hidden.
+      If a preset is hidden, it cannot be used in the ``--preset=`` argument,
+      will not show up in the :manual:`CMake GUI <cmake-gui(1)>`, and does not
+      have to have a valid ``generator`` or ``binaryDir``, even from
+      inheritance. ``hidden`` presets are intended to be used as a base for
+      other presets to inherit via the ``inherits`` field.
+
+    ``inherits``
+
+      An optional array of strings representing the names of presets to inherit
+      from. The preset will inherit all of the fields from the ``inherits``
+      presets by default (except ``name``, ``hidden``, ``inherits``,
+      ``description``, and ``longDescription``), but can override them as
+      desired. If multiple ``inherits`` presets provide conflicting values for
+      the same field, the earlier preset in the ``inherits`` list will be
+      preferred. Presets in ``CMakePresets.json`` may not inherit from presets
+      in ``CMakeUserPresets.json``.
+
+      This field can also be a string, which is equivalent to an array
+      containing one string.
+
+    ``vendor``
+
+      An optional map containing vendor-specific information. CMake does not
+      interpret the contents of this field except to verify that it is a map
+      if it does exist. However, it should follow the same conventions as the
+      root-level ``vendor`` field. If vendors use their own per-preset
+      ``vendor`` field, they should implement inheritance in a sensible manner
+      when appropriate.
+
+    ``displayName``
+
+      An optional string with a human-friendly name of the preset.
+
+    ``description``
+
+      An optional string with a human-friendly description of the preset.
+
+    ``generator``
+
+      An optional string representing the generator to use for the preset. If
+      ``generator`` is not specified, it must be inherited from the
+      ``inherits`` preset (unless this preset is ``hidden``).
+
+      Note that for Visual Studio generators, unlike in the command line ``-G``
+      argument, you cannot include the platform name in the generator name. Use
+      the ``architecture`` field instead.
+
+    ``architecture``
+    ``toolset``
+
+      Optional fields representing the platform and toolset, respectively, for
+      generators that support them. Each may be either a string or an object
+      with the following fields:
+
+      ``value``
+
+        An optional string representing the value.
+
+      ``strategy``
+
+        An optional string telling CMake how to handle the ``architecture`` or
+        ``toolset`` field. Valid values are:
+
+        ``"set"``
+
+          Set the respective value. This will result in an error for generators
+          that do not support the respective field.
+
+        ``"external"``
+
+          Do not set the value, even if the generator supports it. This is
+          useful if, for example, a preset uses the Ninja generator, and an IDE
+          knows how to set up the Visual C++ environment from the
+          ``architecture`` and ``toolset`` fields. In that case, CMake will
+          ignore the field, but the IDE can use them to set up the environment
+          before invoking CMake.
+
+    ``binaryDir``
+
+      An optional string representing the path to the output binary directory.
+      This field supports macro expansion. If a relative path is specified, it
+      is calculated relative to the source directory. If ``binaryDir`` is not
+      specified, it must be inherited from the ``inherits`` preset (unless this
+      preset is ``hidden``).
+
+    ``cmakeExecutable``
+
+      An optional string representing the path to the CMake executable to use
+      for this preset. This is reserved for use by IDEs, and is not used by
+      CMake itself. IDEs that use this field should expand any macros in it.
+
+    ``cacheVariables``
+
+      An optional map of cache variables. The key is the variable name (which
+      may not be an empty string), and the value is either ``null``, a boolean
+      (which is equivalent to a value of ``"TRUE"`` or ``"FALSE"`` and a type
+      of ``BOOL``), a string representing the value of the variable (which
+      supports macro expansion), or an object with the following fields:
+
+      ``type``
+
+        An optional string representing the type of the variable.
+
+      ``value``
+
+        A required string or boolean representing the value of the variable.
+        A boolean is equivalent to ``"TRUE"`` or ``"FALSE"``. This field
+        supports macro expansion.
+
+      Cache variables are inherited through the ``inherits`` field, and the
+      preset's variables will be the union of its own ``cacheVariables`` and
+      the ``cacheVariables`` from all its parents. If multiple presets in this
+      union define the same variable, the standard rules of ``inherits`` are
+      applied. Setting a variable to ``null`` causes it to not be set, even if
+      a value was inherited from another preset.
+
+    ``environment``
+
+      An optional map of environment variables. The key is the variable name
+      (which may not be an empty string), and the value is either ``null`` or
+      a string representing the value of the variable. Each variable is set
+      regardless of whether or not a value was given to it by the process's
+      environment. This field supports macro expansion, and environment
+      variables in this map may reference each other, and may be listed in any
+      order, as long as such references do not cause a cycle (for example,
+      if ``ENV_1`` is ``$env{ENV_2}``, ``ENV_2`` may not be ``$env{ENV_1}``.)
+
+      Environment variables are inherited through the ``inherits`` field, and
+      the preset's environment will be the union of its own ``environment`` and
+      the ``environment`` from all its parents. If multiple presets in this
+      union define the same variable, the standard rules of ``inherits`` are
+      applied. Setting a variable to ``null`` causes it to not be set, even if
+      a value was inherited from another preset.
+
+    ``warnings``
+
+      An optional object specifying the warnings to enable. The object may
+      contain the following fields:
+
+      ``dev``
+
+        An optional boolean. Equivalent to passing ``-Wdev`` or ``-Wno-dev``
+        on the command line. This may not be set to ``false`` if ``errors.dev``
+        is set to ``true``.
+
+      ``deprecated``
+
+        An optional boolean. Equivalent to passing ``-Wdeprecated`` or
+        ``-Wno-deprecated`` on the command line. This may not be set to
+        ``false`` if ``errors.deprecated`` is set to ``true``.
+
+      ``uninitialized``
+
+        An optional boolean. Setting this to ``true`` is equivalent to passing
+        ``--warn-uninitialized`` on the command line.
+
+      ``unusedCli``
+
+        An optional boolean. Setting this to ``false`` is equivalent to passing
+        ``--no-warn-unused-cli`` on the command line.
+
+      ``systemVars``
+
+        An optional boolean. Setting this to ``true`` is equivalent to passing
+        ``--check-system-vars`` on the command line.
+
+    ``errors``
+
+      An optional object specifying the errors to enable. The object may
+      contain the following fields:
+
+      ``dev``
+
+        An optional boolean. Equivalent to passing ``-Werror=dev`` or
+        ``-Wno-error=dev`` on the command line. This may not be set to ``true``
+        if ``warnings.dev`` is set to ``false``.
+
+      ``deprecated``
+
+        An optional boolean. Equivalent to passing ``-Werror=deprecated`` or
+        ``-Wno-error=deprecated`` on the command line. This may not be set to
+        ``true`` if ``warnings.deprecated`` is set to ``false``.
+
+    ``debug``
+
+      An optional object specifying debug options. The object may contain the
+      following fields:
+
+      ``output``
+
+        An optional boolean. Setting this to ``true`` is equivalent to passing
+        ``--debug-output`` on the command line.
+
+      ``tryCompile``
+
+        An optional boolean. Setting this to ``true`` is equivalent to passing
+        ``--debug-trycompile`` on the command line.
+
+      ``find``
+
+        An optional boolean. Setting this to ``true`` is equivalent to passing
+        ``--debug-find`` on the command line.
+
+  As mentioned above, some fields support macro expansion. Macros are
+  recognized in the form ``$<macro-namespace>{<macro-name>}``. All macros are
+  evaluated in the context of the preset being used, even if the macro is in a
+  field that was inherited from another preset. For example, if the ``Base``
+  preset sets variable ``PRESET_NAME`` to ``${presetName}``, and the
+  ``Derived`` preset inherits from ``Base``, ``PRESET_NAME`` will be set to
+  ``Derived``.
+
+  It is an error to not put a closing brace at the end of a macro name. For
+  example, ``${sourceDir`` is invalid. A dollar sign (``$``) followed by
+  anything other than a left curly brace (``{``) with a possible namespace is
+  interpreted as a literal dollar sign.
+
+  Recognized macros include:
+
+  ``${sourceDir}``
+
+    Path to the project source directory.
+
+  ``${sourceParentDir}``
+
+    Path to the project source directory's parent directory.
+
+  ``${sourceDirName}``
+
+    The last filename component of ``${sourceDir}``. For example, if
+    ``${sourceDir}`` is ``/path/to/source``, this would be ``source``.
+
+  ``${presetName}``
+
+    Name specified in the preset's ``name`` field.
+
+  ``${generator}``
+
+    Generator specified in the preset's ``generator`` field.
+
+  ``${dollar}``
+
+    A literal dollar sign (``$``).
+
+  ``$env{<variable-name>}``
+
+    Environment variable with name ``<variable-name>``. The variable name may
+    not be an empty string. If the variable is defined in the ``environment``
+    field, that value is used instead of the value from the parent environment.
+    If the environment variable is not defined, this evaluates as an empty
+    string.
+
+    Note that while Windows environment variable names are case-insensitive,
+    variable names within a preset are still case-sensitive. This may lead to
+    unexpected results when using inconsistent casing. For best results, keep
+    the casing of environment variable names consistent.
+
+  ``$penv{<variable-name>}``
+
+    Similar to ``$env{<variable-name>}``, except that the value only comes from
+    the parent environment, and never from the ``environment`` field. This
+    allows you to prepend or append values to existing environment variables.
+    For example, setting ``PATH`` to ``/path/to/ninja/bin:$penv{PATH}`` will
+    prepend ``/path/to/ninja/bin`` to the ``PATH`` environment variable. This
+    is needed because ``$env{<variable-name>}`` does not allow circular
+    references.
+
+  ``$vendor{<macro-name>}``
+
+    An extension point for vendors to insert their own macros. CMake will not
+    be able to use presets which have a ``$vendor{<macro-name>}`` macro, and
+    effectively ignores such presets. However, it will still be able to use
+    other presets from the same file.
+
+    CMake does not make any attempt to interpret ``$vendor{<macro-name>}``
+    macros. However, to avoid name collisions, IDE vendors should prefix
+    ``<macro-name>`` with a very short (preferably <= 4 characters) vendor
+    identifier prefix, followed by a ``.``, followed by the macro name. For
+    example, the Example IDE could have ``$vendor{xide.ideInstallDir}``.
+
+Schema
+======
+
+:download:`This file </manual/presets/schema.json>` provides a machine-readable
+JSON schema for the ``CMakePresets.json`` format.
diff --git a/Help/manual/cmake.1.rst b/Help/manual/cmake.1.rst
index b345db0..5452c79 100644
--- a/Help/manual/cmake.1.rst
+++ b/Help/manual/cmake.1.rst
@@ -150,21 +150,14 @@
     $ cmake -S src -B build
 
 ``cmake [<options>] -S <path-to-source> --preset=<preset-name>``
-  Uses ``<path-to-source>`` as the source tree and reads a preset from
+  Uses ``<path-to-source>`` as the source tree and reads a
+  :manual:`preset <cmake-presets(7)>` from
   ``<path-to-source>/CMakePresets.json`` and
   ``<path-to-source>/CMakeUserPresets.json``. The preset specifies the
   generator and the build directory, and optionally a list of variables and
   other arguments to pass to CMake. The :manual:`CMake GUI <cmake-gui(1)>` can
-  also recognize ``CMakePresets.json`` and ``CMakeUserPresets.json`` files.
-
-  ``CMakePresets.json`` and ``CMakeUserPresets.json`` have exactly the same
-  format, and both are optional (though at least one must be present if
-  ``--preset`` is specified.) ``CMakePresets.json`` is meant to save
-  project-wide builds, while ``CMakeUserPresets.json`` is meant for developers
-  to save their own local builds. ``CMakePresets.json`` may be checked into a
-  version control system, and ``CMakeUserPresets.json`` should NOT be checked
-  in. For example, if a project is using Git, ``CMakePresets.json`` may be
-  tracked, and ``CMakeUserPresets.json`` should be added to the ``.gitignore``.
+  also recognize ``CMakePresets.json`` and ``CMakeUserPresets.json`` files. For
+  full details on these files, see :manual:`cmake-presets(7)`.
 
   The presets are read before all other command line options. The options
   specified by the preset (variables, generator, etc.) can all be overridden by
@@ -172,323 +165,6 @@
   a variable called ``MYVAR`` to ``1``, but the user sets it to ``2`` with a
   ``-D`` argument, the value ``2`` is preferred.
 
-  The files are a JSON document with an object as the root:
-
-  .. literalinclude:: presets/example.json
-    :language: json
-
-  The root object recognizes the following fields:
-
-  ``version``
-
-    A required integer representing the version of the JSON schema. Currently,
-    the only supported version is 1.
-
-  ``cmakeMinimumRequired``
-
-    An optional object representing the minimum version of CMake needed to
-    build this project. This object consists of the following fields:
-
-    ``major``
-
-      An optional integer representing the major version.
-
-    ``minor``
-
-      An optional integer representing the minor version.
-
-    ``patch``
-
-      An optional integer representing the patch version.
-
-  ``vendor``
-
-    An optional map containing vendor-specific information. CMake does not
-    interpret the contents of this field except to verify that it is a map if
-    it does exist. However, the keys should be a vendor-specific domain name
-    followed by a ``/``-separated path. For example, the Example IDE 1.0 could
-    use ``example.com/ExampleIDE/1.0``. The value of each field can be anything
-    desired by the vendor, though will typically be a map. For example:
-
-    .. code-block:: json
-
-      {
-        "version": 1,
-        "vendor": {
-          "example.com/ExampleIDE/1.0": {
-            "autoFormat": true
-          }
-        },
-        "configurePresets": []
-      }
-
-  ``configurePresets``
-
-    An optional array of configure preset objects. Each preset may contain the
-    following fields:
-
-    ``name``
-
-      A required string representing the machine-friendly name of the preset.
-      This identifier is used in the ``--preset`` argument. There must not be
-      two presets in the union of ``CMakePresets.json`` and
-      ``CMakeUserPresets.json`` in the same directory with the same name.
-
-    ``hidden``
-
-      An optional boolean specifying whether or not a preset should be hidden.
-      If a preset is hidden, it cannot be used in the ``--preset=`` argument,
-      will not show up in the :manual:`CMake GUI <cmake-gui(1)>`, and does not
-      have to have a valid ``generator`` or ``binaryDir``, even from
-      inheritance. ``hidden`` presets are intended to be used as a base for
-      other presets to inherit via the ``inherits`` field.
-
-    ``inherits``
-
-      An optional array of strings representing the names of presets to inherit
-      from. The preset will inherit all of the fields from the ``inherits``
-      presets by default (except ``name``, ``hidden``, ``inherits``,
-      ``description``, and ``longDescription``), but can override them as
-      desired. If multiple ``inherits`` presets provide conflicting values for
-      the same field, the earlier preset in the ``inherits`` list will be
-      preferred. Presets in ``CMakePresets.json`` may not inherit from presets
-      in ``CMakeUserPresets.json``.
-
-      This field can also be a string, which is equivalent to an array
-      containing one string.
-
-    ``vendor``
-
-      An optional map containing vendor-specific information. CMake does not
-      interpret the contents of this field except to verify that it is a map
-      if it does exist. However, it should follow the same conventions as the
-      root-level ``vendor`` field. If vendors use their own per-preset
-      ``vendor`` field, they should implement inheritance in a sensible manner
-      when appropriate.
-
-    ``displayName``
-
-      An optional string with a human-friendly name of the preset.
-
-    ``description``
-
-      An optional string with a human-friendly description of the preset.
-
-    ``generator``
-
-      An optional string representing the generator to use for the preset. If
-      ``generator`` is not specified, it must be inherited from the
-      ``inherits`` preset (unless this preset is ``hidden``).
-
-      Note that for Visual Studio generators, unlike in the command line ``-G``
-      argument, you cannot include the platform name in the generator name. Use
-      the ``architecture`` field instead.
-
-    ``architecture``
-
-      An optional string representing the platform name to use for Visual
-      Studio generators.
-
-    ``toolset``
-
-      An optional string representing the toolset name to use for Visual Studio
-      generators.
-
-    ``cmakeGeneratorConfig``
-
-      An optional string telling CMake how to handle the ``architecture`` and
-      ``toolset`` fields. Valid values are:
-
-      ``"default"``
-
-        Set the platform and toolset using the ``architecture`` and ``toolset``
-        fields respectively. On non-Visual Studio generators, this will result
-        in an error if ``architecture`` or ``toolset`` are set.
-
-      ``"ignore"``
-
-        Do not set the platform or toolset at all, even on Visual Studio
-        generators. This is useful if, for example, a preset uses the Ninja
-        generator, and an IDE knows how to set up the Visual C++ environment
-        from the ``architecture`` and ``toolset`` fields. In that case, CMake
-        will ignore ``architecture`` and ``toolset``, but the IDE can use them
-        to set up the environment before invoking CMake.
-
-    ``binaryDir``
-
-      An optional string representing the path to the output binary directory.
-      This field supports macro expansion. If a relative path is specified, it
-      is calculated relative to the source directory. If ``binaryDir`` is not
-      specified, it must be inherited from the ``inherits`` preset (unless this
-      preset is ``hidden``).
-
-    ``cmakeExecutable``
-
-      An optional string representing the path to the CMake executable to use
-      for this preset. This is reserved for use by IDEs, and is not used by
-      CMake itself. IDEs that use this field should expand any macros in it.
-
-    ``cacheVariables``
-
-      An optional map of cache variables. The key is the variable name (which
-      may not be an empty string), and the value is either ``null``, a string
-      representing the value of the variable (which supports macro expansion),
-      or an object with the following fields:
-
-      ``type``
-
-        An optional string representing the type of the variable.
-
-      ``value``
-
-        A required string representing the value of the variable. This field
-        supports macro expansion.
-
-      Cache variables are inherited through the ``inherits`` field, and the
-      preset's variables will be the union of its own ``cacheVariables`` and
-      the ``cacheVariables`` from all its parents. If multiple presets in this
-      union define the same variable, the standard rules of ``inherits`` are
-      applied. Setting a variable to ``null`` causes it to not be set, even if
-      a value was inherited from another preset.
-
-    ``environment``
-
-      An optional map of environment variables. The key is the variable name
-      (which may not be an empty string), and the value is either ``null`` or
-      a string representing the value of the variable. Each variable is set
-      regardless of whether or not a value was given to it by the process's
-      environment. This field supports macro expansion, and environment
-      variables in this map may reference each other, and may be listed in any
-      order, as long as such references do not cause a cycle (for example,
-      if ``ENV_1`` is ``$env{ENV_2}``, ``ENV_2`` may not be ``$env{ENV_1}``.)
-
-      Environment variables are inherited through the ``inherits`` field, and
-      the preset's environment will be the union of its own ``environment`` and
-      the ``environment`` from all its parents. If multiple presets in this
-      union define the same variable, the standard rules of ``inherits`` are
-      applied. Setting a variable to ``null`` causes it to not be set, even if
-      a value was inherited from another preset.
-
-    ``warnings``
-
-      An optional object specifying warnings. The object may contain the
-      following fields:
-
-      ``dev``
-
-        An optional boolean. Equivalent to passing ``-Wdev`` or ``-Wno-dev``
-        on the command line. This may not be set to ``false`` if ``errors.dev``
-        is set to ``true``.
-
-      ``deprecated``
-
-        An optional boolean. Equivalent to passing ``-Wdeprecated`` or
-        ``-Wno-deprecated`` on the command line. This may not be set to
-        ``false`` if ``errors.deprecated`` is set to ``true``.
-
-      ``uninitialized``
-
-        An optional boolean. Setting this to ``true`` is equivalent to passing
-        ``--warn-uninitialized`` on the command line.
-
-      ``unusedVars``
-
-        An optional boolean. Setting this to ``false`` is equivalent to passing
-        ``--no-warn-unused-cli`` on the command line.
-
-      ``systemVars``
-
-        An optional boolean. Setting this to ``true`` is equivalent to passing
-        ``--check-system-vars`` on the command line.
-
-    ``errors``
-
-      An optional object specifying errors. The object may contain the
-      following fields:
-
-      ``dev``
-
-        An optional boolean. Equivalent to passing ``-Werror=dev`` or
-        ``-Wno-error=dev`` on the command line. This may not be set to ``true``
-        if ``warnings.dev`` is set to ``false``.
-
-      ``deprecated``
-
-        An optional boolean. Equivalent to passing ``-Werror=deprecated`` or
-        ``-Wno-error=deprecated`` on the command line. This may not be set to
-        ``true`` if ``warnings.deprecated`` is set to ``false``.
-
-  As mentioned above, some fields support macro expansion. Macros are
-  recognized in the form ``$<macro-namespace>{<macro-name>}``. All macros are
-  evaluated in the context of the preset being used, even if the macro is in a
-  field that was inherited from another preset. For example, if the ``Base``
-  preset sets variable ``PRESET_NAME`` to ``${presetName}``, and the
-  ``Derived`` preset inherits from ``Base``, ``PRESET_NAME`` will be set to
-  ``Derived``.
-
-  It is an error to not put a closing brace at the end of a macro name. For
-  example, ``${sourceDir`` is invalid. A dollar sign (``$``) followed by
-  anything other than a left curly brace (``{``) with a possible namespace is
-  interpreted as a literal dollar sign.
-
-  Recognized macros include:
-
-  ``${sourceDir}``
-
-    Path to the project source directory.
-
-  ``${sourceParentDir}``
-
-    Path to the project source directory's parent directory.
-
-  ``${presetName}``
-
-    Name specified in the preset's ``name`` field.
-
-  ``${generator}``
-
-    Generator specified in the preset's ``generator`` field.
-
-  ``${dollar}``
-
-    A literal dollar sign (``$``).
-
-  ``$env{<variable-name>}``
-
-    Environment variable with name ``<variable-name>``. The variable name may
-    not be an empty string. If the variable is defined in the ``environment``
-    field, that value is used instead of the value from the parent environment.
-    If the environment variable is not defined, this evaluates as an empty
-    string.
-
-    Note that while Windows environment variable names are case-insensitive,
-    variable names within a preset are still case-sensitive. This may lead to
-    unexpected results when using inconsistent casing. For best results, keep
-    the casing of environment variable names consistent.
-
-  ``$penv{<variable-name>}``
-
-    Similar to ``$env{<variable-name>}``, except that the value only comes from
-    the parent environment, and never from the ``environment`` field. This
-    allows you to prepend or append values to existing environment variables.
-    For example, setting ``PATH`` to ``/path/to/ninja/bin:$penv{PATH}`` will
-    prepend ``/path/to/ninja/bin`` to the ``PATH`` environment variable. This
-    is needed because ``$env{<variable-name>}`` does not allow circular
-    references.
-
-  ``$vendor{<macro-name>}``
-
-    An extension point for vendors to insert their own macros. CMake will not
-    be able to use presets which have a ``$vendor{<macro-name>}`` macro, and
-    effectively ignores such presets. However, it will still be able to use
-    other presets from the same file.
-
-    CMake does not make any attempt to interpret ``$vendor{<macro-name>}``
-    macros. However, to avoid name collisions, IDE vendors should prefix
-    ``<macro-name>`` with a very short (preferably <= 4 characters) vendor
-    identifier prefix, followed by a ``.``, followed by the macro name. For
-    example, the Example IDE could have ``$vendor{xide.ideInstallDir}``.
-
 In all cases the ``<options>`` may be zero or more of the `Options`_ below.
 
 After generating a buildsystem one may use the corresponding native
@@ -1156,7 +832,7 @@
 
 To view the presets available for a project, use
 
-.. code-block::shell
+.. code-block:: shell
 
   cmake <source-dir> --list-presets
 
diff --git a/Help/manual/presets/example.json b/Help/manual/presets/example.json
index a299a06..d3b6f4a 100644
--- a/Help/manual/presets/example.json
+++ b/Help/manual/presets/example.json
@@ -13,11 +13,33 @@
       "generator": "Ninja",
       "binaryDir": "${sourceDir}/build/default",
       "cacheVariables": {
-        "MY_CACHE_VARIABLE": {
+        "FIRST_CACHE_VARIABLE": {
           "type": "BOOL",
           "value": "OFF"
+        },
+        "SECOND_CACHE_VARIABLE": "ON"
+      },
+      "environment": {
+        "MY_ENVIRONMENT_VARIABLE": "Test",
+        "PATH": "$env{HOME}/ninja/bin:$penv{PATH}"
+      },
+      "vendor": {
+        "example.com/ExampleIDE/1.0": {
+          "autoFormat": true
         }
       }
+    },
+    {
+      "name": "ninja-multi",
+      "inherits": "default",
+      "displayName": "Ninja Multi-Config",
+      "description": "Default build using Ninja Multi-Config generator",
+      "generator": "Ninja Multi-Config"
     }
-  ]
+  ],
+  "vendor": {
+    "example.com/ExampleIDE/1.0": {
+      "autoFormat": false
+    }
+  }
 }
diff --git a/Help/manual/presets/schema.json b/Help/manual/presets/schema.json
new file mode 100644
index 0000000..57b063e
--- /dev/null
+++ b/Help/manual/presets/schema.json
@@ -0,0 +1,292 @@
+{
+  "$schema": "http://json-schema.org/draft-07/schema#",
+  "type": "object",
+  "description": "The presets specify the generator and the build directory, and optionally a list of variables and other arguments to pass to CMake.",
+  "properties": {
+    "version": {
+      "type": "integer",
+      "description": "A required integer representing the version of the JSON schema. Currently, the only supported version is 1.",
+      "minimum": 1,
+      "maximum": 1
+    },
+    "cmakeMinimumRequired": {
+      "type": "object",
+      "description": "An optional object representing the minimum version of CMake needed to build this project.",
+      "properties": {
+        "major": {
+          "type": "integer",
+          "description": "An optional integer representing the major version."
+        },
+        "minor": {
+          "type": "integer",
+          "description": "An optional integer representing the minor version."
+        },
+        "patch": {
+          "type": "integer",
+          "description": "An optional integer representing the patch version."
+        }
+      },
+      "additionalProperties": false
+    },
+    "vendor": {
+      "type": "object",
+      "description": "An optional map containing vendor-specific information. CMake does not interpret the contents of this field except to verify that it is a map if it does exist. However, the keys should be a vendor-specific domain name followed by a /-separated path. For example, the Example IDE 1.0 could use example.com/ExampleIDE/1.0. The value of each field can be anything desired by the vendor, though will typically be a map.",
+      "properties": {}
+    },
+    "configurePresets": {
+      "type": "array",
+      "description": "An optional array of configure preset objects.",
+      "items": {
+        "type": "object",
+        "description": "A configure preset object.",
+        "properties": {
+          "name": {
+            "type": "string",
+            "description": "A required string representing the machine-friendly name of the preset. This identifier is used in the --preset argument. There must not be two presets in the union of CMakePresets.json and CMakeUserPresets.json in the same directory with the same name.",
+            "minLength": 1
+          },
+          "hidden": {
+            "type": "boolean",
+            "description": "An optional boolean specifying whether or not a preset should be hidden. If a preset is hidden, it cannot be used in the --preset= argument, will not show up in the CMake GUI, and does not have to have a valid generator or binaryDir, even from inheritance. hidden presets are intended to be used as a base for other presets to inherit via the inherits field."
+          },
+          "inherits": {
+            "anyOf": [
+              {
+                "type": "string",
+                "description": "An optional string representing the name of the preset to inherit from.",
+                "minLength": 1
+              },
+              {
+                "type": "array",
+                "description": "An optional array of strings representing the names of presets to inherit from. The preset will inherit all of the fields from the inherits presets by default (except name, hidden, inherits, description, and longDescription), but can override them as desired. If multiple inherits presets provide conflicting values for the same field, the earlier preset in the inherits list will be preferred. Presets in CMakePresets.json may not inherit from presets in CMakeUserPresets.json.",
+                "items": {
+                  "type": "string",
+                  "description": "An optional string representing the name of the preset to inherit from.",
+                  "minLength": 1
+                }
+              }
+            ]
+          },
+          "vendor": {
+            "type": "object",
+            "description": "An optional map containing vendor-specific information. CMake does not interpret the contents of this field except to verify that it is a map if it does exist. However, it should follow the same conventions as the root-level vendor field. If vendors use their own per-preset vendor field, they should implement inheritance in a sensible manner when appropriate.",
+            "properties": {}
+          },
+          "displayName": {
+            "type": "string",
+            "description": "An optional string with a human-friendly name of the preset."
+          },
+          "description": {
+            "type": "string",
+            "description": "An optional string with a human-friendly description of the preset."
+          },
+          "generator": {
+            "type": "string",
+            "description": "An optional string representing the generator to use for the preset. If generator is not specified, it must be inherited from the inherits preset (unless this preset is hidden). Note that for Visual Studio generators, unlike in the command line -G argument, you cannot include the platform name in the generator name. Use the architecture field instead."
+          },
+          "architecture": {
+            "anyOf": [
+              {
+                "type": "string",
+                "description": "An optional string representing the platform for generators that support it."
+              },
+              {
+                "type": "object",
+                "description": "An optional object representing the platform for generators that support it.",
+                "properties": {
+                  "value": {
+                    "type": "string",
+                    "description": "An optional string representing the value."
+                  },
+                  "strategy": {
+                    "type": "string",
+                    "description": "An optional string telling CMake how to handle the field. Valid values are: \"set\" Set the respective value. This will result in an error for generators that do not support the respective field. \"external\" Do not set the value, even if the generator supports it. This is useful if, for example, a preset uses the Ninja generator, and an IDE knows how to set up the Visual C++ environment from the architecture and toolset fields. In that case, CMake will ignore the field, but the IDE can use them to set up the environment before invoking CMake.",
+                    "enum": [
+                      "set",
+                      "external"
+                    ]
+                  }
+                },
+                "additionalProperties": false
+              }
+            ]
+          },
+          "toolset": {
+            "anyOf": [
+              {
+                "type": "string",
+                "description": "An optional string representing the toolset for generators that support it."
+              },
+              {
+                "type": "object",
+                "description": "An optional object representing the toolset for generators that support it.",
+                "properties": {
+                  "value": {
+                    "type": "string",
+                    "description": "An optional string representing the value."
+                  },
+                  "strategy": {
+                    "type": "string",
+                    "description": "An optional string telling CMake how to handle the field. Valid values are: \"set\" Set the respective value. This will result in an error for generators that do not support the respective field. \"external\" Do not set the value, even if the generator supports it. This is useful if, for example, a preset uses the Ninja generator, and an IDE knows how to set up the Visual C++ environment from the architecture and toolset fields. In that case, CMake will ignore the field, but the IDE can use them to set up the environment before invoking CMake.",
+                    "enum": [
+                      "set",
+                      "external"
+                    ]
+                  }
+                },
+                "additionalProperties": false
+              }
+            ]
+          },
+          "binaryDir": {
+            "type": "string",
+            "description": "An optional string representing the path to the output binary directory. This field supports macro expansion. If a relative path is specified, it is calculated relative to the source directory. If binaryDir is not specified, it must be inherited from the inherits preset (unless this preset is hidden)."
+          },
+          "cmakeExecutable": {
+            "type": "string",
+            "description": "An optional string representing the path to the CMake executable to use for this preset. This is reserved for use by IDEs, and is not used by CMake itself. IDEs that use this field should expand any macros in it."
+          },
+          "cacheVariables": {
+            "type": "object",
+            "description": "An optional map of cache variables. The key is the variable name (which must not be an empty string). Cache variables are inherited through the inherits field, and the preset's variables will be the union of its own cacheVariables and the cacheVariables from all its parents. If multiple presets in this union define the same variable, the standard rules of inherits are applied.",
+            "properties": {},
+            "additionalProperties": {
+              "anyOf": [
+                {
+                  "type": "null",
+                  "description": "Setting a variable to null causes it to not be set, even if a value was inherited from another preset."
+                },
+                {
+                  "type": "boolean",
+                  "description": "A boolean representing the value of the variable. Equivalent to \"TRUE\" or \"FALSE\"."
+                },
+                {
+                  "type": "string",
+                  "description": "A string representing the value of the variable (which supports macro expansion)."
+                },
+                {
+                  "type": "object",
+                  "description": "An object representing the type and value of the variable.",
+                  "properties": {
+                    "type": {
+                      "type": "string",
+                      "description": "An optional string representing the type of the variable. It should be BOOL, FILEPATH, PATH, STRING, or INTERNAL."
+                    },
+                    "value": {
+                      "anyOf": [
+                        {
+                          "type": "boolean",
+                          "description": "A required boolean representing the value of the variable. Equivalent to \"TRUE\" or \"FALSE\"."
+                        },
+                        {
+                          "type": "string",
+                          "description": "A required string representing the value of the variable. This field supports macro expansion."
+                        }
+                      ]
+                    }
+                  },
+                  "required": [
+                    "value"
+                  ],
+                  "additionalProperties": false
+                }
+              ]
+            },
+            "propertyNames": {
+              "pattern": "^.+$"
+            }
+          },
+          "environment": {
+            "type": "object",
+            "description": "An optional map of environment variables. The key is the variable name (which must not be an empty string). Each variable is set regardless of whether or not a value was given to it by the process's environment. This field supports macro expansion, and environment variables in this map may reference each other, and may be listed in any order, as long as such references do not cause a cycle (for example,if ENV_1 is $env{ENV_2}, ENV_2 may not be $env{ENV_1}.) Environment variables are inherited through the inherits field, and the preset's environment will be the union of its own environment and the environment from all its parents. If multiple presets in this union define the same variable, the standard rules of inherits are applied. Setting a variable to null causes it to not be set, even if a value was inherited from another preset.",
+            "properties": {},
+            "additionalProperties": {
+              "anyOf": [
+                {
+                  "type": "null",
+                  "description": "Setting a variable to null causes it to not be set, even if a value was inherited from another preset."
+                },
+                {
+                  "type": "string",
+                  "description": "A string representing the value of the variable."
+                }
+              ]
+            },
+            "propertyNames": {
+              "pattern": "^.+$"
+            }
+          },
+          "warnings": {
+            "type": "object",
+            "description": "An optional object specifying warnings.",
+            "properties": {
+              "dev": {
+                "type": "boolean",
+                "description": "An optional boolean. Equivalent to passing -Wdev or -Wno-dev on the command line. This may not be set to false if errors.dev is set to true."
+              },
+              "deprecated": {
+                "type": "boolean",
+                "description": "An optional boolean. Equivalent to passing -Wdeprecated or -Wno-deprecated on the command line. This may not be set to false if errors.deprecated is set to true."
+              },
+              "uninitialized": {
+                "type": "boolean",
+                "description": "An optional boolean. Setting this to true is equivalent to passing --warn-uninitialized on the command line."
+              },
+              "unusedCli": {
+                "type": "boolean",
+                "description": "An optional boolean. Setting this to false is equivalent to passing --no-warn-unused-cli on the command line."
+              },
+              "systemVars": {
+                "type": "boolean",
+                "description": "An optional boolean. Setting this to true is equivalent to passing --check-system-vars on the command line."
+              }
+            },
+            "additionalProperties": false
+          },
+          "errors": {
+            "type": "object",
+            "description": "An optional object specifying errors.",
+            "properties": {
+              "dev": {
+                "type": "boolean",
+                "description": "An optional boolean. Equivalent to passing -Werror=dev or -Wno-error=dev on the command line. This may not be set to true if warnings.dev is set to false."
+              },
+              "deprecated": {
+                "type": "boolean",
+                "description": "An optional boolean. Equivalent to passing -Werror=deprecated or -Wno-error=deprecated on the command line. This may not be set to true if warnings.deprecated is set to false."
+              }
+            },
+            "additionalProperties": false
+          },
+          "debug": {
+            "type": "object",
+            "description": "An optional object specifying debug options.",
+            "properties": {
+              "output": {
+                "type": "boolean",
+                "description": "An optional boolean. Setting this to true is equivalent to passing --debug-output on the command line."
+              },
+              "tryCompile": {
+                "type": "boolean",
+                "description": "An optional boolean. Setting this to true is equivalent to passing --debug-trycompile on the command line."
+              },
+              "find": {
+                "type": "boolean",
+                "description": "An optional boolean. Setting this to true is equivalent to passing --debug-find on the command line."
+              }
+            },
+            "additionalProperties": false
+          }
+        },
+        "required": [
+          "name"
+        ],
+        "additionalProperties": false
+      }
+    }
+  },
+  "required": [
+    "version"
+  ],
+  "additionalProperties": false
+}
diff --git a/Help/policy/CMP0111.rst b/Help/policy/CMP0111.rst
index 37e5ad5..e327583 100644
--- a/Help/policy/CMP0111.rst
+++ b/Help/policy/CMP0111.rst
@@ -3,10 +3,17 @@
 
 .. versionadded:: 3.19
 
-An imported target with a missing location fails during generation.
+An imported target missing its location property fails during generation.
 
-Prior to this the location would be generated as ``<TARGET_NAME>-NOTFOUND``,
-which would result in build failures.
+:ref:`Imported Targets` for library files and executables require that
+their location on disk is specified in a target property such as
+:prop_tgt:`IMPORTED_LOCATION`, :prop_tgt:`IMPORTED_IMPLIB`, or a
+per-configuration equivalent.  If a needed location property is not set,
+CMake 3.18 and below generate the string ``<TARGET_NAME>-NOTFOUND`` in
+its place, which results in failures of the corresponding rules at build
+time.  CMake 3.19 and above prefer instead to raise an error during
+generation.  This policy provides compatibility for projects that have
+not been updated to expect the new behavior.
 
 The ``OLD`` behavior of this policy is to generate the location of an imported
 unknown, static or shared library target as ``<TARGET_NAME>-NOTFOUND`` if not
diff --git a/Help/policy/CMP0112.rst b/Help/policy/CMP0112.rst
index 3eab6d2..78a9055 100644
--- a/Help/policy/CMP0112.rst
+++ b/Help/policy/CMP0112.rst
@@ -21,13 +21,13 @@
 
 
 In CMake 3.18 and lower a dependency on the evaluated target of the above
-generator expressions would be always added.  CMake 3.19 and above prefer
+generator expressions would always be added.  CMake 3.19 and above prefer
 to not add this dependency.  This policy provides compatibility for projects
 that have not been updated to expect the new behavior.
 
 The ``OLD`` behavior for this policy is to add a dependency on the evaluated
-target for the the above generator expressions.  The ``NEW`` behavior of
-this policy is to not add a dependency on the evaluated target for the the
+target for the above generator expressions.  The ``NEW`` behavior of
+this policy is to not add a dependency on the evaluated target for the
 above generator expressions.
 
 This policy was introduced in CMake version 3.19.  Unlike many policies,
diff --git a/Help/policy/CMP0114.rst b/Help/policy/CMP0114.rst
index 1bc1216..ae48478 100644
--- a/Help/policy/CMP0114.rst
+++ b/Help/policy/CMP0114.rst
@@ -47,7 +47,7 @@
   * The ``download``, ``update``, and ``patch`` steps are independent.
   * The ``configure``, ``build``, ``test``, and ``install`` steps are not.
 
-  For custom steps, the :command:`ExternalProject_Add_Step` command provies
+  For custom steps, the :command:`ExternalProject_Add_Step` command provides
   an ``INDEPENDENT`` option to mark them as independent.  It is an error to
   mark a step as independent if it depends on other steps that are not.  Note
   that this use of the term "independent" refers only to independence from
diff --git a/Help/release/3.19.rst b/Help/release/3.19.rst
index ea68594..6e46452 100644
--- a/Help/release/3.19.rst
+++ b/Help/release/3.19.rst
@@ -14,7 +14,8 @@
 -------
 
 * :manual:`cmake(1)` and :manual:`cmake-gui(1)` now recognize
-  ``CMakePresets.json`` and ``CMakeUserPresets.json`` files.
+  ``CMakePresets.json`` and ``CMakeUserPresets.json`` files (see
+  :manual:`cmake-presets(7)`).
 
 Generators
 ----------
@@ -105,21 +106,22 @@
 * The :command:`file(GENERATE)` command gained a new ``TARGET`` keyword to
   support resolving target-dependent generator expressions.
 
-* The :command:`file` gained sub-command `REAL_PATH` to compute a path with
-  symlinks resolved.
+* The :command:`file` command gained a new ``REAL_PATH`` sub-command to
+  compute a path with symlinks resolved.
 
 * The :command:`find_package` command learned to handle a version range.
 
-* The :command:`separate_arguments` command gained new ``PROGRAM`` option to
-  search program.
+* The :command:`separate_arguments` command gained a new ``PROGRAM`` option.
+  It allows the arguments to be treated as a program invocation and will
+  resolve the executable to a full path if it can be found.
 
-* The :command:`set_property`, :command:`get_property`,
-  and :command:`get_directory_property` commands' ``DIRECTORY``
-  options now accept references to binary directory paths,
-  such as the value of :variable:`CMAKE_CURRENT_BINARY_DIR`.
+* The ``DIRECTORY`` option of the :command:`set_property`,
+  :command:`get_property`, and :command:`get_directory_property` commands
+  now accepts references to binary directory paths, such as the value of
+  :variable:`CMAKE_CURRENT_BINARY_DIR`.
 
-* The :command:`string` command gained set of new ``JSON`` sub commands
-  to provide JSON parsing capabilities.
+* The :command:`string` command gained a set of new ``JSON`` sub commands
+  that provide JSON parsing capabilities.
 
 Variables
 ---------
@@ -134,6 +136,9 @@
   initialize the new :prop_tgt:`OPTIMIZE_DEPENDENCIES` target property and
   avoid unnecessarily building dependencies for a static library.
 
+* The :variable:`CMAKE_PCH_INSTANTIATE_TEMPLATES` variable was added to
+  initialize the new :prop_tgt:`PCH_INSTANTIATE_TEMPLATES` target property.
+
 * The :variable:`CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION_MAXIMUM` variable
   was added to tell the :ref:`Visual Studio Generators` what maximum
   version of the Windows SDK to choose.
@@ -149,8 +154,8 @@
 
 * The :prop_tgt:`PCH_INSTANTIATE_TEMPLATES` target property was added to enable
   template instantiation in the precompiled header. This is enabled by default
-  and offers a roughly 20% compile time improvement. Currently only supported
-  by Clang 11.
+  and may significantly improve compile times. Currently only supported for
+  Clang (version 11 or later).
 
 * The :prop_tgt:`WIN32_EXECUTABLE` target property now supports
   :manual:`generator expressions <cmake-generator-expressions(7)>`.
@@ -175,19 +180,20 @@
   :module:`CheckCXXSourceRuns` to more languages.
   It also supports the ``CUDA`` language.
 
-* :module:`CMakePackageConfigHelpers` module learned to manage version range.
+* The :module:`CMakePackageConfigHelpers` module gained support for version
+  ranges.
 
 * The :module:`FindCUDAToolkit` module gained support for finding CUDA
   toolkits that do not contain ``nvcc``, as well as for finding scattered
   toolkit installations when cross-compiling.
 
 * The :module:`FindPackageHandleStandardArgs` module learned to handle
-  version range. It also gained the ``find_package_check_version()`` command to
-  check the validity of a version against version-related arguments of
+  version ranges. It also gained the ``find_package_check_version()`` command
+  to check the validity of a version against version-related arguments of
   :command:`find_package` command.
 
 * The :module:`FindPython3`, :module:`FindPython2` and :module:`FindPython`
-  modules gained the capability to manage a version range.
+  modules gained the ability to handle a version range.
 
 * The :module:`FindPython3`, :module:`FindPython2` and :module:`FindPython`
   modules provide, respectively, the variable ``Python3_LINK_OPTIONS``,
@@ -195,14 +201,14 @@
 
 * The :module:`FindSDL` module now provides:
 
-  * imported target ``SDL::SDL``,
+  * An imported target ``SDL::SDL``.
 
-  * result variables ``SDL_LIBRARIES`` and ``SDL_INCLUDE_DIRS``,
+  * Result variables ``SDL_LIBRARIES`` and ``SDL_INCLUDE_DIRS``.
 
-  * version variables ``SDL_VERSION``, ``SDL_VERSION_MAJOR``
+  * Version variables ``SDL_VERSION``, ``SDL_VERSION_MAJOR``,
     ``SDL_VERSION_MINOR``, and ``SDL_VERSION_PATCH``.
 
-* :module:`FindSWIG` module gains the capability to manage a version range.
+* The :module:`FindSWIG` module gained the ability to handle a version range.
 
 * The :module:`FindTIFF` module gained a ``CXX`` component to
   find the ``tiffxx`` library containing C++ bindings.
@@ -211,15 +217,17 @@
   target and associated ``Vulkan_GLSLC_EXECUTABLE`` variable which contain
   the path to the GLSL SPIR-V compiler.
 
-* :module:`UseSWIG` module gains new source file properties ``OUTPUT_DIR`` and
-  ``OUTFILE_DIR`` to manage output directories on per source basis.
+* The :module:`UseSWIG` module gained support for new source file properties
+  ``OUTPUT_DIR`` and ``OUTFILE_DIR`` to manage output directories on a
+  per-source basis.
 
 CTest
 -----
 
-* :manual:`ctest(1)` now supports ``compute-sanitizer`` (``cuda-memcheck``) as
-  ``CTEST_MEMORYCHECK_COMMAND``.  The different tools (memcheck, racecheck,
-  synccheck, initcheck) supplied by ``compute-sanitizer`` can be selected by
+* :manual:`ctest(1)` now supports the CUDA ``compute-sanitizer`` checker
+  (previously known as ``cuda-memcheck``) as the ``CTEST_MEMORYCHECK_COMMAND``.
+  The different tools (``memcheck``, ``racecheck``, ``synccheck`` and
+  ``initcheck``) supported by ``compute-sanitizer`` can be selected by
   adding appropriate flags to the ``CTEST_MEMORYCHECK_COMMAND_OPTIONS``
   variable.  The default flags are ``--tool memcheck --leak-check full``.
 
@@ -293,7 +301,7 @@
 * The :command:`find_program` command now requires permission to execute
   but not to read the file found.  See policy :policy:`CMP0109`.
 
-* An imported target with a missing location now fails during generation
+* An imported target missing its location property fails during generation
   if the location is used.  See policy :policy:`CMP0111`.
 
 * The following target-based generator expressions that query for directory or
diff --git a/Modules/CMakePackageConfigHelpers.cmake b/Modules/CMakePackageConfigHelpers.cmake
index 50d7605..1a7f9cf 100644
--- a/Modules/CMakePackageConfigHelpers.cmake
+++ b/Modules/CMakePackageConfigHelpers.cmake
@@ -161,8 +161,8 @@
 
 .. note:: ``COMPATIBILITY_MODE`` ``AnyNewerVersion`` handles the version range
   if any is specified (see :command:`find_package` command for the details).
-  All other modes are incompatible with version range and will display an
-  author warning if a one is specified.
+  All other modes are incompatible with version ranges and will display an
+  author warning if one is specified.
 
 If ``ARCH_INDEPENDENT`` is given, the installed package version will be
 considered compatible even if it was built for a different architecture than
diff --git a/Modules/CheckCCompilerFlag.cmake b/Modules/CheckCCompilerFlag.cmake
index f835f29..335b437 100644
--- a/Modules/CheckCCompilerFlag.cmake
+++ b/Modules/CheckCCompilerFlag.cmake
@@ -34,8 +34,8 @@
 
 include_guard(GLOBAL)
 include(CheckCSourceCompiles)
-include(CheckCompilerFlag)
+include(Internal/CheckCompilerFlag)
 
 macro (CHECK_C_COMPILER_FLAG _FLAG _RESULT)
-  check_compiler_flag(C "${_FLAG}" ${_RESULT})
+  cmake_check_compiler_flag(C "${_FLAG}" ${_RESULT})
 endmacro ()
diff --git a/Modules/CheckCSourceCompiles.cmake b/Modules/CheckCSourceCompiles.cmake
index 975e653..698a007 100644
--- a/Modules/CheckCSourceCompiles.cmake
+++ b/Modules/CheckCSourceCompiles.cmake
@@ -66,8 +66,8 @@
 #]=======================================================================]
 
 include_guard(GLOBAL)
-include(CheckSourceCompiles)
+include(Internal/CheckSourceCompiles)
 
 macro(CHECK_C_SOURCE_COMPILES SOURCE VAR)
-  check_source_compiles(C "${SOURCE}" ${VAR} ${ARGN})
+  cmake_check_source_compiles(C "${SOURCE}" ${VAR} ${ARGN})
 endmacro()
diff --git a/Modules/CheckCSourceRuns.cmake b/Modules/CheckCSourceRuns.cmake
index 86ad248..258b1a0 100644
--- a/Modules/CheckCSourceRuns.cmake
+++ b/Modules/CheckCSourceRuns.cmake
@@ -65,8 +65,8 @@
 #]=======================================================================]
 
 include_guard(GLOBAL)
-include(CheckSourceRuns)
+include(Internal/CheckSourceRuns)
 
 macro(CHECK_C_SOURCE_RUNS SOURCE VAR)
-  check_source_runs(C "${SOURCE}" ${VAR} ${ARGN})
+  cmake_check_source_runs(C "${SOURCE}" ${VAR} ${ARGN})
 endmacro()
diff --git a/Modules/CheckCXXCompilerFlag.cmake b/Modules/CheckCXXCompilerFlag.cmake
index ce49ae3..3bc3463 100644
--- a/Modules/CheckCXXCompilerFlag.cmake
+++ b/Modules/CheckCXXCompilerFlag.cmake
@@ -34,8 +34,8 @@
 
 include_guard(GLOBAL)
 include(CheckCXXSourceCompiles)
-include(CheckCompilerFlag)
+include(Internal/CheckCompilerFlag)
 
 macro (CHECK_CXX_COMPILER_FLAG _FLAG _RESULT)
-  check_compiler_flag(CXX "${_FLAG}" ${_RESULT})
+  cmake_check_compiler_flag(CXX "${_FLAG}" ${_RESULT})
 endmacro ()
diff --git a/Modules/CheckCXXSourceCompiles.cmake b/Modules/CheckCXXSourceCompiles.cmake
index f7f9d0b..dc209b2 100644
--- a/Modules/CheckCXXSourceCompiles.cmake
+++ b/Modules/CheckCXXSourceCompiles.cmake
@@ -66,8 +66,8 @@
 #]=======================================================================]
 
 include_guard(GLOBAL)
-include(CheckSourceCompiles)
+include(Internal/CheckSourceCompiles)
 
 macro(CHECK_CXX_SOURCE_COMPILES SOURCE VAR)
-  check_source_compiles(CXX "${SOURCE}" ${VAR} ${ARGN})
+  cmake_check_source_compiles(CXX "${SOURCE}" ${VAR} ${ARGN})
 endmacro()
diff --git a/Modules/CheckCXXSourceRuns.cmake b/Modules/CheckCXXSourceRuns.cmake
index 70511ee..246c873 100644
--- a/Modules/CheckCXXSourceRuns.cmake
+++ b/Modules/CheckCXXSourceRuns.cmake
@@ -65,8 +65,8 @@
 #]=======================================================================]
 
 include_guard(GLOBAL)
-include(CheckSourceRuns)
+include(Internal/CheckSourceRuns)
 
 macro(CHECK_CXX_SOURCE_RUNS SOURCE VAR)
-  check_source_runs(CXX "${SOURCE}" ${VAR} ${ARGN})
+  cmake_check_source_runs(CXX "${SOURCE}" ${VAR} ${ARGN})
 endmacro()
diff --git a/Modules/CheckCompilerFlag.cmake b/Modules/CheckCompilerFlag.cmake
index 3ce1b9b..77c07b9 100644
--- a/Modules/CheckCompilerFlag.cmake
+++ b/Modules/CheckCompilerFlag.cmake
@@ -19,7 +19,7 @@
 Stores the result in an internal cache entry named ``<var>``.
 
 This command temporarily sets the ``CMAKE_REQUIRED_DEFINITIONS`` variable
-and calls the ``check_source_compiles(<LANG>`` function from the
+and calls the ``check_source_compiles(<LANG>)`` function from the
 :module:`CheckSourceCompiles` module.  See documentation of that
 module for a listing of variables that can otherwise modify the build.
 
@@ -34,78 +34,8 @@
 #]=======================================================================]
 
 include_guard(GLOBAL)
-include(CheckSourceCompiles)
-include(CMakeCheckCompilerFlagCommonPatterns)
-
-cmake_policy(PUSH)
-cmake_policy(SET CMP0054 NEW) # if() quoted variables not dereferenced
-cmake_policy(SET CMP0057 NEW) # if() supports IN_LIST
+include(Internal/CheckCompilerFlag)
 
 function(CHECK_COMPILER_FLAG _lang _flag _var)
-
-  if(_lang STREQUAL C)
-    set(_lang_src "int main(void) { return 0; }")
-    set(_lang_fail_regex FAIL_REGEX "command[ -]line option .* is valid for .* but not for C")
-  elseif(_lang STREQUAL CXX)
-    set(_lang_src "int main() { return 0; }")
-    set(_lang_fail_regex FAIL_REGEX "command[ -]line option .* is valid for .* but not for C\\+\\+")
-    elseif(_lang STREQUAL CUDA)
-    set(_lang_src "__host__ int main() { return 0; }")
-    set(_lang_fail_regex FAIL_REGEX "command[ -]line option .* is valid for .* but not for C\\+\\+" # Host GNU
-                         FAIL_REGEX "argument unused during compilation: .*") # Clang
-  elseif(_lang STREQUAL Fortran)
-    set(_lang_src "       program test\n       stop\n       end program")
-    set(_lang_fail_regex FAIL_REGEX "command[ -]line option .* is valid for .* but not for Fortran")
-  elseif(_lang STREQUAL OBJC)
-    set(_lang_src [=[
-#ifndef __OBJC__
-#  error "Not an Objective-C compiler"
-#endif
-int main(void) { return 0; }]=])
-    set(_lang_fail_regex FAIL_REGEX "command[ -]line option .* is valid for .* but not for Objective-C" # GNU
-                         FAIL_REGEX "argument unused during compilation: .*") # Clang
-  elseif(_lang STREQUAL OBJCXX)
-    set(_lang_src [=[
-#ifndef __OBJC__
-#  error "Not an Objective-C++ compiler"
-#endif
-int main(void) { return 0; }]=])
-    set(_lang_fail_regex FAIL_REGEX "command[ -]line option .* is valid for .* but not for Objective-C\\+\\+" # GNU
-                         FAIL_REGEX "argument unused during compilation: .*") # Clang
-  elseif(_lang STREQUAL ISPC)
-    set(_lang_src "float func(uniform int32, float a) { return a / 2.25; }")
-  else()
-    message (SEND_ERROR "check_compiler_flag: ${_lang}: unknown language.")
-    return()
-  endif()
-
-  get_property (_supported_languages GLOBAL PROPERTY ENABLED_LANGUAGES)
-  if (NOT _lang IN_LIST _supported_languages)
-    message (SEND_ERROR "check_compiler_flag: ${_lang}: needs to be enabled before use.")
-    return()
-  endif()
-
-  set(CMAKE_REQUIRED_DEFINITIONS ${_flag})
-
-  # Normalize locale during test compilation.
-  set(_locale_vars LC_ALL LC_MESSAGES LANG)
-  foreach(v IN LISTS _locale_vars)
-    set(_locale_vars_saved_${v} "$ENV{${v}}")
-    set(ENV{${v}} C)
-  endforeach()
-
-  check_compiler_flag_common_patterns(_common_patterns)
-  check_source_compiles(${_lang}
-    "${_lang_src}"
-    ${_var}
-    ${_lang_fail_regex}
-    ${_common_patterns}
-    )
-
-  foreach(v IN LISTS _locale_vars)
-    set(ENV{${v}} ${_locale_vars_saved_${v}})
-  endforeach()
-  set(${_var} "${${_var}}" PARENT_SCOPE)
-endfunction ()
-
-cmake_policy(POP)
+  cmake_check_compiler_flag(${_lang} "${_flag}" ${_var})
+endfunction()
diff --git a/Modules/CheckFortranCompilerFlag.cmake b/Modules/CheckFortranCompilerFlag.cmake
index 0f5cf9a..5b1cd02 100644
--- a/Modules/CheckFortranCompilerFlag.cmake
+++ b/Modules/CheckFortranCompilerFlag.cmake
@@ -36,8 +36,8 @@
 
 include_guard(GLOBAL)
 include(CheckFortranSourceCompiles)
-include(CheckCompilerFlag)
+include(Internal/CheckCompilerFlag)
 
 macro (CHECK_FORTRAN_COMPILER_FLAG _FLAG _RESULT)
-  check_compiler_flag(Fortran "${_FLAG}" ${_RESULT})
+  cmake_check_compiler_flag(Fortran "${_FLAG}" ${_RESULT})
 endmacro ()
diff --git a/Modules/CheckFortranSourceCompiles.cmake b/Modules/CheckFortranSourceCompiles.cmake
index 2bcc343..5ede284 100644
--- a/Modules/CheckFortranSourceCompiles.cmake
+++ b/Modules/CheckFortranSourceCompiles.cmake
@@ -87,8 +87,10 @@
 #]=======================================================================]
 
 include_guard(GLOBAL)
-include(CheckSourceCompiles)
+include(Internal/CheckSourceCompiles)
 
 macro(CHECK_Fortran_SOURCE_COMPILES SOURCE VAR)
-  check_source_compiles(Fortran "${SOURCE}" ${VAR} ${ARGN})
+  # Pass the SRC_EXT we used by default historically.
+  # A user-provided SRC_EXT argument in ARGN will override ours.
+  cmake_check_source_compiles(Fortran "${SOURCE}" ${VAR} SRC_EXT "F" ${ARGN})
 endmacro()
diff --git a/Modules/CheckFortranSourceRuns.cmake b/Modules/CheckFortranSourceRuns.cmake
index 29f4a98..28f713f 100644
--- a/Modules/CheckFortranSourceRuns.cmake
+++ b/Modules/CheckFortranSourceRuns.cmake
@@ -83,8 +83,10 @@
 #]=======================================================================]
 
 include_guard(GLOBAL)
-include(CheckSourceRuns)
+include(Internal/CheckSourceRuns)
 
 macro(CHECK_Fortran_SOURCE_RUNS SOURCE VAR)
-  check_source_runs(Fortran "${SOURCE}" ${VAR} ${ARGN})
+  # Pass the SRC_EXT we used by default historically.
+  # A user-provided SRC_EXT argument in ARGN will override ours.
+  cmake_check_source_runs(Fortran "${SOURCE}" ${VAR} SRC_EXT "F90" ${ARGN})
 endmacro()
diff --git a/Modules/CheckLinkerFlag.cmake b/Modules/CheckLinkerFlag.cmake
index f56d365..3c7a828 100644
--- a/Modules/CheckLinkerFlag.cmake
+++ b/Modules/CheckLinkerFlag.cmake
@@ -19,15 +19,12 @@
 a diagnostic.  Stores the result in an internal cache entry named ``<var>``.
 
 This command temporarily sets the ``CMAKE_REQUIRED_LINK_OPTIONS`` variable
-and calls the ``check_<lang>_source_compiles`` macro from the
-``Check<lang>SourceCompiles`` module (:module:`CheckCSourceCompiles`,
-:module:`CheckCSourceCompiles`, :module:`CheckCXXSourceCompiles`,
-:module:`CheckOBJCSourceCompiles`, :module:`CheckOBJCXXSourceCompiles` or
-:module:`CheckFortranSourceCompiles`).  See documentation of these
-modules for a listing of variables that can otherwise modify the build.
+and calls the :command:`check_source_compiles` command from the
+:module:`CheckSourceCompiles` module.  See that module's documentation
+for a listing of variables that can otherwise modify the build.
 
-The underlying implementation rely on :prop_tgt:`LINK_OPTIONS` property to
-check the specified flag. The ``LINKER:`` prefix, as described in
+The underlying implementation relies on the :prop_tgt:`LINK_OPTIONS` property
+to check the specified flag. The ``LINKER:`` prefix, as described in the
 :command:`target_link_options` command, can be used as well.
 
 A positive result from this check indicates only that the compiler did not
diff --git a/Modules/CheckOBJCCompilerFlag.cmake b/Modules/CheckOBJCCompilerFlag.cmake
index df9d724..d8d8741 100644
--- a/Modules/CheckOBJCCompilerFlag.cmake
+++ b/Modules/CheckOBJCCompilerFlag.cmake
@@ -36,8 +36,8 @@
 
 include_guard(GLOBAL)
 include(CheckOBJCSourceCompiles)
-include(CheckCompilerFlag)
+include(Internal/CheckCompilerFlag)
 
 macro (CHECK_OBJC_COMPILER_FLAG _FLAG _RESULT)
-  check_compiler_flag(OBJC "${_FLAG}" ${_RESULT})
+  cmake_check_compiler_flag(OBJC "${_FLAG}" ${_RESULT})
 endmacro ()
diff --git a/Modules/CheckOBJCSourceCompiles.cmake b/Modules/CheckOBJCSourceCompiles.cmake
index aad2bdc..c268ef9 100644
--- a/Modules/CheckOBJCSourceCompiles.cmake
+++ b/Modules/CheckOBJCSourceCompiles.cmake
@@ -68,8 +68,8 @@
 #]=======================================================================]
 
 include_guard(GLOBAL)
-include(CheckSourceCompiles)
+include(Internal/CheckSourceCompiles)
 
 macro(CHECK_OBJC_SOURCE_COMPILES SOURCE VAR)
-  check_source_compiles(OBJC "${SOURCE}" ${VAR} ${ARGN})
+  cmake_check_source_compiles(OBJC "${SOURCE}" ${VAR} ${ARGN})
 endmacro()
diff --git a/Modules/CheckOBJCSourceRuns.cmake b/Modules/CheckOBJCSourceRuns.cmake
index dadab21..9894180 100644
--- a/Modules/CheckOBJCSourceRuns.cmake
+++ b/Modules/CheckOBJCSourceRuns.cmake
@@ -67,8 +67,8 @@
 #]=======================================================================]
 
 include_guard(GLOBAL)
-include(CheckSourceRuns)
+include(Internal/CheckSourceRuns)
 
 macro(CHECK_OBJC_SOURCE_RUNS SOURCE VAR)
-  check_source_runs(OBJC "${SOURCE}" ${VAR} ${ARGN})
+  cmake_check_source_runs(OBJC "${SOURCE}" ${VAR} ${ARGN})
 endmacro()
diff --git a/Modules/CheckOBJCXXCompilerFlag.cmake b/Modules/CheckOBJCXXCompilerFlag.cmake
index 6e01bcc..3f3f8fe 100644
--- a/Modules/CheckOBJCXXCompilerFlag.cmake
+++ b/Modules/CheckOBJCXXCompilerFlag.cmake
@@ -36,8 +36,8 @@
 
 include_guard(GLOBAL)
 include(CheckOBJCXXSourceCompiles)
-include(CheckCompilerFlag)
+include(Internal/CheckCompilerFlag)
 
 macro (CHECK_OBJCXX_COMPILER_FLAG _FLAG _RESULT)
-  check_compiler_flag(OBJCXX "${_FLAG}" ${_RESULT})
+  cmake_check_compiler_flag(OBJCXX "${_FLAG}" ${_RESULT})
 endmacro ()
diff --git a/Modules/CheckOBJCXXSourceCompiles.cmake b/Modules/CheckOBJCXXSourceCompiles.cmake
index 37dabfe..1186934 100644
--- a/Modules/CheckOBJCXXSourceCompiles.cmake
+++ b/Modules/CheckOBJCXXSourceCompiles.cmake
@@ -68,8 +68,8 @@
 #]=======================================================================]
 
 include_guard(GLOBAL)
-include(CheckSourceCompiles)
+include(Internal/CheckSourceCompiles)
 
 macro(CHECK_OBJCXX_SOURCE_COMPILES SOURCE VAR)
-  check_source_compiles(OBJCXX "${SOURCE}" ${VAR} ${ARGN})
+  cmake_check_source_compiles(OBJCXX "${SOURCE}" ${VAR} ${ARGN})
 endmacro()
diff --git a/Modules/CheckOBJCXXSourceRuns.cmake b/Modules/CheckOBJCXXSourceRuns.cmake
index 200e799..43d514f 100644
--- a/Modules/CheckOBJCXXSourceRuns.cmake
+++ b/Modules/CheckOBJCXXSourceRuns.cmake
@@ -67,8 +67,8 @@
 #]=======================================================================]
 
 include_guard(GLOBAL)
-include(CheckSourceRuns)
+include(Internal/CheckSourceRuns)
 
 macro(CHECK_OBJCXX_SOURCE_RUNS SOURCE VAR)
-  check_source_runs(OBJCXX "${SOURCE}" ${VAR} ${ARGN})
+  cmake_check_source_runs(OBJCXX "${SOURCE}" ${VAR} ${ARGN})
 endmacro()
diff --git a/Modules/CheckSourceCompiles.cmake b/Modules/CheckSourceCompiles.cmake
index 08fc153..ad74c3c 100644
--- a/Modules/CheckSourceCompiles.cmake
+++ b/Modules/CheckSourceCompiles.cmake
@@ -75,124 +75,8 @@
 
 
 include_guard(GLOBAL)
-
-cmake_policy(PUSH)
-cmake_policy(SET CMP0054 NEW) # if() quoted variables not dereferenced
-cmake_policy(SET CMP0057 NEW) # if() supports IN_LIST
+include(Internal/CheckSourceCompiles)
 
 function(CHECK_SOURCE_COMPILES _lang _source _var)
-  if(NOT DEFINED "${_var}")
-
-    if(_lang STREQUAL C)
-      set(_lang_textual "C")
-      set(_lang_ext "c")
-    elseif(_lang STREQUAL CXX)
-      set(_lang_textual "C++")
-      set(_lang_ext "cxx")
-    elseif(_lang STREQUAL CUDA)
-      set(_lang_textual "CUDA")
-      set(_lang_ext "cu")
-    elseif(_lang STREQUAL Fortran)
-      set(_lang_textual "Fortran")
-      set(_lang_ext "F")
-    elseif(_lang STREQUAL ISPC)
-      set(_lang_textual "ISPC")
-      set(_lang_ext "ispc")
-    elseif(_lang STREQUAL OBJC)
-      set(_lang_textual "Objective-C")
-      set(_lang_ext "m")
-    elseif(_lang STREQUAL OBJCXX)
-      set(_lang_textual "Objective-C++")
-      set(_lang_ext "mm")
-    else()
-      message (SEND_ERROR "check_source_compiles: ${_lang}: unknown language.")
-      return()
-    endif()
-
-    get_property (_supported_languages GLOBAL PROPERTY ENABLED_LANGUAGES)
-    if (NOT _lang IN_LIST _supported_languages)
-      message (SEND_ERROR "check_source_compiles: ${_lang}: needs to be enabled before use.")
-      return()
-    endif()
-
-    set(_FAIL_REGEX)
-    set(_SRC_EXT)
-    set(_key)
-    foreach(arg ${ARGN})
-      if("${arg}" MATCHES "^(FAIL_REGEX|SRC_EXT)$")
-        set(_key "${arg}")
-      elseif(_key)
-        list(APPEND _${_key} "${arg}")
-      else()
-        message(FATAL_ERROR "Unknown argument:\n  ${arg}\n")
-      endif()
-    endforeach()
-
-    if(NOT _SRC_EXT)
-      set(_SRC_EXT ${_lang_ext})
-    endif()
-
-    if(CMAKE_REQUIRED_LINK_OPTIONS)
-      set(CHECK_${LANG}_SOURCE_COMPILES_ADD_LINK_OPTIONS
-        LINK_OPTIONS ${CMAKE_REQUIRED_LINK_OPTIONS})
-    else()
-      set(CHECK_${LANG}_SOURCE_COMPILES_ADD_LINK_OPTIONS)
-    endif()
-    if(CMAKE_REQUIRED_LIBRARIES)
-      set(CHECK_${LANG}_SOURCE_COMPILES_ADD_LIBRARIES
-        LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
-    else()
-      set(CHECK_${LANG}_SOURCE_COMPILES_ADD_LIBRARIES)
-    endif()
-    if(CMAKE_REQUIRED_INCLUDES)
-      set(CHECK_${LANG}_SOURCE_COMPILES_ADD_INCLUDES
-        "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}")
-    else()
-      set(CHECK_${LANG}_SOURCE_COMPILES_ADD_INCLUDES)
-    endif()
-    file(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.${_SRC_EXT}"
-      "${_source}\n")
-
-    if(NOT CMAKE_REQUIRED_QUIET)
-      message(CHECK_START "Performing Test ${_var}")
-    endif()
-    try_compile(${_var}
-      ${CMAKE_BINARY_DIR}
-      ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.${_SRC_EXT}
-      COMPILE_DEFINITIONS -D${_var} ${CMAKE_REQUIRED_DEFINITIONS}
-      ${CHECK_${LANG}_SOURCE_COMPILES_ADD_LINK_OPTIONS}
-      ${CHECK_${LANG}_SOURCE_COMPILES_ADD_LIBRARIES}
-      CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${CMAKE_REQUIRED_FLAGS}
-      "${CHECK_${LANG}_SOURCE_COMPILES_ADD_INCLUDES}"
-      OUTPUT_VARIABLE OUTPUT)
-
-    foreach(_regex ${_FAIL_REGEX})
-      if("${OUTPUT}" MATCHES "${_regex}")
-        set(${_var} 0)
-      endif()
-    endforeach()
-
-    if(${_var})
-      set(${_var} 1 CACHE INTERNAL "Test ${_var}")
-      if(NOT CMAKE_REQUIRED_QUIET)
-        message(CHECK_PASS "Success")
-      endif()
-      file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
-        "Performing ${_lang_textual} SOURCE FILE Test ${_var} succeeded with the following output:\n"
-        "${OUTPUT}\n"
-        "Source file was:\n${_source}\n")
-    else()
-      if(NOT CMAKE_REQUIRED_QUIET)
-        message(CHECK_FAIL "Failed")
-      endif()
-      set(${_var} "" CACHE INTERNAL "Test ${_var}")
-      file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
-        "Performing ${_lang_textual} SOURCE FILE Test ${_var} failed with the following output:\n"
-        "${OUTPUT}\n"
-        "Source file was:\n${_source}\n")
-    endif()
-  endif()
-
+  cmake_check_source_compiles(${_lang} "${_source}" ${_var} ${ARGN})
 endfunction()
-
-cmake_policy(POP)
diff --git a/Modules/CheckSourceRuns.cmake b/Modules/CheckSourceRuns.cmake
index 20f3e1e..8f1cf01 100644
--- a/Modules/CheckSourceRuns.cmake
+++ b/Modules/CheckSourceRuns.cmake
@@ -73,133 +73,8 @@
 #]=======================================================================]
 
 include_guard(GLOBAL)
-
-cmake_policy(PUSH)
-cmake_policy(SET CMP0054 NEW) # if() quoted variables not dereferenced
-cmake_policy(SET CMP0057 NEW) # if() supports IN_LIST
+include(Internal/CheckSourceRuns)
 
 function(CHECK_SOURCE_RUNS _lang _source _var)
-  if(NOT DEFINED "${_var}")
-
-    if(_lang STREQUAL C)
-      set(_lang_textual "C")
-      set(_lang_ext "c")
-    elseif(_lang STREQUAL CXX)
-      set(_lang_textual "C++")
-      set(_lang_ext "cxx")
-    elseif(_lang STREQUAL CUDA)
-      set(_lang_textual "CUDA")
-      set(_lang_ext "cu")
-    elseif(_lang STREQUAL Fortran)
-      set(_lang_textual "Fortran")
-      set(_lang_ext "F")
-    elseif(_lang STREQUAL OBJC)
-      set(_lang_textual "Objective-C")
-      set(_lang_ext "m")
-    elseif(_lang STREQUAL OBJCXX)
-      set(_lang_textual "Objective-C++")
-      set(_lang_ext "mm")
-    else()
-      message (SEND_ERROR "check_source_runs: ${_lang}: unknown language.")
-      return()
-    endif()
-
-    get_property (_supported_languages GLOBAL PROPERTY ENABLED_LANGUAGES)
-    if (NOT _lang IN_LIST _supported_languages)
-      message (SEND_ERROR "check_source_runs: ${_lang}: needs to be enabled before use.")
-      return()
-    endif()
-
-    set(_FAIL_REGEX)
-    set(_SRC_EXT)
-    set(_key)
-    foreach(arg ${ARGN})
-      if("${arg}" MATCHES "^(SRC_EXT)$")
-        set(_key "${arg}")
-      elseif(_key)
-        list(APPEND _${_key} "${arg}")
-      else()
-        message(FATAL_ERROR "Unknown argument:\n  ${arg}\n")
-      endif()
-    endforeach()
-
-    if(NOT _SRC_EXT)
-      set(_SRC_EXT ${_lang_ext})
-    endif()
-
-    if(CMAKE_REQUIRED_LINK_OPTIONS)
-      set(CHECK_${_lang}_SOURCE_COMPILES_ADD_LINK_OPTIONS
-        LINK_OPTIONS ${CMAKE_REQUIRED_LINK_OPTIONS})
-    else()
-      set(CHECK_${_lang}_SOURCE_COMPILES_ADD_LINK_OPTIONS)
-    endif()
-    if(CMAKE_REQUIRED_LIBRARIES)
-      set(CHECK_${_lang}_SOURCE_COMPILES_ADD_LIBRARIES
-        LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
-    else()
-      set(CHECK_${_lang}_SOURCE_COMPILES_ADD_LIBRARIES)
-    endif()
-    if(CMAKE_REQUIRED_INCLUDES)
-      set(CHECK_${_lang}_SOURCE_COMPILES_ADD_INCLUDES
-        "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}")
-    else()
-      set(CHECK_${_lang}_SOURCE_COMPILES_ADD_INCLUDES)
-    endif()
-    file(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.${_SRC_EXT}"
-      "${_source}\n")
-
-    if(NOT CMAKE_REQUIRED_QUIET)
-      message(CHECK_START "Performing Test ${_var}")
-    endif()
-    try_run(${_var}_EXITCODE ${_var}_COMPILED
-      ${CMAKE_BINARY_DIR}
-      ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.${_SRC_EXT}
-      COMPILE_DEFINITIONS -D${_var} ${CMAKE_REQUIRED_DEFINITIONS}
-      ${CHECK_${_lang}_SOURCE_COMPILES_ADD_LINK_OPTIONS}
-      ${CHECK_${_lang}_SOURCE_COMPILES_ADD_LIBRARIES}
-      CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${CMAKE_REQUIRED_FLAGS}
-      -DCMAKE_SKIP_RPATH:BOOL=${CMAKE_SKIP_RPATH}
-      "${CHECK_${_lang}_SOURCE_COMPILES_ADD_INCLUDES}"
-      COMPILE_OUTPUT_VARIABLE OUTPUT
-      RUN_OUTPUT_VARIABLE RUN_OUTPUT)
-    # if it did not compile make the return value fail code of 1
-    if(NOT ${_var}_COMPILED)
-      set(${_var}_EXITCODE 1)
-      set(${_var}_EXITCODE 1 PARENT_SCOPE)
-    endif()
-    # if the return value was 0 then it worked
-    if("${${_var}_EXITCODE}" EQUAL 0)
-      set(${_var} 1 CACHE INTERNAL "Test ${_var}")
-      if(NOT CMAKE_REQUIRED_QUIET)
-        message(CHECK_PASS "Success")
-      endif()
-      file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
-        "Performing ${_lang_textual} SOURCE FILE Test ${_var} succeeded with the following compile output:\n"
-        "${OUTPUT}\n"
-        "...and run output:\n"
-        "${RUN_OUTPUT}\n"
-        "Return value: ${${_var}}\n"
-        "Source file was:\n${_source}\n")
-    else()
-      if(CMAKE_CROSSCOMPILING AND "${${_var}_EXITCODE}" MATCHES  "FAILED_TO_RUN")
-        set(${_var} "${${_var}_EXITCODE}" PARENT_SCOPE)
-      else()
-        set(${_var} "" CACHE INTERNAL "Test ${_var}")
-      endif()
-
-      if(NOT CMAKE_REQUIRED_QUIET)
-        message(CHECK_FAIL "Failed")
-      endif()
-      file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
-        "Performing ${_lang_textual} SOURCE FILE Test ${_var} failed with the following compile output:\n"
-        "${OUTPUT}\n"
-        "...and run output:\n"
-        "${RUN_OUTPUT}\n"
-        "Return value: ${${_var}_EXITCODE}\n"
-        "Source file was:\n${_source}\n")
-
-    endif()
-  endif()
+  cmake_check_source_runs(${_lang} "${_source}" ${_var} ${ARGN})
 endfunction()
-
-cmake_policy(POP)
diff --git a/Modules/Compiler/IAR.cmake b/Modules/Compiler/IAR.cmake
index 296e2fd..f3938a9 100644
--- a/Modules/Compiler/IAR.cmake
+++ b/Modules/Compiler/IAR.cmake
@@ -42,6 +42,7 @@
 
 macro(__compiler_iar_ilink lang)
   set(CMAKE_EXECUTABLE_SUFFIX ".elf")
+  set(CMAKE_${lang}_OUTPUT_EXTENSION ".o")
   if (${lang} STREQUAL "C" OR ${lang} STREQUAL "CXX")
     set(CMAKE_${lang}_COMPILE_OBJECT             "<CMAKE_${lang}_COMPILER> ${CMAKE_IAR_${lang}_FLAG} --silent <SOURCE> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT>")
     set(CMAKE_${lang}_CREATE_PREPROCESSED_SOURCE "<CMAKE_${lang}_COMPILER> ${CMAKE_IAR_${lang}_FLAG} --silent <SOURCE> <DEFINES> <INCLUDES> <FLAGS> --preprocess=cnl <PREPROCESSED_SOURCE>")
diff --git a/Modules/FindBoost.cmake b/Modules/FindBoost.cmake
index 6154dd6..77868f4 100644
--- a/Modules/FindBoost.cmake
+++ b/Modules/FindBoost.cmake
@@ -442,10 +442,21 @@
     endif()
   endif()
 
+  set(_boost_FIND_PACKAGE_ARGS "")
+  if(Boost_NO_SYSTEM_PATHS)
+    list(APPEND _boost_FIND_PACKAGE_ARGS NO_CMAKE_SYSTEM_PATH NO_SYSTEM_ENVIRONMENT_PATH)
+  endif()
+
   # Do the same find_package call but look specifically for the CMake version.
   # Note that args are passed in the Boost_FIND_xxxxx variables, so there is no
   # need to delegate them to this find_package call.
-  find_package(Boost QUIET NO_MODULE)
+  cmake_policy(PUSH)
+  if(BOOST_ROOT AND NOT Boost_ROOT)
+    cmake_policy(SET CMP0074 NEW)
+    set(Boost_ROOT "${BOOST_ROOT}")
+  endif()
+  find_package(Boost QUIET NO_MODULE ${_boost_FIND_PACKAGE_ARGS})
+  cmake_policy(POP)
   if (DEFINED Boost_DIR)
     mark_as_advanced(Boost_DIR)
   endif ()
diff --git a/Modules/FindPython/Support.cmake b/Modules/FindPython/Support.cmake
index 7de2d29..2b911ae 100644
--- a/Modules/FindPython/Support.cmake
+++ b/Modules/FindPython/Support.cmake
@@ -22,7 +22,7 @@
   message (FATAL_ERROR "FindPython: INTERNAL ERROR")
 endif()
 if (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR EQUAL "3")
-  set(_${_PYTHON_PREFIX}_VERSIONS 3.9 3.8 3.7 3.6 3.5 3.4 3.3 3.2 3.1 3.0)
+  set(_${_PYTHON_PREFIX}_VERSIONS 3.10 3.9 3.8 3.7 3.6 3.5 3.4 3.3 3.2 3.1 3.0)
 elseif (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR EQUAL "2")
   set(_${_PYTHON_PREFIX}_VERSIONS 2.7 2.6 2.5 2.4 2.3 2.2 2.1 2.0)
 else()
diff --git a/Modules/Internal/CheckCompilerFlag.cmake b/Modules/Internal/CheckCompilerFlag.cmake
new file mode 100644
index 0000000..f790d87
--- /dev/null
+++ b/Modules/Internal/CheckCompilerFlag.cmake
@@ -0,0 +1,79 @@
+# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+include_guard(GLOBAL)
+include(Internal/CheckSourceCompiles)
+include(CMakeCheckCompilerFlagCommonPatterns)
+
+cmake_policy(PUSH)
+cmake_policy(SET CMP0054 NEW) # if() quoted variables not dereferenced
+cmake_policy(SET CMP0057 NEW) # if() supports IN_LIST
+
+function(CMAKE_CHECK_COMPILER_FLAG _lang _flag _var)
+
+  if(_lang STREQUAL C)
+    set(_lang_src "int main(void) { return 0; }")
+    set(_lang_fail_regex FAIL_REGEX "command[ -]line option .* is valid for .* but not for C")
+  elseif(_lang STREQUAL CXX)
+    set(_lang_src "int main() { return 0; }")
+    set(_lang_fail_regex FAIL_REGEX "command[ -]line option .* is valid for .* but not for C\\+\\+")
+    elseif(_lang STREQUAL CUDA)
+    set(_lang_src "__host__ int main() { return 0; }")
+    set(_lang_fail_regex FAIL_REGEX "command[ -]line option .* is valid for .* but not for C\\+\\+" # Host GNU
+                         FAIL_REGEX "argument unused during compilation: .*") # Clang
+  elseif(_lang STREQUAL Fortran)
+    set(_lang_src "       program test\n       stop\n       end program")
+    set(_lang_fail_regex FAIL_REGEX "command[ -]line option .* is valid for .* but not for Fortran")
+  elseif(_lang STREQUAL OBJC)
+    set(_lang_src [=[
+#ifndef __OBJC__
+#  error "Not an Objective-C compiler"
+#endif
+int main(void) { return 0; }]=])
+    set(_lang_fail_regex FAIL_REGEX "command[ -]line option .* is valid for .* but not for Objective-C" # GNU
+                         FAIL_REGEX "argument unused during compilation: .*") # Clang
+  elseif(_lang STREQUAL OBJCXX)
+    set(_lang_src [=[
+#ifndef __OBJC__
+#  error "Not an Objective-C++ compiler"
+#endif
+int main(void) { return 0; }]=])
+    set(_lang_fail_regex FAIL_REGEX "command[ -]line option .* is valid for .* but not for Objective-C\\+\\+" # GNU
+                         FAIL_REGEX "argument unused during compilation: .*") # Clang
+  elseif(_lang STREQUAL ISPC)
+    set(_lang_src "float func(uniform int32, float a) { return a / 2.25; }")
+  else()
+    message (SEND_ERROR "check_compiler_flag: ${_lang}: unknown language.")
+    return()
+  endif()
+
+  get_property (_supported_languages GLOBAL PROPERTY ENABLED_LANGUAGES)
+  if (NOT _lang IN_LIST _supported_languages)
+    message (SEND_ERROR "check_compiler_flag: ${_lang}: needs to be enabled before use.")
+    return()
+  endif()
+
+  set(CMAKE_REQUIRED_DEFINITIONS ${_flag})
+
+  # Normalize locale during test compilation.
+  set(_locale_vars LC_ALL LC_MESSAGES LANG)
+  foreach(v IN LISTS _locale_vars)
+    set(_locale_vars_saved_${v} "$ENV{${v}}")
+    set(ENV{${v}} C)
+  endforeach()
+
+  check_compiler_flag_common_patterns(_common_patterns)
+  cmake_check_source_compiles(${_lang}
+    "${_lang_src}"
+    ${_var}
+    ${_lang_fail_regex}
+    ${_common_patterns}
+    )
+
+  foreach(v IN LISTS _locale_vars)
+    set(ENV{${v}} ${_locale_vars_saved_${v}})
+  endforeach()
+  set(${_var} "${${_var}}" PARENT_SCOPE)
+endfunction ()
+
+cmake_policy(POP)
diff --git a/Modules/Internal/CheckSourceCompiles.cmake b/Modules/Internal/CheckSourceCompiles.cmake
new file mode 100644
index 0000000..91c8964
--- /dev/null
+++ b/Modules/Internal/CheckSourceCompiles.cmake
@@ -0,0 +1,127 @@
+# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+include_guard(GLOBAL)
+
+cmake_policy(PUSH)
+cmake_policy(SET CMP0054 NEW) # if() quoted variables not dereferenced
+cmake_policy(SET CMP0057 NEW) # if() supports IN_LIST
+
+function(CMAKE_CHECK_SOURCE_COMPILES _lang _source _var)
+  if(NOT DEFINED "${_var}")
+
+    if(_lang STREQUAL C)
+      set(_lang_textual "C")
+      set(_lang_ext "c")
+    elseif(_lang STREQUAL CXX)
+      set(_lang_textual "C++")
+      set(_lang_ext "cxx")
+    elseif(_lang STREQUAL CUDA)
+      set(_lang_textual "CUDA")
+      set(_lang_ext "cu")
+    elseif(_lang STREQUAL Fortran)
+      set(_lang_textual "Fortran")
+      set(_lang_ext "F90")
+    elseif(_lang STREQUAL ISPC)
+      set(_lang_textual "ISPC")
+      set(_lang_ext "ispc")
+    elseif(_lang STREQUAL OBJC)
+      set(_lang_textual "Objective-C")
+      set(_lang_ext "m")
+    elseif(_lang STREQUAL OBJCXX)
+      set(_lang_textual "Objective-C++")
+      set(_lang_ext "mm")
+    else()
+      message (SEND_ERROR "check_source_compiles: ${_lang}: unknown language.")
+      return()
+    endif()
+
+    get_property (_supported_languages GLOBAL PROPERTY ENABLED_LANGUAGES)
+    if (NOT _lang IN_LIST _supported_languages)
+      message (SEND_ERROR "check_source_compiles: ${_lang}: needs to be enabled before use.")
+      return()
+    endif()
+
+    set(_FAIL_REGEX)
+    set(_SRC_EXT)
+    set(_key)
+    foreach(arg ${ARGN})
+      if("${arg}" MATCHES "^(FAIL_REGEX|SRC_EXT)$")
+        set(_key "${arg}")
+      elseif(_key STREQUAL "FAIL_REGEX")
+        list(APPEND _FAIL_REGEX "${arg}")
+      elseif(_key STREQUAL "SRC_EXT")
+        set(_SRC_EXT "${arg}")
+        set(_key "")
+      else()
+        message(FATAL_ERROR "Unknown argument:\n  ${arg}\n")
+      endif()
+    endforeach()
+
+    if(NOT _SRC_EXT)
+      set(_SRC_EXT ${_lang_ext})
+    endif()
+
+    if(CMAKE_REQUIRED_LINK_OPTIONS)
+      set(CHECK_${LANG}_SOURCE_COMPILES_ADD_LINK_OPTIONS
+        LINK_OPTIONS ${CMAKE_REQUIRED_LINK_OPTIONS})
+    else()
+      set(CHECK_${LANG}_SOURCE_COMPILES_ADD_LINK_OPTIONS)
+    endif()
+    if(CMAKE_REQUIRED_LIBRARIES)
+      set(CHECK_${LANG}_SOURCE_COMPILES_ADD_LIBRARIES
+        LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
+    else()
+      set(CHECK_${LANG}_SOURCE_COMPILES_ADD_LIBRARIES)
+    endif()
+    if(CMAKE_REQUIRED_INCLUDES)
+      set(CHECK_${LANG}_SOURCE_COMPILES_ADD_INCLUDES
+        "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}")
+    else()
+      set(CHECK_${LANG}_SOURCE_COMPILES_ADD_INCLUDES)
+    endif()
+    file(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.${_SRC_EXT}"
+      "${_source}\n")
+
+    if(NOT CMAKE_REQUIRED_QUIET)
+      message(CHECK_START "Performing Test ${_var}")
+    endif()
+    try_compile(${_var}
+      ${CMAKE_BINARY_DIR}
+      ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.${_SRC_EXT}
+      COMPILE_DEFINITIONS -D${_var} ${CMAKE_REQUIRED_DEFINITIONS}
+      ${CHECK_${LANG}_SOURCE_COMPILES_ADD_LINK_OPTIONS}
+      ${CHECK_${LANG}_SOURCE_COMPILES_ADD_LIBRARIES}
+      CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${CMAKE_REQUIRED_FLAGS}
+      "${CHECK_${LANG}_SOURCE_COMPILES_ADD_INCLUDES}"
+      OUTPUT_VARIABLE OUTPUT)
+
+    foreach(_regex ${_FAIL_REGEX})
+      if("${OUTPUT}" MATCHES "${_regex}")
+        set(${_var} 0)
+      endif()
+    endforeach()
+
+    if(${_var})
+      set(${_var} 1 CACHE INTERNAL "Test ${_var}")
+      if(NOT CMAKE_REQUIRED_QUIET)
+        message(CHECK_PASS "Success")
+      endif()
+      file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+        "Performing ${_lang_textual} SOURCE FILE Test ${_var} succeeded with the following output:\n"
+        "${OUTPUT}\n"
+        "Source file was:\n${_source}\n")
+    else()
+      if(NOT CMAKE_REQUIRED_QUIET)
+        message(CHECK_FAIL "Failed")
+      endif()
+      set(${_var} "" CACHE INTERNAL "Test ${_var}")
+      file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+        "Performing ${_lang_textual} SOURCE FILE Test ${_var} failed with the following output:\n"
+        "${OUTPUT}\n"
+        "Source file was:\n${_source}\n")
+    endif()
+  endif()
+endfunction()
+
+cmake_policy(POP)
diff --git a/Modules/Internal/CheckSourceRuns.cmake b/Modules/Internal/CheckSourceRuns.cmake
new file mode 100644
index 0000000..c667245
--- /dev/null
+++ b/Modules/Internal/CheckSourceRuns.cmake
@@ -0,0 +1,137 @@
+# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+include_guard(GLOBAL)
+
+cmake_policy(PUSH)
+cmake_policy(SET CMP0054 NEW) # if() quoted variables not dereferenced
+cmake_policy(SET CMP0057 NEW) # if() supports IN_LIST
+
+function(CMAKE_CHECK_SOURCE_RUNS _lang _source _var)
+  if(NOT DEFINED "${_var}")
+
+    if(_lang STREQUAL C)
+      set(_lang_textual "C")
+      set(_lang_ext "c")
+    elseif(_lang STREQUAL CXX)
+      set(_lang_textual "C++")
+      set(_lang_ext "cxx")
+    elseif(_lang STREQUAL CUDA)
+      set(_lang_textual "CUDA")
+      set(_lang_ext "cu")
+    elseif(_lang STREQUAL Fortran)
+      set(_lang_textual "Fortran")
+      set(_lang_ext "F90")
+    elseif(_lang STREQUAL OBJC)
+      set(_lang_textual "Objective-C")
+      set(_lang_ext "m")
+    elseif(_lang STREQUAL OBJCXX)
+      set(_lang_textual "Objective-C++")
+      set(_lang_ext "mm")
+    else()
+      message (SEND_ERROR "check_source_runs: ${_lang}: unknown language.")
+      return()
+    endif()
+
+    get_property (_supported_languages GLOBAL PROPERTY ENABLED_LANGUAGES)
+    if (NOT _lang IN_LIST _supported_languages)
+      message (SEND_ERROR "check_source_runs: ${_lang}: needs to be enabled before use.")
+      return()
+    endif()
+
+    set(_FAIL_REGEX)
+    set(_SRC_EXT)
+    set(_key)
+    foreach(arg ${ARGN})
+      if("${arg}" MATCHES "^(FAIL_REGEX|SRC_EXT)$")
+        set(_key "${arg}")
+      elseif(_key STREQUAL "FAIL_REGEX")
+        list(APPEND _FAIL_REGEX "${arg}")
+      elseif(_key STREQUAL "SRC_EXT")
+        set(_SRC_EXT "${arg}")
+        set(_key "")
+      else()
+        message(FATAL_ERROR "Unknown argument:\n  ${arg}\n")
+      endif()
+    endforeach()
+
+    if(NOT _SRC_EXT)
+      set(_SRC_EXT ${_lang_ext})
+    endif()
+
+    if(CMAKE_REQUIRED_LINK_OPTIONS)
+      set(CHECK_${_lang}_SOURCE_COMPILES_ADD_LINK_OPTIONS
+        LINK_OPTIONS ${CMAKE_REQUIRED_LINK_OPTIONS})
+    else()
+      set(CHECK_${_lang}_SOURCE_COMPILES_ADD_LINK_OPTIONS)
+    endif()
+    if(CMAKE_REQUIRED_LIBRARIES)
+      set(CHECK_${_lang}_SOURCE_COMPILES_ADD_LIBRARIES
+        LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
+    else()
+      set(CHECK_${_lang}_SOURCE_COMPILES_ADD_LIBRARIES)
+    endif()
+    if(CMAKE_REQUIRED_INCLUDES)
+      set(CHECK_${_lang}_SOURCE_COMPILES_ADD_INCLUDES
+        "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}")
+    else()
+      set(CHECK_${_lang}_SOURCE_COMPILES_ADD_INCLUDES)
+    endif()
+    file(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.${_SRC_EXT}"
+      "${_source}\n")
+
+    if(NOT CMAKE_REQUIRED_QUIET)
+      message(CHECK_START "Performing Test ${_var}")
+    endif()
+    try_run(${_var}_EXITCODE ${_var}_COMPILED
+      ${CMAKE_BINARY_DIR}
+      ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.${_SRC_EXT}
+      COMPILE_DEFINITIONS -D${_var} ${CMAKE_REQUIRED_DEFINITIONS}
+      ${CHECK_${_lang}_SOURCE_COMPILES_ADD_LINK_OPTIONS}
+      ${CHECK_${_lang}_SOURCE_COMPILES_ADD_LIBRARIES}
+      CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${CMAKE_REQUIRED_FLAGS}
+      -DCMAKE_SKIP_RPATH:BOOL=${CMAKE_SKIP_RPATH}
+      "${CHECK_${_lang}_SOURCE_COMPILES_ADD_INCLUDES}"
+      COMPILE_OUTPUT_VARIABLE OUTPUT
+      RUN_OUTPUT_VARIABLE RUN_OUTPUT)
+    # if it did not compile make the return value fail code of 1
+    if(NOT ${_var}_COMPILED)
+      set(${_var}_EXITCODE 1)
+      set(${_var}_EXITCODE 1 PARENT_SCOPE)
+    endif()
+    # if the return value was 0 then it worked
+    if("${${_var}_EXITCODE}" EQUAL 0)
+      set(${_var} 1 CACHE INTERNAL "Test ${_var}")
+      if(NOT CMAKE_REQUIRED_QUIET)
+        message(CHECK_PASS "Success")
+      endif()
+      file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+        "Performing ${_lang_textual} SOURCE FILE Test ${_var} succeeded with the following compile output:\n"
+        "${OUTPUT}\n"
+        "...and run output:\n"
+        "${RUN_OUTPUT}\n"
+        "Return value: ${${_var}}\n"
+        "Source file was:\n${_source}\n")
+    else()
+      if(CMAKE_CROSSCOMPILING AND "${${_var}_EXITCODE}" MATCHES  "FAILED_TO_RUN")
+        set(${_var} "${${_var}_EXITCODE}" PARENT_SCOPE)
+      else()
+        set(${_var} "" CACHE INTERNAL "Test ${_var}")
+      endif()
+
+      if(NOT CMAKE_REQUIRED_QUIET)
+        message(CHECK_FAIL "Failed")
+      endif()
+      file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+        "Performing ${_lang_textual} SOURCE FILE Test ${_var} failed with the following compile output:\n"
+        "${OUTPUT}\n"
+        "...and run output:\n"
+        "${RUN_OUTPUT}\n"
+        "Return value: ${${_var}_EXITCODE}\n"
+        "Source file was:\n${_source}\n")
+
+    endif()
+  endif()
+endfunction()
+
+cmake_policy(POP)
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index 1e16e17..1194318 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -197,6 +197,8 @@
   cmComputeLinkInformation.h
   cmComputeTargetDepends.h
   cmComputeTargetDepends.cxx
+  cmConsoleBuf.h
+  cmConsoleBuf.cxx
   cmCPackPropertiesGenerator.h
   cmCPackPropertiesGenerator.cxx
   cmCryptoHash.cxx
diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx
index 6c80753..85c13ad 100644
--- a/Source/CPack/cpack.cxx
+++ b/Source/CPack/cpack.cxx
@@ -1,12 +1,22 @@
 /* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
    file Copyright.txt or https://cmake.org/licensing for details.  */
 
+#include <cstddef>
+#include <iostream>
+#include <map>
+#include <memory>
+#include <sstream>
+#include <string>
+#include <utility>
+#include <vector>
+
 #include "cmsys/CommandLineArguments.hxx"
 #include "cmsys/Encoding.hxx"
 
 #include "cmCPackGenerator.h"
 #include "cmCPackGeneratorFactory.h"
 #include "cmCPackLog.h"
+#include "cmConsoleBuf.h"
 #include "cmDocumentation.h"
 #include "cmDocumentationEntry.h"
 #include "cmDocumentationFormatter.h"
@@ -19,19 +29,6 @@
 #include "cmSystemTools.h"
 #include "cmake.h"
 
-#if defined(_WIN32) && !defined(CMAKE_BOOTSTRAP)
-#  include "cmsys/ConsoleBuf.hxx"
-#endif
-
-#include <cstddef>
-#include <iostream>
-#include <map>
-#include <memory>
-#include <sstream>
-#include <string>
-#include <utility>
-#include <vector>
-
 namespace {
 const char* cmDocumentationName[][2] = {
   { nullptr, "  cpack - Packaging driver provided by CMake." },
@@ -104,13 +101,11 @@
 int main(int argc, char const* const* argv)
 {
   cmSystemTools::EnsureStdPipes();
-#if defined(_WIN32) && !defined(CMAKE_BOOTSTRAP)
+
   // Replace streambuf so we can output Unicode to console
-  cmsys::ConsoleBuf::Manager consoleOut(std::cout);
-  consoleOut.SetUTF8Pipes();
-  cmsys::ConsoleBuf::Manager consoleErr(std::cerr, true);
-  consoleErr.SetUTF8Pipes();
-#endif
+  cmConsoleBuf consoleBuf;
+  consoleBuf.SetUTF8Pipes();
+
   cmsys::Encoding::CommandLineArguments args =
     cmsys::Encoding::CommandLineArguments::Main(argc, argv);
   argc = args.argc();
diff --git a/Source/QtDialog/CMakeLists.txt b/Source/QtDialog/CMakeLists.txt
index bff3cb8..452a303 100644
--- a/Source/QtDialog/CMakeLists.txt
+++ b/Source/QtDialog/CMakeLists.txt
@@ -162,10 +162,10 @@
 target_link_libraries(cmake-gui CMakeGUIMainLib Qt5::Core)
 
 if(WIN32)
-  target_sources(CMakeGUILib INTERFACE $<TARGET_OBJECTS:CMakeVersion> CMakeSetup.rc)
+  target_sources(CMakeGUIMainLib INTERFACE $<TARGET_OBJECTS:CMakeVersion> CMakeSetup.rc)
 endif()
 if(APPLE)
-  target_sources(CMakeGUILib INTERFACE CMakeSetup.icns)
+  target_sources(CMakeGUIMainLib INTERFACE CMakeSetup.icns)
   set(MACOSX_BUNDLE_ICON_FILE CMakeSetup.icns)
   set_source_files_properties(CMakeSetup.icns PROPERTIES
     MACOSX_PACKAGE_LOCATION Resources)
diff --git a/Source/QtDialog/CMakeSetupDialog.cxx b/Source/QtDialog/CMakeSetupDialog.cxx
index acd32ec..a15614d 100644
--- a/Source/QtDialog/CMakeSetupDialog.cxx
+++ b/Source/QtDialog/CMakeSetupDialog.cxx
@@ -43,6 +43,12 @@
 #include "RegexExplorer.h"
 #include "WarningMessagesDialog.h"
 
+namespace {
+const QString PRESETS_DISABLED_TOOLTIP =
+  "This option is disabled because there are no available presets in "
+  "CMakePresets.json or CMakeUserPresets.json.";
+}
+
 QCMakeThread::QCMakeThread(QObject* p)
   : QThread(p)
 {
@@ -92,6 +98,7 @@
   this->ProgressBar->reset();
   this->RemoveEntry->setEnabled(false);
   this->AddEntry->setEnabled(false);
+  this->Preset->setStatusTip(PRESETS_DISABLED_TOOLTIP);
 
   QByteArray p = settings.value("SplitterSizes").toByteArray();
   this->Splitter->restoreState(p);
@@ -696,8 +703,8 @@
     this->Preset->blockSignals(false);
   }
 
-  this->Preset->setHidden(presets.isEmpty());
-  this->PresetLabel->setHidden(presets.isEmpty());
+  this->Preset->setDisabled(presets.isEmpty());
+  this->Preset->setToolTip(presets.isEmpty() ? PRESETS_DISABLED_TOOLTIP : "");
 
   if (!this->DeferredPreset.isNull()) {
     this->Preset->setPresetName(this->DeferredPreset);
@@ -823,7 +830,7 @@
   this->CacheValues->cacheModel()->setEditEnabled(enabled);
   this->SourceDirectory->setEnabled(enabled);
   this->BrowseSourceDirectoryButton->setEnabled(enabled);
-  this->Preset->setEnabled(enabled);
+  this->Preset->setEnabled(enabled && !this->Preset->presets().isEmpty());
   this->BinaryDirectory->setEnabled(enabled);
   this->BrowseBinaryDirectoryButton->setEnabled(enabled);
   this->ReloadCacheAction->setEnabled(enabled);
@@ -852,8 +859,10 @@
   if (presetData.isValid()) {
     auto preset = presetData.value<QCMakePreset>();
     dialog.setCurrentGenerator(preset.generator);
-    if (preset.setGenConfig) {
+    if (preset.setArchitecture) {
       dialog.setPlatform(preset.architecture);
+    }
+    if (preset.setToolset) {
       dialog.setToolset(preset.toolset);
     }
     dialog.setCompilerOption(CompilerOption::DefaultNative);
diff --git a/Source/QtDialog/CMakeSetupDialog.ui b/Source/QtDialog/CMakeSetupDialog.ui
index afb25eb..a5c35b1 100644
--- a/Source/QtDialog/CMakeSetupDialog.ui
+++ b/Source/QtDialog/CMakeSetupDialog.ui
@@ -68,7 +68,11 @@
       </widget>
      </item>
      <item row="1" column="1">
-      <widget class="QCMakePresetComboBox" name="Preset"/>
+      <widget class="QCMakePresetComboBox" name="Preset">
+       <property name="enabled">
+        <bool>false</bool>
+       </property>
+      </widget>
      </item>
      <item row="2" column="0">
       <widget class="QLabel" name="BinaryLabel">
diff --git a/Source/QtDialog/QCMake.cxx b/Source/QtDialog/QCMake.cxx
index 9017a63..2f41f70 100644
--- a/Source/QtDialog/QCMake.cxx
+++ b/Source/QtDialog/QCMake.cxx
@@ -157,8 +157,8 @@
 
     if (!name.isNull()) {
       std::string presetName(name.toLocal8Bit());
-      auto const& preset = this->CMakePresetsFile.Presets[presetName];
-      auto expandedPreset = this->CMakePresetsFile.ExpandMacros(preset);
+      auto const& expandedPreset =
+        this->CMakePresetsFile.Presets[presetName].Expanded;
       if (expandedPreset) {
         if (setBinary) {
           QString binaryDir =
@@ -420,8 +420,7 @@
 
   if (!this->PresetName.isNull()) {
     std::string presetName(this->PresetName.toLocal8Bit());
-    auto p = this->CMakePresetsFile.ExpandMacros(
-      this->CMakePresetsFile.Presets.at(presetName));
+    auto const& p = this->CMakePresetsFile.Presets.at(presetName).Expanded;
     if (p) {
       for (auto const& v : p->CacheVariables) {
         if (!v.second) {
@@ -537,7 +536,8 @@
 
   QVector<QCMakePreset> presets;
   for (auto const& name : this->CMakePresetsFile.PresetOrder) {
-    auto const& p = this->CMakePresetsFile.Presets[name];
+    auto const& it = this->CMakePresetsFile.Presets[name];
+    auto const& p = it.Unexpanded;
     if (p.Hidden) {
       continue;
     }
@@ -551,15 +551,17 @@
     preset.generator = std::move(QString::fromLocal8Bit(p.Generator.data()));
     preset.architecture =
       std::move(QString::fromLocal8Bit(p.Architecture.data()));
+    preset.setArchitecture = !p.ArchitectureStrategy ||
+      p.ArchitectureStrategy == cmCMakePresetsFile::ArchToolsetStrategy::Set;
     preset.toolset = std::move(QString::fromLocal8Bit(p.Toolset.data()));
-    preset.setGenConfig = !p.GeneratorConfig ||
-      p.GeneratorConfig == cmCMakePresetsFile::CMakeGeneratorConfig::Default;
-    preset.enabled = std::find_if(this->AvailableGenerators.begin(),
-                                  this->AvailableGenerators.end(),
-                                  [&p](const cmake::GeneratorInfo& g) {
-                                    return g.name == p.Generator;
-                                  }) != this->AvailableGenerators.end() &&
-      this->CMakePresetsFile.ExpandMacros(p);
+    preset.setToolset = !p.ToolsetStrategy ||
+      p.ToolsetStrategy == cmCMakePresetsFile::ArchToolsetStrategy::Set;
+    preset.enabled = it.Expanded &&
+      std::find_if(this->AvailableGenerators.begin(),
+                   this->AvailableGenerators.end(),
+                   [&p](const cmake::GeneratorInfo& g) {
+                     return g.name == p.Generator;
+                   }) != this->AvailableGenerators.end();
     presets.push_back(preset);
   }
   emit this->presetsChanged(presets);
diff --git a/Source/QtDialog/QCMakePreset.cxx b/Source/QtDialog/QCMakePreset.cxx
index b10cf07..176f532 100644
--- a/Source/QtDialog/QCMakePreset.cxx
+++ b/Source/QtDialog/QCMakePreset.cxx
@@ -6,8 +6,9 @@
 {
   return lhs.name == rhs.name && lhs.displayName == rhs.displayName &&
     lhs.description == rhs.description && lhs.generator == rhs.generator &&
-    lhs.architecture == rhs.architecture && lhs.toolset == rhs.toolset &&
-    lhs.setGenConfig == rhs.setGenConfig && lhs.enabled == rhs.enabled;
+    lhs.architecture == rhs.architecture &&
+    lhs.setArchitecture == rhs.setArchitecture && lhs.toolset == rhs.toolset &&
+    lhs.setToolset == rhs.setToolset && lhs.enabled == rhs.enabled;
 }
 
 bool operator!=(const QCMakePreset& lhs, const QCMakePreset& rhs)
@@ -27,11 +28,13 @@
           (lhs.generator == rhs.generator &&
            (lhs.architecture < rhs.architecture ||
             (lhs.architecture == rhs.architecture &&
-             (lhs.toolset < rhs.toolset ||
-              (lhs.toolset == rhs.toolset &&
-               (lhs.setGenConfig < rhs.setGenConfig ||
-                (lhs.setGenConfig == rhs.setGenConfig &&
-                 (lhs.enabled < rhs.enabled))))))))))))));
+             (lhs.setArchitecture < rhs.setArchitecture ||
+              (lhs.setArchitecture == rhs.setArchitecture &&
+               (lhs.toolset < rhs.toolset ||
+                (lhs.toolset == rhs.toolset &&
+                 (lhs.setToolset < rhs.setToolset ||
+                  (lhs.setToolset == rhs.setToolset &&
+                   (lhs.enabled < rhs.enabled))))))))))))))));
 }
 
 bool operator<=(const QCMakePreset& lhs, const QCMakePreset& rhs)
diff --git a/Source/QtDialog/QCMakePreset.h b/Source/QtDialog/QCMakePreset.h
index 93d70d8..1609fcb 100644
--- a/Source/QtDialog/QCMakePreset.h
+++ b/Source/QtDialog/QCMakePreset.h
@@ -15,8 +15,9 @@
   QString description;
   QString generator;
   QString architecture;
+  bool setArchitecture;
   QString toolset;
-  bool setGenConfig;
+  bool setToolset;
   bool enabled;
 };
 
diff --git a/Source/cmCMakePresetsFile.cxx b/Source/cmCMakePresetsFile.cxx
index 90a0faa..cf5db6e 100644
--- a/Source/cmCMakePresetsFile.cxx
+++ b/Source/cmCMakePresetsFile.cxx
@@ -29,7 +29,8 @@
 using ReadFileResult = cmCMakePresetsFile::ReadFileResult;
 using CacheVariable = cmCMakePresetsFile::CacheVariable;
 using UnexpandedPreset = cmCMakePresetsFile::UnexpandedPreset;
-using CMakeGeneratorConfig = cmCMakePresetsFile::CMakeGeneratorConfig;
+using ExpandedPreset = cmCMakePresetsFile::ExpandedPreset;
+using ArchToolsetStrategy = cmCMakePresetsFile::ArchToolsetStrategy;
 
 constexpr int MIN_VERSION = 1;
 constexpr int MAX_VERSION = 1;
@@ -77,15 +78,37 @@
 auto const VariableStringHelper = cmJSONStringHelper<ReadFileResult>(
   ReadFileResult::READ_OK, ReadFileResult::INVALID_VARIABLE);
 
+ReadFileResult VariableValueHelper(std::string& out, const Json::Value* value)
+{
+  if (!value) {
+    out.clear();
+    return ReadFileResult::READ_OK;
+  }
+
+  if (value->isBool()) {
+    out = value->asBool() ? "TRUE" : "FALSE";
+    return ReadFileResult::READ_OK;
+  }
+
+  return VariableStringHelper(out, value);
+}
+
 auto const VariableObjectHelper =
   cmJSONObjectHelper<CacheVariable, ReadFileResult>(
     ReadFileResult::READ_OK, ReadFileResult::INVALID_VARIABLE, false)
     .Bind("type"_s, &CacheVariable::Type, VariableStringHelper, false)
-    .Bind("value"_s, &CacheVariable::Value, VariableStringHelper);
+    .Bind("value"_s, &CacheVariable::Value, VariableValueHelper);
 
 ReadFileResult VariableHelper(cm::optional<CacheVariable>& out,
                               const Json::Value* value)
 {
+  if (value->isBool()) {
+    out = CacheVariable{
+      /*Type=*/"BOOL",
+      /*Value=*/value->asBool() ? "TRUE" : "FALSE",
+    };
+    return ReadFileResult::READ_OK;
+  }
   if (value->isString()) {
     out = CacheVariable{
       /*Type=*/"",
@@ -189,8 +212,8 @@
     .Bind("find"_s, &UnexpandedPreset::DebugFind, PresetOptionalBoolHelper,
           false);
 
-ReadFileResult CMakeGeneratorConfigHelper(
-  cm::optional<CMakeGeneratorConfig>& out, const Json::Value* value)
+ReadFileResult ArchToolsetStrategyHelper(
+  cm::optional<ArchToolsetStrategy>& out, const Json::Value* value)
 {
   if (!value) {
     out = cm::nullopt;
@@ -201,19 +224,56 @@
     return ReadFileResult::INVALID_PRESET;
   }
 
-  if (value->asString() == "default") {
-    out = CMakeGeneratorConfig::Default;
+  if (value->asString() == "set") {
+    out = ArchToolsetStrategy::Set;
     return ReadFileResult::READ_OK;
   }
 
-  if (value->asString() == "ignore") {
-    out = CMakeGeneratorConfig::Ignore;
+  if (value->asString() == "external") {
+    out = ArchToolsetStrategy::External;
     return ReadFileResult::READ_OK;
   }
 
   return ReadFileResult::INVALID_PRESET;
 }
 
+std::function<ReadFileResult(UnexpandedPreset&, const Json::Value*)>
+ArchToolsetHelper(
+  std::string UnexpandedPreset::*valueField,
+  cm::optional<ArchToolsetStrategy> UnexpandedPreset::*strategyField)
+{
+  auto const objectHelper =
+    cmJSONObjectHelper<UnexpandedPreset, ReadFileResult>(
+      ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false)
+      .Bind("value", valueField, PresetStringHelper, false)
+      .Bind("strategy", strategyField, ArchToolsetStrategyHelper, false);
+  return [valueField, strategyField, objectHelper](
+           UnexpandedPreset& out, const Json::Value* value) -> ReadFileResult {
+    if (!value) {
+      (out.*valueField).clear();
+      out.*strategyField = cm::nullopt;
+      return ReadFileResult::READ_OK;
+    }
+
+    if (value->isString()) {
+      out.*valueField = value->asString();
+      out.*strategyField = cm::nullopt;
+      return ReadFileResult::READ_OK;
+    }
+
+    if (value->isObject()) {
+      return objectHelper(out, value);
+    }
+
+    return ReadFileResult::INVALID_PRESET;
+  };
+}
+
+auto const ArchitectureHelper = ArchToolsetHelper(
+  &UnexpandedPreset::Architecture, &UnexpandedPreset::ArchitectureStrategy);
+auto const ToolsetHelper = ArchToolsetHelper(
+  &UnexpandedPreset::Toolset, &UnexpandedPreset::ToolsetStrategy);
+
 auto const PresetHelper =
   cmJSONObjectHelper<UnexpandedPreset, ReadFileResult>(
     ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false)
@@ -229,11 +289,8 @@
           false)
     .Bind("generator"_s, &UnexpandedPreset::Generator, PresetStringHelper,
           false)
-    .Bind("architecture"_s, &UnexpandedPreset::Architecture,
-          PresetStringHelper, false)
-    .Bind("toolset"_s, &UnexpandedPreset::Toolset, PresetStringHelper, false)
-    .Bind("cmakeGeneratorConfig"_s, &UnexpandedPreset::GeneratorConfig,
-          CMakeGeneratorConfigHelper, false)
+    .Bind("architecture"_s, ArchitectureHelper, false)
+    .Bind("toolset"_s, ToolsetHelper, false)
     .Bind("binaryDir"_s, &UnexpandedPreset::BinaryDir, PresetStringHelper,
           false)
     .Bind<std::string>("cmakeExecutable"_s, nullptr, PresetStringHelper, false)
@@ -290,9 +347,9 @@
  * that each preset has the required fields, either directly or through
  * inheritance.
  */
-ReadFileResult VisitPreset(std::map<std::string, UnexpandedPreset>& presets,
-                           UnexpandedPreset& preset,
-                           std::map<std::string, CycleStatus> cycleStatus)
+ReadFileResult VisitPreset(
+  std::map<std::string, cmCMakePresetsFile::PresetPair>& presets,
+  UnexpandedPreset& preset, std::map<std::string, CycleStatus> cycleStatus)
 {
   switch (cycleStatus[preset.Name]) {
     case CycleStatus::InProgress:
@@ -318,35 +375,42 @@
       return ReadFileResult::INVALID_PRESET;
     }
 
-    if (!preset.User && parent->second.User) {
+    if (!preset.User && parent->second.Unexpanded.User) {
       return ReadFileResult::USER_PRESET_INHERITANCE;
     }
 
-    auto result = VisitPreset(presets, parent->second, cycleStatus);
+    auto result = VisitPreset(presets, parent->second.Unexpanded, cycleStatus);
     if (result != ReadFileResult::READ_OK) {
       return result;
     }
 
-    InheritString(preset.Generator, parent->second.Generator);
-    InheritString(preset.Architecture, parent->second.Architecture);
-    InheritString(preset.Toolset, parent->second.Toolset);
-    if (!preset.GeneratorConfig) {
-      preset.GeneratorConfig = parent->second.GeneratorConfig;
+    InheritString(preset.Generator, parent->second.Unexpanded.Generator);
+    InheritString(preset.Architecture, parent->second.Unexpanded.Architecture);
+    InheritString(preset.Toolset, parent->second.Unexpanded.Toolset);
+    if (!preset.ArchitectureStrategy) {
+      preset.ArchitectureStrategy =
+        parent->second.Unexpanded.ArchitectureStrategy;
     }
-    InheritString(preset.BinaryDir, parent->second.BinaryDir);
-    InheritOptionalBool(preset.WarnDev, parent->second.WarnDev);
-    InheritOptionalBool(preset.ErrorDev, parent->second.ErrorDev);
-    InheritOptionalBool(preset.WarnDeprecated, parent->second.WarnDeprecated);
+    if (!preset.ToolsetStrategy) {
+      preset.ToolsetStrategy = parent->second.Unexpanded.ToolsetStrategy;
+    }
+    InheritString(preset.BinaryDir, parent->second.Unexpanded.BinaryDir);
+    InheritOptionalBool(preset.WarnDev, parent->second.Unexpanded.WarnDev);
+    InheritOptionalBool(preset.ErrorDev, parent->second.Unexpanded.ErrorDev);
+    InheritOptionalBool(preset.WarnDeprecated,
+                        parent->second.Unexpanded.WarnDeprecated);
     InheritOptionalBool(preset.ErrorDeprecated,
-                        parent->second.ErrorDeprecated);
+                        parent->second.Unexpanded.ErrorDeprecated);
     InheritOptionalBool(preset.WarnUninitialized,
-                        parent->second.WarnUninitialized);
-    InheritOptionalBool(preset.WarnUnusedCli, parent->second.WarnUnusedCli);
-    InheritOptionalBool(preset.WarnSystemVars, parent->second.WarnSystemVars);
-    for (auto const& v : parent->second.CacheVariables) {
+                        parent->second.Unexpanded.WarnUninitialized);
+    InheritOptionalBool(preset.WarnUnusedCli,
+                        parent->second.Unexpanded.WarnUnusedCli);
+    InheritOptionalBool(preset.WarnSystemVars,
+                        parent->second.Unexpanded.WarnSystemVars);
+    for (auto const& v : parent->second.Unexpanded.CacheVariables) {
       preset.CacheVariables.insert(v);
     }
-    for (auto const& v : parent->second.Environment) {
+    for (auto const& v : parent->second.Unexpanded.Environment) {
       preset.Environment.insert(v);
     }
   }
@@ -371,7 +435,7 @@
 }
 
 ReadFileResult ComputePresetInheritance(
-  std::map<std::string, UnexpandedPreset>& presets)
+  std::map<std::string, cmCMakePresetsFile::PresetPair>& presets)
 {
   std::map<std::string, CycleStatus> cycleStatus;
   for (auto const& it : presets) {
@@ -379,7 +443,7 @@
   }
 
   for (auto& it : presets) {
-    auto result = VisitPreset(presets, it.second, cycleStatus);
+    auto result = VisitPreset(presets, it.second.Unexpanded, cycleStatus);
     if (result != ReadFileResult::READ_OK) {
       return result;
     }
@@ -415,44 +479,111 @@
   return false;
 }
 
-bool VisitEnv(const cmCMakePresetsFile& file,
-              cmCMakePresetsFile::ExpandedPreset& preset,
-              std::map<std::string, CycleStatus>& envCycles,
-              std::string& value, CycleStatus& status);
-bool ExpandMacros(const cmCMakePresetsFile& file,
-                  cmCMakePresetsFile::ExpandedPreset& preset,
-                  std::map<std::string, CycleStatus>& envCycles,
-                  std::string& out);
-bool ExpandMacro(const cmCMakePresetsFile& file,
-                 cmCMakePresetsFile::ExpandedPreset& preset,
-                 std::map<std::string, CycleStatus>& envCycles,
-                 std::string& out, const std::string& macroNamespace,
-                 const std::string& macroName);
-
-bool VisitEnv(const cmCMakePresetsFile& file,
-              cmCMakePresetsFile::ExpandedPreset& preset,
-              std::map<std::string, CycleStatus>& envCycles,
-              std::string& value, CycleStatus& status)
+enum class ExpandMacroResult
 {
-  if (status == CycleStatus::Verified) {
-    return true;
-  }
-  if (status == CycleStatus::InProgress) {
-    return false;
+  Ok,
+  Ignore,
+  Error,
+};
+
+ExpandMacroResult VisitEnv(const cmCMakePresetsFile& file,
+                           cmCMakePresetsFile::ExpandedPreset& preset,
+                           std::map<std::string, CycleStatus>& envCycles,
+                           std::string& value, CycleStatus& status);
+ExpandMacroResult ExpandMacros(const cmCMakePresetsFile& file,
+                               cmCMakePresetsFile::ExpandedPreset& preset,
+                               std::map<std::string, CycleStatus>& envCycles,
+                               std::string& out);
+ExpandMacroResult ExpandMacro(const cmCMakePresetsFile& file,
+                              cmCMakePresetsFile::ExpandedPreset& preset,
+                              std::map<std::string, CycleStatus>& envCycles,
+                              std::string& out,
+                              const std::string& macroNamespace,
+                              const std::string& macroName);
+
+bool ExpandMacros(const cmCMakePresetsFile& file,
+                  const UnexpandedPreset& preset,
+                  cm::optional<ExpandedPreset>& out)
+{
+  out = preset;
+
+  std::map<std::string, CycleStatus> envCycles;
+  for (auto const& v : out->Environment) {
+    envCycles[v.first] = CycleStatus::Unvisited;
   }
 
-  status = CycleStatus::InProgress;
-  if (!ExpandMacros(file, preset, envCycles, value)) {
-    return false;
+  for (auto& v : out->Environment) {
+    if (v.second) {
+      switch (VisitEnv(file, *out, envCycles, *v.second, envCycles[v.first])) {
+        case ExpandMacroResult::Error:
+          return false;
+        case ExpandMacroResult::Ignore:
+          out.reset();
+          return true;
+        case ExpandMacroResult::Ok:
+          break;
+      }
+    }
   }
-  status = CycleStatus::Verified;
+
+  std::string binaryDir = preset.BinaryDir;
+  switch (ExpandMacros(file, *out, envCycles, binaryDir)) {
+    case ExpandMacroResult::Error:
+      return false;
+    case ExpandMacroResult::Ignore:
+      out.reset();
+      return true;
+    case ExpandMacroResult::Ok:
+      break;
+  }
+  if (!cmSystemTools::FileIsFullPath(binaryDir)) {
+    binaryDir = cmStrCat(file.SourceDir, '/', binaryDir);
+  }
+  out->BinaryDir = cmSystemTools::CollapseFullPath(binaryDir);
+  cmSystemTools::ConvertToUnixSlashes(out->BinaryDir);
+
+  for (auto& variable : out->CacheVariables) {
+    if (variable.second) {
+      switch (ExpandMacros(file, *out, envCycles, variable.second->Value)) {
+        case ExpandMacroResult::Error:
+          return false;
+        case ExpandMacroResult::Ignore:
+          out.reset();
+          return true;
+        case ExpandMacroResult::Ok:
+          break;
+      }
+    }
+  }
+
   return true;
 }
 
-bool ExpandMacros(const cmCMakePresetsFile& file,
-                  cmCMakePresetsFile::ExpandedPreset& preset,
-                  std::map<std::string, CycleStatus>& envCycles,
-                  std::string& out)
+ExpandMacroResult VisitEnv(const cmCMakePresetsFile& file,
+                           cmCMakePresetsFile::ExpandedPreset& preset,
+                           std::map<std::string, CycleStatus>& envCycles,
+                           std::string& value, CycleStatus& status)
+{
+  if (status == CycleStatus::Verified) {
+    return ExpandMacroResult::Ok;
+  }
+  if (status == CycleStatus::InProgress) {
+    return ExpandMacroResult::Error;
+  }
+
+  status = CycleStatus::InProgress;
+  auto e = ExpandMacros(file, preset, envCycles, value);
+  if (e != ExpandMacroResult::Ok) {
+    return e;
+  }
+  status = CycleStatus::Verified;
+  return ExpandMacroResult::Ok;
+}
+
+ExpandMacroResult ExpandMacros(const cmCMakePresetsFile& file,
+                               cmCMakePresetsFile::ExpandedPreset& preset,
+                               std::map<std::string, CycleStatus>& envCycles,
+                               std::string& out)
 {
   std::string result;
   std::string macroNamespace;
@@ -499,9 +630,10 @@
 
       case State::MacroName:
         if (c == '}') {
-          if (!ExpandMacro(file, preset, envCycles, result, macroNamespace,
-                           macroName)) {
-            return false;
+          auto e = ExpandMacro(file, preset, envCycles, result, macroNamespace,
+                               macroName);
+          if (e != ExpandMacroResult::Ok) {
+            return e;
           }
           macroNamespace.clear();
           macroName.clear();
@@ -521,67 +653,76 @@
       result += macroNamespace;
       break;
     case State::MacroName:
-      return false;
+      return ExpandMacroResult::Error;
   }
 
   out = std::move(result);
-  return true;
+  return ExpandMacroResult::Ok;
 }
 
-bool ExpandMacro(const cmCMakePresetsFile& file,
-                 cmCMakePresetsFile::ExpandedPreset& preset,
-                 std::map<std::string, CycleStatus>& envCycles,
-                 std::string& out, const std::string& macroNamespace,
-                 const std::string& macroName)
+ExpandMacroResult ExpandMacro(const cmCMakePresetsFile& file,
+                              cmCMakePresetsFile::ExpandedPreset& preset,
+                              std::map<std::string, CycleStatus>& envCycles,
+                              std::string& out,
+                              const std::string& macroNamespace,
+                              const std::string& macroName)
 {
   if (macroNamespace.empty()) {
     if (macroName == "sourceDir") {
       out += file.SourceDir;
-      return true;
+      return ExpandMacroResult::Ok;
     }
     if (macroName == "sourceParentDir") {
       out += cmSystemTools::GetParentDirectory(file.SourceDir);
-      return true;
+      return ExpandMacroResult::Ok;
+    }
+    if (macroName == "sourceDirName") {
+      out += cmSystemTools::GetFilenameName(file.SourceDir);
+      return ExpandMacroResult::Ok;
     }
     if (macroName == "presetName") {
       out += preset.Name;
-      return true;
+      return ExpandMacroResult::Ok;
     }
     if (macroName == "generator") {
       out += preset.Generator;
-      return true;
+      return ExpandMacroResult::Ok;
     }
     if (macroName == "dollar") {
       out += '$';
-      return true;
+      return ExpandMacroResult::Ok;
     }
   }
 
   if (macroNamespace == "env" && !macroName.empty()) {
     auto v = preset.Environment.find(macroName);
     if (v != preset.Environment.end() && v->second) {
-      if (!VisitEnv(file, preset, envCycles, *v->second,
-                    envCycles[macroName])) {
-        return false;
+      auto e =
+        VisitEnv(file, preset, envCycles, *v->second, envCycles[macroName]);
+      if (e != ExpandMacroResult::Ok) {
+        return e;
       }
       out += *v->second;
-      return true;
+      return ExpandMacroResult::Ok;
     }
   }
 
   if (macroNamespace == "env" || macroNamespace == "penv") {
     if (macroName.empty()) {
-      return false;
+      return ExpandMacroResult::Error;
     }
     const char* value = std::getenv(macroName.c_str());
     if (value) {
       out += value;
     }
-    return true;
+    return ExpandMacroResult::Ok;
   }
 
-  // "vendor" falls through to here
-  return false;
+  if (macroNamespace == "vendor") {
+    return ExpandMacroResult::Ignore;
+  }
+
+  return ExpandMacroResult::Error;
 }
 }
 
@@ -604,7 +745,7 @@
   this->PresetOrder.clear();
 
   std::vector<std::string> presetOrder;
-  std::map<std::string, UnexpandedPreset> presetMap;
+  std::map<std::string, PresetPair> presetMap;
 
   std::string filename = GetUserFilename(this->SourceDir);
   if (cmSystemTools::FileExists(filename)) {
@@ -634,6 +775,12 @@
     return result;
   }
 
+  for (auto& it : presetMap) {
+    if (!ExpandMacros(*this, it.second.Unexpanded, it.second.Expanded)) {
+      return ReadFileResult::INVALID_MACRO_EXPANSION;
+    }
+  }
+
   this->PresetOrder = std::move(presetOrder);
   this->Presets = std::move(presetMap);
   return ReadFileResult::READ_OK;
@@ -672,51 +819,16 @@
       return "Cyclic preset inheritance";
     case ReadFileResult::USER_PRESET_INHERITANCE:
       return "Project preset inherits from user preset";
-    default:
-      return "Unknown error";
-  }
-}
-
-cm::optional<cmCMakePresetsFile::ExpandedPreset>
-cmCMakePresetsFile::ExpandMacros(const UnexpandedPreset& preset) const
-{
-  ExpandedPreset retval{ preset };
-
-  std::map<std::string, CycleStatus> envCycles;
-  for (auto const& v : retval.Environment) {
-    envCycles[v.first] = CycleStatus::Unvisited;
+    case ReadFileResult::INVALID_MACRO_EXPANSION:
+      return "Invalid macro expansion";
   }
 
-  for (auto& v : retval.Environment) {
-    if (v.second &&
-        !VisitEnv(*this, retval, envCycles, *v.second, envCycles[v.first])) {
-      return cm::nullopt;
-    }
-  }
-
-  std::string binaryDir = preset.BinaryDir;
-  if (!::ExpandMacros(*this, retval, envCycles, binaryDir)) {
-    return cm::nullopt;
-  }
-  if (!cmSystemTools::FileIsFullPath(binaryDir)) {
-    binaryDir = cmStrCat(this->SourceDir, '/', binaryDir);
-  }
-  retval.BinaryDir = cmSystemTools::CollapseFullPath(binaryDir);
-  cmSystemTools::ConvertToUnixSlashes(retval.BinaryDir);
-
-  for (auto& variable : retval.CacheVariables) {
-    if (variable.second &&
-        !::ExpandMacros(*this, retval, envCycles, variable.second->Value)) {
-      return cm::nullopt;
-    }
-  }
-
-  return cm::make_optional(retval);
+  return "Unknown error";
 }
 
 cmCMakePresetsFile::ReadFileResult cmCMakePresetsFile::ReadJSONFile(
   const std::string& filename, std::vector<std::string>& presetOrder,
-  std::map<std::string, UnexpandedPreset>& presetMap, bool user)
+  std::map<std::string, PresetPair>& presetMap, bool user)
 {
   cmsys::ifstream fin(filename.c_str());
   if (!fin) {
@@ -763,7 +875,7 @@
     if (preset.Name.empty()) {
       return ReadFileResult::INVALID_PRESET;
     }
-    if (!presetMap.insert({ preset.Name, preset }).second) {
+    if (!presetMap.insert({ preset.Name, { preset, cm::nullopt } }).second) {
       return ReadFileResult::DUPLICATE_PRESETS;
     }
     presetOrder.push_back(preset.Name);
diff --git a/Source/cmCMakePresetsFile.h b/Source/cmCMakePresetsFile.h
index 70ec4c5..f6b159a 100644
--- a/Source/cmCMakePresetsFile.h
+++ b/Source/cmCMakePresetsFile.h
@@ -12,10 +12,10 @@
 class cmCMakePresetsFile
 {
 public:
-  enum class CMakeGeneratorConfig
+  enum class ArchToolsetStrategy
   {
-    Default,
-    Ignore,
+    Set,
+    External,
   };
 
   class CacheVariable
@@ -50,8 +50,9 @@
     std::string Description;
     std::string Generator;
     std::string Architecture;
+    cm::optional<ArchToolsetStrategy> ArchitectureStrategy;
     std::string Toolset;
-    cm::optional<CMakeGeneratorConfig> GeneratorConfig;
+    cm::optional<ArchToolsetStrategy> ToolsetStrategy;
     std::string BinaryDir;
 
     std::map<std::string, cm::optional<CacheVariable>> CacheVariables;
@@ -102,8 +103,15 @@
     }
   };
 
+  class PresetPair
+  {
+  public:
+    UnexpandedPreset Unexpanded;
+    cm::optional<ExpandedPreset> Expanded;
+  };
+
   std::string SourceDir;
-  std::map<std::string, UnexpandedPreset> Presets;
+  std::map<std::string, PresetPair> Presets;
   std::vector<std::string> PresetOrder;
 
   enum class ReadFileResult
@@ -123,6 +131,7 @@
     DUPLICATE_PRESETS,
     CYCLIC_PRESET_INHERITANCE,
     USER_PRESET_INHERITANCE,
+    INVALID_MACRO_EXPANSION,
   };
 
   static std::string GetFilename(const std::string& sourceDir);
@@ -131,11 +140,9 @@
                                     bool allowNoFiles = false);
   static const char* ResultToString(ReadFileResult result);
 
-  cm::optional<ExpandedPreset> ExpandMacros(
-    const UnexpandedPreset& preset) const;
-
 private:
-  ReadFileResult ReadJSONFile(
-    const std::string& filename, std::vector<std::string>& presetOrder,
-    std::map<std::string, UnexpandedPreset>& presetMap, bool user);
+  ReadFileResult ReadJSONFile(const std::string& filename,
+                              std::vector<std::string>& presetOrder,
+                              std::map<std::string, PresetPair>& presetMap,
+                              bool user);
 };
diff --git a/Source/cmConsoleBuf.cxx b/Source/cmConsoleBuf.cxx
new file mode 100644
index 0000000..70be481
--- /dev/null
+++ b/Source/cmConsoleBuf.cxx
@@ -0,0 +1,23 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file Copyright.txt or https://cmake.org/licensing for details.  */
+#include "cmConsoleBuf.h"
+
+#if defined(_WIN32) && !defined(CMAKE_BOOTSTRAP)
+cmConsoleBuf::cmConsoleBuf()
+  : m_ConsoleOut(std::cout)
+  , m_ConsoleErr(std::cerr, true)
+{
+}
+#else
+cmConsoleBuf::cmConsoleBuf() = default;
+#endif
+
+cmConsoleBuf::~cmConsoleBuf() = default;
+
+void cmConsoleBuf::SetUTF8Pipes()
+{
+#if defined(_WIN32) && !defined(CMAKE_BOOTSTRAP)
+  m_ConsoleOut.SetUTF8Pipes();
+  m_ConsoleErr.SetUTF8Pipes();
+#endif
+}
diff --git a/Source/cmConsoleBuf.h b/Source/cmConsoleBuf.h
new file mode 100644
index 0000000..3564598
--- /dev/null
+++ b/Source/cmConsoleBuf.h
@@ -0,0 +1,23 @@
+/* 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
+
+#if defined(_WIN32) && !defined(CMAKE_BOOTSTRAP)
+#  include "cmsys/ConsoleBuf.hxx"
+#endif
+
+class cmConsoleBuf
+{
+#if defined(_WIN32) && !defined(CMAKE_BOOTSTRAP)
+  cmsys::ConsoleBuf::Manager m_ConsoleOut;
+  cmsys::ConsoleBuf::Manager m_ConsoleErr;
+#endif
+public:
+  cmConsoleBuf();
+  ~cmConsoleBuf();
+  cmConsoleBuf(cmConsoleBuf const&) = delete;
+  cmConsoleBuf& operator=(cmConsoleBuf const&) = delete;
+  void SetUTF8Pipes();
+};
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index be91846..8a3aad2 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -2945,15 +2945,7 @@
   std::string outputFile = cmSystemTools::CollapseFullPath(
     args[2], status.GetMakefile().GetCurrentBinaryDirectory());
 
-  std::string::size_type pos = input.find_first_of("<>");
-  if (pos != std::string::npos) {
-    status.SetError(cmStrCat("CONFIGURE called with CONTENT containing a \"",
-                             input[pos],
-                             "\".  This character is not allowed."));
-    return false;
-  }
-
-  pos = outputFile.find_first_of("<>");
+  std::string::size_type pos = outputFile.find_first_of("<>");
   if (pos != std::string::npos) {
     status.SetError(cmStrCat("CONFIGURE called with OUTPUT containing a \"",
                              outputFile[pos],
diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx
index c988b59..92b1e80 100644
--- a/Source/cmFindPackageCommand.cxx
+++ b/Source/cmFindPackageCommand.cxx
@@ -1984,7 +1984,7 @@
 bool cmFileListGeneratorBase::Consider(std::string const& fullPath,
                                        cmFileList& listing)
 {
-  if (!cmSystemTools::FileIsDirectory(fullPath)) {
+  if (!fullPath.empty() && !cmSystemTools::FileIsDirectory(fullPath)) {
     return false;
   }
   if (this->Next) {
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index bdea9fa..3560739 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -3098,12 +3098,17 @@
     }
 
     // Check for target references in generator expressions.
-    for (std::string const& cl : cCmdLine) {
-      const std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(cl);
-      cge->SetQuiet(true);
-      cge->Evaluate(this->GeneratorTarget->GetLocalGenerator(), "");
-      std::set<cmGeneratorTarget*> geTargets = cge->GetTargets();
-      targets.insert(geTargets.begin(), geTargets.end());
+    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());
+      }
     }
   }
 
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index 985f430..8c194fd 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -1253,7 +1253,9 @@
   std::string outputPath = this->NinjaOutputPath(alias);
   std::string buildAlias = this->BuildAlias(outputPath, config);
   cmNinjaDeps outputs;
-  this->AppendTargetOutputs(target, outputs, config, DependOnTargetArtifact);
+  if (config != "all") {
+    this->AppendTargetOutputs(target, outputs, config, DependOnTargetArtifact);
+  }
   // Mark the target's outputs as ambiguous to ensure that no other target
   // uses the output as an alias.
   for (std::string const& output : outputs) {
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index fdf8307..d2cdb99 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -275,10 +275,9 @@
   { "SuppressStartupBanner", "nologo", "SuppressStartupBanner", "true", 0 },
   { "SourceFileFormat", "fixed", "Use Fixed Format", "fileFormatFixed", 0 },
   { "SourceFileFormat", "free", "Use Free Format", "fileFormatFree", 0 },
-  { "DebugInformationFormat", "Zi", "full debug", "debugEnabled", 0 },
   { "DebugInformationFormat", "debug:full", "full debug", "debugEnabled", 0 },
-  { "DebugInformationFormat", "Z7", "c7 compat", "debugOldStyleInfo", 0 },
-  { "DebugInformationFormat", "Zd", "line numbers", "debugLineInfoOnly", 0 },
+  { "DebugInformationFormat", "debug:minimal", "line numbers",
+    "debugLineInfoOnly", 0 },
   { "Optimization", "Od", "disable optimization", "optimizeDisabled", 0 },
   { "Optimization", "O1", "min space", "optimizeMinSpace", 0 },
   { "Optimization", "O3", "full optimize", "optimizeFull", 0 },
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 14ec689..0e4f888 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -3401,10 +3401,9 @@
   GeneratorConfigQuery mode) const
 {
   std::vector<std::string> configs;
-  if (this->GetGlobalGenerator()->IsMultiConfig() ||
-      mode == cmMakefile::OnlyMultiConfig) {
+  if (this->GetGlobalGenerator()->IsMultiConfig()) {
     this->GetDefExpandList("CMAKE_CONFIGURATION_TYPES", configs);
-  } else {
+  } else if (mode != cmMakefile::OnlyMultiConfig) {
     const std::string& buildType = this->GetSafeDefinition("CMAKE_BUILD_TYPE");
     if (!buildType.empty()) {
       configs.emplace_back(buildType);
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index 958d061..18ce9c3 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -327,7 +327,7 @@
          "add_test() supports arbitrary characters in test names.", 3, 19, 0, \
          cmPolicies::WARN)                                                    \
   SELECT(POLICY, CMP0111,                                                     \
-         "An imported target with a missing location fails during "           \
+         "An imported target missing its location property fails during "     \
          "generation.",                                                       \
          3, 19, 0, cmPolicies::WARN)                                          \
   SELECT(POLICY, CMP0112,                                                     \
diff --git a/Source/cmSeparateArgumentsCommand.cxx b/Source/cmSeparateArgumentsCommand.cxx
index 7e501a2..52b1a44 100644
--- a/Source/cmSeparateArgumentsCommand.cxx
+++ b/Source/cmSeparateArgumentsCommand.cxx
@@ -80,6 +80,11 @@
     return false;
   }
 
+  if (unparsedArguments.empty()) {
+    status.GetMakefile().AddDefinition(var, {});
+    return true;
+  }
+
   std::string& command = unparsedArguments.front();
 
   if (command.empty()) {
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index 2a14b03..45d6d6c 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -941,19 +941,19 @@
         return;
       }
 #if !defined(CMAKE_BOOTSTRAP)
-    } else if (cmHasLiteralPrefix(arg, "--profiling-format")) {
+    } else if (cmHasLiteralPrefix(arg, "--profiling-format=")) {
       profilingFormat = arg.substr(strlen("--profiling-format="));
       if (profilingFormat.empty()) {
         cmSystemTools::Error("No format specified for --profiling-format");
       }
-    } else if (cmHasLiteralPrefix(arg, "--profiling-output")) {
+    } else if (cmHasLiteralPrefix(arg, "--profiling-output=")) {
       profilingOutput = arg.substr(strlen("--profiling-output="));
       profilingOutput = cmSystemTools::CollapseFullPath(profilingOutput);
       cmSystemTools::ConvertToUnixSlashes(profilingOutput);
       if (profilingOutput.empty()) {
         cmSystemTools::Error("No path specified for --profiling-output");
       }
-    } else if (cmHasLiteralPrefix(arg, "--preset")) {
+    } else if (cmHasLiteralPrefix(arg, "--preset=")) {
       presetName = arg.substr(strlen("--preset="));
       if (presetName.empty()) {
         cmSystemTools::Error("No preset specified for --preset");
@@ -1042,17 +1042,17 @@
       this->PrintPresetList(settingsFile);
       return;
     }
-    if (preset->second.Hidden) {
+    if (preset->second.Unexpanded.Hidden) {
       cmSystemTools::Error(cmStrCat("Cannot use hidden preset in ",
                                     this->GetHomeDirectory(), ": \"",
                                     presetName, '"'));
       this->PrintPresetList(settingsFile);
       return;
     }
-    auto expandedPreset = settingsFile.ExpandMacros(preset->second);
+    auto const& expandedPreset = preset->second.Expanded;
     if (!expandedPreset) {
       cmSystemTools::Error(cmStrCat("Could not evaluate preset \"",
-                                    preset->second.Name,
+                                    preset->second.Unexpanded.Name,
                                     "\": Invalid macro expansion"));
       return;
     }
@@ -1069,12 +1069,16 @@
     this->UnprocessedPresetVariables = expandedPreset->CacheVariables;
     this->UnprocessedPresetEnvironment = expandedPreset->Environment;
 
-    if (!expandedPreset->GeneratorConfig ||
-        expandedPreset->GeneratorConfig ==
-          cmCMakePresetsFile::CMakeGeneratorConfig::Default) {
+    if (!expandedPreset->ArchitectureStrategy ||
+        expandedPreset->ArchitectureStrategy ==
+          cmCMakePresetsFile::ArchToolsetStrategy::Set) {
       if (!this->GeneratorPlatformSet) {
         this->SetGeneratorPlatform(expandedPreset->Architecture);
       }
+    }
+    if (!expandedPreset->ToolsetStrategy ||
+        expandedPreset->ToolsetStrategy ==
+          cmCMakePresetsFile::ArchToolsetStrategy::Set) {
       if (!this->GeneratorToolsetSet) {
         this->SetGeneratorToolset(expandedPreset->Toolset);
       }
@@ -1464,13 +1468,12 @@
   std::vector<cmCMakePresetsFile::UnexpandedPreset> presets;
   for (auto const& p : file.PresetOrder) {
     auto const& preset = file.Presets.at(p);
-    if (!preset.Hidden &&
+    if (!preset.Unexpanded.Hidden && preset.Expanded &&
         std::find_if(generators.begin(), generators.end(),
                      [&preset](const GeneratorInfo& info) {
-                       return info.name == preset.Generator;
-                     }) != generators.end() &&
-        file.ExpandMacros(preset)) {
-      presets.push_back(preset);
+                       return info.name == preset.Unexpanded.Generator;
+                     }) != generators.end()) {
+      presets.push_back(preset.Unexpanded);
     }
   }
 
diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx
index c769227..f570337 100644
--- a/Source/cmakemain.cxx
+++ b/Source/cmakemain.cxx
@@ -11,12 +11,15 @@
 #include <iostream>
 #include <sstream>
 #include <string>
+#include <utility>
 #include <vector>
 
+#include <cm/memory>
 #include <cmext/algorithm>
 
 #include <cm3p/uv.h>
 
+#include "cmConsoleBuf.h"
 #include "cmDocumentationEntry.h" // IWYU pragma: keep
 #include "cmGlobalGenerator.h"
 #include "cmMakefile.h"
@@ -34,9 +37,6 @@
 #endif
 
 #include "cmsys/Encoding.hxx"
-#if defined(_WIN32) && !defined(CMAKE_BOOTSTRAP)
-#  include "cmsys/ConsoleBuf.hxx"
-#endif
 
 namespace {
 #ifndef CMAKE_BOOTSTRAP
@@ -111,13 +111,14 @@
 
 #endif
 
-int do_command(int ac, char const* const* av)
+int do_command(int ac, char const* const* av,
+               std::unique_ptr<cmConsoleBuf> consoleBuf)
 {
   std::vector<std::string> args;
   args.reserve(ac - 1);
   args.emplace_back(av[0]);
   cm::append(args, av + 2, av + ac);
-  return cmcmd::ExecuteCMakeCommand(args);
+  return cmcmd::ExecuteCMakeCommand(args, std::move(consoleBuf));
 }
 
 cmMakefile* cmakemainGetMakefile(cmake* cm)
@@ -830,13 +831,11 @@
 int main(int ac, char const* const* av)
 {
   cmSystemTools::EnsureStdPipes();
-#if defined(_WIN32) && !defined(CMAKE_BOOTSTRAP)
+
   // Replace streambuf so we can output Unicode to console
-  cmsys::ConsoleBuf::Manager consoleOut(std::cout);
-  consoleOut.SetUTF8Pipes();
-  cmsys::ConsoleBuf::Manager consoleErr(std::cerr, true);
-  consoleErr.SetUTF8Pipes();
-#endif
+  auto consoleBuf = cm::make_unique<cmConsoleBuf>();
+  consoleBuf->SetUTF8Pipes();
+
   cmsys::Encoding::CommandLineArguments args =
     cmsys::Encoding::CommandLineArguments::Main(ac, av);
   ac = args.argc();
@@ -855,7 +854,7 @@
       return do_open(ac, av);
     }
     if (strcmp(av[1], "-E") == 0) {
-      return do_command(ac, av);
+      return do_command(ac, av, std::move(consoleBuf));
     }
   }
   int ret = do_cmake(ac, av);
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx
index 15d2fd1..e2ff8b7 100644
--- a/Source/cmcmd.cxx
+++ b/Source/cmcmd.cxx
@@ -7,6 +7,7 @@
 #include <cm3p/uv.h>
 #include <fcntl.h>
 
+#include "cmConsoleBuf.h"
 #include "cmDuration.h"
 #include "cmGlobalGenerator.h"
 #include "cmLocalGenerator.h"
@@ -33,10 +34,6 @@
 #  include "bindexplib.h"
 #endif
 
-#if !defined(CMAKE_BOOTSTRAP) && defined(_WIN32)
-#  include "cmsys/ConsoleBuf.hxx"
-#endif
-
 #if !defined(CMAKE_BOOTSTRAP) && defined(_WIN32) && !defined(__CYGWIN__)
 #  include "cmVisualStudioWCEPlatformParser.h"
 #endif
@@ -51,6 +48,12 @@
 #include <sstream>
 #include <utility>
 
+#ifdef _WIN32
+#  include <fcntl.h> // for _O_BINARY
+#  include <io.h>    // for _setmode
+#  include <stdio.h> // for std{out,err} and fileno
+#endif
+
 #include <cm/string_view>
 
 #include "cmsys/Directory.hxx"
@@ -182,6 +185,9 @@
 
 static void cmCatFile(const std::string& fileToAppend)
 {
+#ifdef _WIN32
+  _setmode(fileno(stdout), _O_BINARY);
+#endif
   cmsys::ifstream source(fileToAppend.c_str(),
                          (std::ios::binary | std::ios::in));
   std::cout << source.rdbuf();
@@ -501,7 +507,8 @@
   return ret;
 }
 
-int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args)
+int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args,
+                               std::unique_ptr<cmConsoleBuf> consoleBuf)
 {
   // IF YOU ADD A NEW COMMAND, DOCUMENT IT ABOVE and in cmakemain.cxx
   if (args.size() > 1) {
@@ -951,6 +958,8 @@
           cmSystemTools::Error(arg + ": no such file or directory (ignoring)");
           return_value = 1;
         } else {
+          // Destroy console buffers to drop cout/cerr encoding transform.
+          consoleBuf.reset();
           cmCatFile(arg);
         }
       }
@@ -1889,14 +1898,11 @@
 // still works.
 int cmcmd::VisualStudioLink(std::vector<std::string> const& args, int type)
 {
-#if defined(_WIN32) && !defined(CMAKE_BOOTSTRAP)
   // Replace streambuf so we output in the system codepage. CMake is set up
   // to output in Unicode (see SetUTF8Pipes) but the Visual Studio linker
   // outputs using the system codepage so we need to change behavior when
   // we run the link command.
-  cmsys::ConsoleBuf::Manager consoleOut(std::cout);
-  cmsys::ConsoleBuf::Manager consoleErr(std::cerr, true);
-#endif
+  cmConsoleBuf consoleBuf;
 
   if (args.size() < 2) {
     return -1;
diff --git a/Source/cmcmd.h b/Source/cmcmd.h
index 605df23..a2e0b1e 100644
--- a/Source/cmcmd.h
+++ b/Source/cmcmd.h
@@ -4,11 +4,14 @@
 
 #include "cmConfigure.h" // IWYU pragma: keep
 
+#include <memory>
 #include <string>
 #include <vector>
 
 #include "cmCryptoHash.h"
 
+class cmConsoleBuf;
+
 class cmcmd
 {
 public:
@@ -16,7 +19,8 @@
    * Execute commands during the build process. Supports options such
    * as echo, remove file etc.
    */
-  static int ExecuteCMakeCommand(std::vector<std::string> const&);
+  static int ExecuteCMakeCommand(std::vector<std::string> const&,
+                                 std::unique_ptr<cmConsoleBuf> consoleBuf);
 
 protected:
   static int HandleCoCompileCommands(std::vector<std::string> const& args);
diff --git a/Source/ctest.cxx b/Source/ctest.cxx
index 3b5bf8c..d0bc061 100644
--- a/Source/ctest.cxx
+++ b/Source/ctest.cxx
@@ -1,21 +1,20 @@
 /* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
    file Copyright.txt or https://cmake.org/licensing for details.  */
 
+#include <cstring>
+#include <iostream>
+#include <string>
+#include <vector>
+
 #include "cmsys/Encoding.hxx"
 
 #include "cmCTest.h"
+#include "cmConsoleBuf.h"
 #include "cmDocumentation.h"
 #include "cmSystemTools.h"
 
 #include "CTest/cmCTestLaunch.h"
 #include "CTest/cmCTestScriptHandler.h"
-#if defined(_WIN32) && !defined(CMAKE_BOOTSTRAP)
-#  include "cmsys/ConsoleBuf.hxx"
-#endif
-#include <cstring>
-#include <iostream>
-#include <string>
-#include <vector>
 
 static const char* cmDocumentationName[][2] = {
   { nullptr, "  ctest - Testing driver provided by CMake." },
@@ -154,13 +153,11 @@
 int main(int argc, char const* const* argv)
 {
   cmSystemTools::EnsureStdPipes();
-#if defined(_WIN32) && !defined(CMAKE_BOOTSTRAP)
+
   // Replace streambuf so we can output Unicode to console
-  cmsys::ConsoleBuf::Manager consoleOut(std::cout);
-  consoleOut.SetUTF8Pipes();
-  cmsys::ConsoleBuf::Manager consoleErr(std::cerr, true);
-  consoleErr.SetUTF8Pipes();
-#endif
+  cmConsoleBuf consoleBuf;
+  consoleBuf.SetUTF8Pipes();
+
   cmsys::Encoding::CommandLineArguments encoding_args =
     cmsys::Encoding::CommandLineArguments::Main(argc, argv);
   argc = encoding_args.argc();
diff --git a/Tests/CMakeGUI/CMakeGUITest.cxx b/Tests/CMakeGUI/CMakeGUITest.cxx
index 5a6bec3..2b5d973 100644
--- a/Tests/CMakeGUI/CMakeGUITest.cxx
+++ b/Tests/CMakeGUI/CMakeGUITest.cxx
@@ -356,16 +356,14 @@
   QCOMPARE(this->m_window->Preset->presetName(), QString{});
   QCOMPARE(this->m_window->Preset->presets().size(), 0);
   QCOMPARE(this->m_window->BinaryDirectory->currentText(), "");
-  QCOMPARE(this->m_window->Preset->isHidden(), true);
-  QCOMPARE(this->m_window->PresetLabel->isHidden(), true);
+  QCOMPARE(this->m_window->Preset->isEnabled(), false);
 
   writePresets("build1", { "preset" });
   loopSleep(1500);
   QCOMPARE(this->m_window->Preset->presetName(), QString{});
   QCOMPARE(this->m_window->Preset->presets().size(), 1);
   QCOMPARE(this->m_window->BinaryDirectory->currentText(), "");
-  QCOMPARE(this->m_window->Preset->isHidden(), false);
-  QCOMPARE(this->m_window->PresetLabel->isHidden(), false);
+  QCOMPARE(this->m_window->Preset->isEnabled(), true);
 
   this->m_window->Preset->setPresetName("preset");
   loopSleep();
@@ -373,8 +371,7 @@
   QCOMPARE(this->m_window->Preset->presets().size(), 1);
   QCOMPARE(this->m_window->BinaryDirectory->currentText(),
            CMakeGUITest_BINARY_DIR "/changingPresets/src/build1/preset");
-  QCOMPARE(this->m_window->Preset->isHidden(), false);
-  QCOMPARE(this->m_window->PresetLabel->isHidden(), false);
+  QCOMPARE(this->m_window->Preset->isEnabled(), true);
 
   writePresets("build2", { "preset2", "preset" });
   loopSleep(1500);
@@ -382,8 +379,7 @@
   QCOMPARE(this->m_window->Preset->presets().size(), 2);
   QCOMPARE(this->m_window->BinaryDirectory->currentText(),
            CMakeGUITest_BINARY_DIR "/changingPresets/src/build1/preset");
-  QCOMPARE(this->m_window->Preset->isHidden(), false);
-  QCOMPARE(this->m_window->PresetLabel->isHidden(), false);
+  QCOMPARE(this->m_window->Preset->isEnabled(), true);
 
   writePresets("build3", { "preset2" });
   loopSleep(1500);
@@ -391,8 +387,7 @@
   QCOMPARE(this->m_window->Preset->presets().size(), 1);
   QCOMPARE(this->m_window->BinaryDirectory->currentText(),
            CMakeGUITest_BINARY_DIR "/changingPresets/src/build1/preset");
-  QCOMPARE(this->m_window->Preset->isHidden(), false);
-  QCOMPARE(this->m_window->PresetLabel->isHidden(), false);
+  QCOMPARE(this->m_window->Preset->isEnabled(), true);
 
   this->m_window->Preset->setPresetName("preset2");
   loopSleep();
@@ -400,8 +395,7 @@
   QCOMPARE(this->m_window->Preset->presets().size(), 1);
   QCOMPARE(this->m_window->BinaryDirectory->currentText(),
            CMakeGUITest_BINARY_DIR "/changingPresets/src/build3/preset2");
-  QCOMPARE(this->m_window->Preset->isHidden(), false);
-  QCOMPARE(this->m_window->PresetLabel->isHidden(), false);
+  QCOMPARE(this->m_window->Preset->isEnabled(), true);
 
   QDir::root().mkpath(CMakeGUITest_BINARY_DIR "/changingPresets/src2");
   QFile::copy(CMakeGUITest_BINARY_DIR "/changingPresets/src/CMakePresets.json",
@@ -414,8 +408,7 @@
   QCOMPARE(this->m_window->Preset->presets().size(), 1);
   QCOMPARE(this->m_window->BinaryDirectory->currentText(),
            CMakeGUITest_BINARY_DIR "/changingPresets/src/build3/preset2");
-  QCOMPARE(this->m_window->Preset->isHidden(), false);
-  QCOMPARE(this->m_window->PresetLabel->isHidden(), false);
+  QCOMPARE(this->m_window->Preset->isEnabled(), true);
 
   this->m_window->Preset->setPresetName("preset2");
   loopSleep();
@@ -423,8 +416,7 @@
   QCOMPARE(this->m_window->Preset->presets().size(), 1);
   QCOMPARE(this->m_window->BinaryDirectory->currentText(),
            CMakeGUITest_BINARY_DIR "/changingPresets/src2/build3/preset2");
-  QCOMPARE(this->m_window->Preset->isHidden(), false);
-  QCOMPARE(this->m_window->PresetLabel->isHidden(), false);
+  QCOMPARE(this->m_window->Preset->isEnabled(), true);
 
   QFile(CMakeGUITest_BINARY_DIR "/changingPresets/src2/CMakePresets.json")
     .remove();
@@ -433,8 +425,7 @@
   QCOMPARE(this->m_window->Preset->presets().size(), 0);
   QCOMPARE(this->m_window->BinaryDirectory->currentText(),
            CMakeGUITest_BINARY_DIR "/changingPresets/src2/build3/preset2");
-  QCOMPARE(this->m_window->Preset->isHidden(), true);
-  QCOMPARE(this->m_window->PresetLabel->isHidden(), true);
+  QCOMPARE(this->m_window->Preset->isEnabled(), false);
 }
 
 void SetupDefaultQSettings()
diff --git a/Tests/CMakeGUI/QCMakePresetComboBoxTest.cxx b/Tests/CMakeGUI/QCMakePresetComboBoxTest.cxx
index 6ee55c3..a95d008 100644
--- a/Tests/CMakeGUI/QCMakePresetComboBoxTest.cxx
+++ b/Tests/CMakeGUI/QCMakePresetComboBoxTest.cxx
@@ -24,8 +24,9 @@
       /*description=*/"",
       /*generator=*/"Ninja",
       /*architecture=*/"",
+      /*setArchitecture=*/true,
       /*toolset=*/"",
-      /*setGenConfig=*/true,
+      /*setToolset=*/true,
       /*enabled=*/true,
     },
   });
@@ -48,8 +49,9 @@
       /*description=*/"",
       /*generator=*/"Ninja Multi-Config",
       /*architecture=*/"",
+      /*setArchitecture=*/true,
       /*toolset=*/"",
-      /*setGenConfig=*/true,
+      /*setToolset=*/true,
       /*enabled=*/true,
     },
   });
diff --git a/Tests/CMakeGUI/QCMakePresetItemModelTest.cxx b/Tests/CMakeGUI/QCMakePresetItemModelTest.cxx
index ee45d39..97dbb30 100644
--- a/Tests/CMakeGUI/QCMakePresetItemModelTest.cxx
+++ b/Tests/CMakeGUI/QCMakePresetItemModelTest.cxx
@@ -32,8 +32,9 @@
       /*description=*/"",
       /*generator=*/"",
       /*architecture=*/"",
+      /*setArchitecture=*/true,
       /*toolset=*/"",
-      /*setGenConfig=*/true,
+      /*setToolset=*/true,
       /*enabled=*/true,
     },
     QCMakePreset{
@@ -42,8 +43,9 @@
       /*description=*/"",
       /*generator=*/"",
       /*architecture=*/"",
+      /*setArchitecture=*/true,
       /*toolset=*/"",
-      /*setGenConfig=*/true,
+      /*setToolset=*/true,
       /*enabled=*/true,
     },
     QCMakePreset{
@@ -52,8 +54,9 @@
       /*description=*/"Long Description",
       /*generator=*/"",
       /*architecture=*/"",
+      /*setArchitecture=*/true,
       /*toolset=*/"",
-      /*setGenConfig=*/true,
+      /*setToolset=*/true,
       /*enabled=*/true,
     },
     QCMakePreset{
@@ -62,8 +65,9 @@
       /*description=*/"",
       /*generator=*/"",
       /*architecture=*/"",
+      /*setArchitecture=*/true,
       /*toolset=*/"",
-      /*setGenConfig=*/true,
+      /*setToolset=*/true,
       /*enabled=*/false,
     },
   };
diff --git a/Tests/CMakeGUI/QCMakePresetTest.cxx b/Tests/CMakeGUI/QCMakePresetTest.cxx
index 8fd07e7..2081055 100644
--- a/Tests/CMakeGUI/QCMakePresetTest.cxx
+++ b/Tests/CMakeGUI/QCMakePresetTest.cxx
@@ -16,8 +16,9 @@
     /*description=*/"description",
     /*generator=*/"generator",
     /*architecture=*/"architecture",
+    /*setArchitecture=*/true,
     /*toolset=*/"toolset",
-    /*setGenConfig=*/true,
+    /*setToolset=*/true,
     /*enabled=*/true,
   };
 }
@@ -69,12 +70,14 @@
   QTest::newRow("architecture")
     << makePreset(&QCMakePreset::architecture, "other-architecture") << false
     << true << false;
+  QTest::newRow("setArchitecture")
+    << makePreset(&QCMakePreset::setArchitecture, false) << false << false
+    << true;
   QTest::newRow("toolset") << makePreset(&QCMakePreset::toolset,
                                          "other-toolset")
                            << false << false << true;
-  QTest::newRow("setGenConfig")
-    << makePreset(&QCMakePreset::setGenConfig, false) << false << false
-    << true;
+  QTest::newRow("setToolset")
+    << makePreset(&QCMakePreset::setToolset, false) << false << false << true;
   QTest::newRow("enabled") << makePreset(&QCMakePreset::enabled, false)
                            << false << false << true;
 }
diff --git a/Tests/ConfigSources/CMakeLists.txt b/Tests/ConfigSources/CMakeLists.txt
index 7b1a312..1db00cc 100644
--- a/Tests/ConfigSources/CMakeLists.txt
+++ b/Tests/ConfigSources/CMakeLists.txt
@@ -91,3 +91,16 @@
 target_sources(ObjLibFromGeneratedSources PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/config_$<CONFIG>.cpp)
 add_library(SharedLibFromObjLibFromGeneratedSources SHARED shared.cpp)
 target_link_libraries(SharedLibFromObjLibFromGeneratedSources PRIVATE ObjLibFromGeneratedSources)
+
+
+# ---------------------------------------------------------------------------
+# Make sure that additional build-events do not confuse CMake when using generated files.
+add_library(SharedLibFromGeneratedSources SHARED)
+set_property(TARGET SharedLibFromGeneratedSources PROPERTY POSITION_INDEPENDENT_CODE 1)
+target_sources(SharedLibFromGeneratedSources PRIVATE
+  shared.cpp
+  ${CMAKE_CURRENT_BINARY_DIR}/config_$<CONFIG>.cpp
+  )
+add_custom_command(TARGET SharedLibFromGeneratedSources POST_BUILD
+  COMMAND "${CMAKE_COMMAND}" "-E" "echo" "$<TARGET_FILE:SharedLibFromGeneratedSources>"
+  )
diff --git a/Tests/RunCMake/CMP0111/CMP0111-WARN-stderr.txt b/Tests/RunCMake/CMP0111/CMP0111-WARN-stderr.txt
index 2fe6cc8..3abca0a 100644
--- a/Tests/RunCMake/CMP0111/CMP0111-WARN-stderr.txt
+++ b/Tests/RunCMake/CMP0111/CMP0111-WARN-stderr.txt
@@ -1,25 +1,28 @@
 CMake Warning \(dev\) in CMakeLists.txt:
-  Policy CMP0111 is not set: An imported target with a missing location fails
-  during generation.  Run "cmake --help-policy CMP0111" for policy details.
-  Use the cmake_policy command to set the policy and suppress this warning.
+  Policy CMP0111 is not set: An imported target missing its location property
+  fails during generation.  Run "cmake --help-policy CMP0111" for policy
+  details.  Use the cmake_policy command to set the policy and suppress this
+  warning.
 
   IMPORTED_LOCATION not set for imported target "unknown_lib"( configuration
   ".+")?.
 This warning is for project developers.  Use -Wno-dev to suppress it.
 +
 CMake Warning \(dev\) in CMakeLists.txt:
-  Policy CMP0111 is not set: An imported target with a missing location fails
-  during generation.  Run "cmake --help-policy CMP0111" for policy details.
-  Use the cmake_policy command to set the policy and suppress this warning.
+  Policy CMP0111 is not set: An imported target missing its location property
+  fails during generation.  Run "cmake --help-policy CMP0111" for policy
+  details.  Use the cmake_policy command to set the policy and suppress this
+  warning.
 
   IMPORTED_LOCATION not set for imported target "static_lib"( configuration
   ".+")?.
 This warning is for project developers.  Use -Wno-dev to suppress it.
 +
 CMake Warning \(dev\) in CMakeLists.txt:
-  Policy CMP0111 is not set: An imported target with a missing location fails
-  during generation.  Run "cmake --help-policy CMP0111" for policy details.
-  Use the cmake_policy command to set the policy and suppress this warning.
+  Policy CMP0111 is not set: An imported target missing its location property
+  fails during generation.  Run "cmake --help-policy CMP0111" for policy
+  details.  Use the cmake_policy command to set the policy and suppress this
+  warning.
 
   IMPORTED_IMPLIB not set for imported target "shared_lib"( configuration
   ".+")?.
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index 63738d7..7b85061 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -769,7 +769,7 @@
   -DCMAKE_C_COMPILER_VERSION=${CMAKE_C_COMPILER_VERSION})
 
 add_RunCMake_test("UnityBuild")
-add_RunCMake_test(CMakePresets)
+add_RunCMake_test(CMakePresets -DPYTHON_EXECUTABLE=${PYTHON_EXECUTABLE} -DCMake_TEST_JSON_SCHEMA=${CMake_TEST_JSON_SCHEMA})
 
 if(WIN32)
   add_RunCMake_test(Win32GenEx)
diff --git a/Tests/RunCMake/CMakePresets/CMakeGeneratorConfigDefault-result.txt b/Tests/RunCMake/CMakePresets/ArchToolsetStrategyDefault-result.txt
similarity index 100%
rename from Tests/RunCMake/CMakePresets/CMakeGeneratorConfigDefault-result.txt
rename to Tests/RunCMake/CMakePresets/ArchToolsetStrategyDefault-result.txt
diff --git a/Tests/RunCMake/CMakePresets/CMakeGeneratorConfigDefault-stderr.txt b/Tests/RunCMake/CMakePresets/ArchToolsetStrategyDefault-stderr.txt
similarity index 100%
rename from Tests/RunCMake/CMakePresets/CMakeGeneratorConfigDefault-stderr.txt
rename to Tests/RunCMake/CMakePresets/ArchToolsetStrategyDefault-stderr.txt
diff --git a/Tests/RunCMake/CMakePresets/CMakeGeneratorConfigIgnore.cmake b/Tests/RunCMake/CMakePresets/ArchToolsetStrategyIgnore.cmake
similarity index 100%
rename from Tests/RunCMake/CMakePresets/CMakeGeneratorConfigIgnore.cmake
rename to Tests/RunCMake/CMakePresets/ArchToolsetStrategyIgnore.cmake
diff --git a/Tests/RunCMake/CMakePresets/CMakeGeneratorConfigNone-result.txt b/Tests/RunCMake/CMakePresets/ArchToolsetStrategyNone-result.txt
similarity index 100%
rename from Tests/RunCMake/CMakePresets/CMakeGeneratorConfigNone-result.txt
rename to Tests/RunCMake/CMakePresets/ArchToolsetStrategyNone-result.txt
diff --git a/Tests/RunCMake/CMakePresets/CMakeGeneratorConfigNone-stderr.txt b/Tests/RunCMake/CMakePresets/ArchToolsetStrategyNone-stderr.txt
similarity index 100%
rename from Tests/RunCMake/CMakePresets/CMakeGeneratorConfigNone-stderr.txt
rename to Tests/RunCMake/CMakePresets/ArchToolsetStrategyNone-stderr.txt
diff --git a/Tests/RunCMake/CMakePresets/CMakePresets.json.in b/Tests/RunCMake/CMakePresets/CMakePresets.json.in
index 8bfc602..a8f89ff 100644
--- a/Tests/RunCMake/CMakePresets/CMakePresets.json.in
+++ b/Tests/RunCMake/CMakePresets/CMakePresets.json.in
@@ -46,6 +46,22 @@
           "type": "BOOL",
           "value": "OFF"
         },
+        "TEST_BOOL_TRUE": true,
+        "TEST_BOOL_FALSE": false,
+        "TEST_TYPED_BOOL_TRUE": {
+          "type": "STRING",
+          "value": true
+        },
+        "TEST_TYPED_BOOL_FALSE": {
+          "type": "STRING",
+          "value": false
+        },
+        "TEST_UNTYPED_BOOL_TRUE": {
+          "value": true
+        },
+        "TEST_UNTYPED_BOOL_FALSE": {
+          "value": false
+        },
         "TEST_PRESET_NAME": {
           "type": "STRING",
           "value": "x${presetName}x"
@@ -56,6 +72,7 @@
         "TEST_DOLLAR": {
           "value": "${dollar}"
         },
+        "TEST_SOURCE_DIR_NAME": "${sourceDirName}",
         "TEST_ENV_REF": "$env{TEST_ENV_REF}",
         "TEST_ENV": "$env{TEST_ENV}",
         "TEST_D_ENV_REF": "$env{TEST_D_ENV_REF}",
@@ -306,16 +323,6 @@
       "binaryDir": "${sourceDir}/build"
     },
     {
-      "name": "UnclosedMacro",
-      "generator": "@RunCMake_GENERATOR@",
-      "binaryDir": "${sourceDir"
-    },
-    {
-      "name": "NoSuchMacro",
-      "generator": "@RunCMake_GENERATOR@",
-      "binaryDir": "${noexist}"
-    },
-    {
       "name": "VendorMacro",
       "generator": "@RunCMake_GENERATOR@",
       "binaryDir": "$vendor{unknown.unknownMacro}"
@@ -326,31 +333,6 @@
       "binaryDir": "${sourceDir}/build"
     },
     {
-      "name": "EnvCycle",
-      "generator": "@RunCMake_GENERATOR@",
-      "binaryDir": "${sourceDir}/build",
-      "environment": {
-        "ENV_1": "$env{ENV_2}",
-        "ENV_2": "$env{ENV_1}"
-      }
-    },
-    {
-      "name": "EmptyEnv",
-      "generator": "@RunCMake_GENERATOR@",
-      "binaryDir": "${sourceDir}/build",
-      "cacheVariables": {
-        "MY_VAR": "$env{}"
-      }
-    },
-    {
-      "name": "EmptyPenv",
-      "generator": "@RunCMake_GENERATOR@",
-      "binaryDir": "${sourceDir}/build",
-      "cacheVariables": {
-        "MY_VAR": "$penv{}"
-      }
-    },
-    {
       "name": "UseHiddenPreset",
       "generator": "@RunCMake_GENERATOR@",
       "binaryDir": "${sourceDir}/build",
@@ -470,28 +452,38 @@
       "binaryDir": "${sourceDir}/build"
     },
     {
-      "name": "CMakeGeneratorConfigNone",
+      "name": "ArchToolsetStrategyNone",
       "generator": "@RunCMake_GENERATOR@",
       "architecture": "a",
       "toolset": "a",
       "binaryDir": "${sourceDir}/build"
     },
     {
-      "name": "CMakeGeneratorConfigBase",
+      "name": "ArchToolsetStrategyBase",
       "generator": "@RunCMake_GENERATOR@",
-      "architecture": "a",
-      "toolset": "a",
-      "cmakeGeneratorConfig": "ignore",
+      "architecture": {
+        "value": "a",
+        "strategy": "external"
+      },
+      "toolset": {
+        "value": "a",
+        "strategy": "external"
+      },
       "binaryDir": "${sourceDir}/build"
     },
     {
-      "name": "CMakeGeneratorConfigDefault",
-      "inherits": "CMakeGeneratorConfigBase",
-      "cmakeGeneratorConfig": "default"
+      "name": "ArchToolsetStrategyDefault",
+      "inherits": "ArchToolsetStrategyBase",
+      "architecture": {
+        "strategy": "set"
+      },
+      "toolset": {
+        "strategy": "set"
+      }
     },
     {
-      "name": "CMakeGeneratorConfigIgnore",
-      "inherits": "CMakeGeneratorConfigBase"
+      "name": "ArchToolsetStrategyIgnore",
+      "inherits": "ArchToolsetStrategyBase"
     }
   ]
 }
diff --git a/Tests/RunCMake/CMakePresets/DocumentationExample.cmake b/Tests/RunCMake/CMakePresets/DocumentationExample.cmake
index 1f2fc00..d459e9e 100644
--- a/Tests/RunCMake/CMakePresets/DocumentationExample.cmake
+++ b/Tests/RunCMake/CMakePresets/DocumentationExample.cmake
@@ -1,3 +1,5 @@
 include(${CMAKE_CURRENT_LIST_DIR}/TestVariable.cmake)
 
-test_variable(MY_CACHE_VARIABLE "BOOL" "OFF")
+test_variable(FIRST_CACHE_VARIABLE "BOOL" "OFF")
+test_variable(SECOND_CACHE_VARIABLE "UNINITIALIZED" "ON")
+test_environment_variable(MY_ENVIRONMENT_VARIABLE "Test")
diff --git a/Tests/RunCMake/CMakePresets/EmptyEnv-stderr.txt b/Tests/RunCMake/CMakePresets/EmptyEnv-stderr.txt
index 9c9c025..723ac21 100644
--- a/Tests/RunCMake/CMakePresets/EmptyEnv-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/EmptyEnv-stderr.txt
@@ -1 +1,2 @@
-^CMake Error: Could not evaluate preset "EmptyEnv": Invalid macro expansion$
+^CMake Error: Could not read presets from [^
+]*/Tests/RunCMake/CMakePresets/EmptyEnv: Invalid macro expansion$
diff --git a/Tests/RunCMake/CMakePresets/UnknownCMakeGeneratorConfig.json.in b/Tests/RunCMake/CMakePresets/EmptyEnv.json.in
similarity index 62%
rename from Tests/RunCMake/CMakePresets/UnknownCMakeGeneratorConfig.json.in
rename to Tests/RunCMake/CMakePresets/EmptyEnv.json.in
index 900c6df..ef0d575 100644
--- a/Tests/RunCMake/CMakePresets/UnknownCMakeGeneratorConfig.json.in
+++ b/Tests/RunCMake/CMakePresets/EmptyEnv.json.in
@@ -2,10 +2,12 @@
   "version": 1,
   "configurePresets": [
     {
-      "name": "UnknownCMakeGeneratorConfig",
+      "name": "EmptyEnv",
       "generator": "@RunCMake_GENERATOR@",
       "binaryDir": "${sourceDir}/build",
-      "cmakeGeneratorConfig": "unknown"
+      "cacheVariables": {
+        "MY_VAR": "$env{}"
+      }
     }
   ]
 }
diff --git a/Tests/RunCMake/CMakePresets/EmptyPenv-stderr.txt b/Tests/RunCMake/CMakePresets/EmptyPenv-stderr.txt
index 395c7b4..880cee6 100644
--- a/Tests/RunCMake/CMakePresets/EmptyPenv-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/EmptyPenv-stderr.txt
@@ -1 +1,2 @@
-^CMake Error: Could not evaluate preset "EmptyPenv": Invalid macro expansion$
+^CMake Error: Could not read presets from [^
+]*/Tests/RunCMake/CMakePresets/EmptyPenv: Invalid macro expansion$
diff --git a/Tests/RunCMake/CMakePresets/UnknownCMakeGeneratorConfig.json.in b/Tests/RunCMake/CMakePresets/EmptyPenv.json.in
similarity index 61%
copy from Tests/RunCMake/CMakePresets/UnknownCMakeGeneratorConfig.json.in
copy to Tests/RunCMake/CMakePresets/EmptyPenv.json.in
index 900c6df..9081fe5 100644
--- a/Tests/RunCMake/CMakePresets/UnknownCMakeGeneratorConfig.json.in
+++ b/Tests/RunCMake/CMakePresets/EmptyPenv.json.in
@@ -2,10 +2,12 @@
   "version": 1,
   "configurePresets": [
     {
-      "name": "UnknownCMakeGeneratorConfig",
+      "name": "EmptyPenv",
       "generator": "@RunCMake_GENERATOR@",
       "binaryDir": "${sourceDir}/build",
-      "cmakeGeneratorConfig": "unknown"
+      "cacheVariables": {
+        "MY_VAR": "$penv{}"
+      }
     }
   ]
 }
diff --git a/Tests/RunCMake/CMakePresets/EnvCycle-stderr.txt b/Tests/RunCMake/CMakePresets/EnvCycle-stderr.txt
index c8568f1..1d22b87 100644
--- a/Tests/RunCMake/CMakePresets/EnvCycle-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/EnvCycle-stderr.txt
@@ -1 +1,2 @@
-^CMake Error: Could not evaluate preset "EnvCycle": Invalid macro expansion$
+^CMake Error: Could not read presets from [^
+]*/Tests/RunCMake/CMakePresets/EnvCycle: Invalid macro expansion$
diff --git a/Tests/RunCMake/CMakePresets/EnvCycle.json.in b/Tests/RunCMake/CMakePresets/EnvCycle.json.in
new file mode 100644
index 0000000..25a1349
--- /dev/null
+++ b/Tests/RunCMake/CMakePresets/EnvCycle.json.in
@@ -0,0 +1,14 @@
+{
+  "version": 1,
+  "configurePresets": [
+    {
+      "name": "EnvCycle",
+      "generator": "@RunCMake_GENERATOR@",
+      "binaryDir": "${sourceDir}/build",
+      "environment": {
+        "ENV_1": "$env{ENV_2}",
+        "ENV_2": "$env{ENV_1}"
+      }
+    }
+  ]
+}
diff --git a/Tests/RunCMake/CMakePresets/Good-stdout.txt b/Tests/RunCMake/CMakePresets/Good-stdout.txt
index ce6189e..75003c7 100644
--- a/Tests/RunCMake/CMakePresets/Good-stdout.txt
+++ b/Tests/RunCMake/CMakePresets/Good-stdout.txt
@@ -1,5 +1,7 @@
 Preset CMake variables:
 
+  TEST_BOOL_FALSE:BOOL="FALSE"
+  TEST_BOOL_TRUE:BOOL="TRUE"
   TEST_DOLLAR="\$"
   TEST_D_ENV_REF="xEnvironment variablex"
   TEST_D_ENV_REF_P=""
@@ -24,6 +26,7 @@
   TEST_PRESET_NAME:STRING="xGoodx"
   TEST_SOURCE_DIR:PATH="[^
 ]*/Tests/RunCMake/CMakePresets/Good"
+  TEST_SOURCE_DIR_NAME="Good"
   TEST_SOURCE_LIST:FILEPATH="[^
 ]*/Tests/RunCMake/CMakePresets/Good/CMakeLists\.txt"
   TEST_SOURCE_PARENT_DIR:PATH="[^
@@ -32,6 +35,10 @@
   TEST_TRAILING_DOLLAR="a \$"
   TEST_TRAILING_UNKNOWN_NAMESPACE="\$unknown{namespace"
   TEST_TRUE:BOOL="TRUE"
+  TEST_TYPED_BOOL_FALSE:STRING="FALSE"
+  TEST_TYPED_BOOL_TRUE:STRING="TRUE"
+  TEST_UNTYPED_BOOL_FALSE="FALSE"
+  TEST_UNTYPED_BOOL_TRUE="TRUE"
 
 Preset environment variables:
 
diff --git a/Tests/RunCMake/CMakePresets/Good.cmake b/Tests/RunCMake/CMakePresets/Good.cmake
index d8e3e2d..73a618d 100644
--- a/Tests/RunCMake/CMakePresets/Good.cmake
+++ b/Tests/RunCMake/CMakePresets/Good.cmake
@@ -8,9 +8,16 @@
 test_variable(TEST_SOURCE_LIST "FILEPATH" "${CMAKE_SOURCE_DIR}/CMakeLists.txt")
 test_variable(TEST_TRUE "BOOL" "TRUE")
 test_variable(TEST_OFF "BOOL" "OFF")
+test_variable(TEST_BOOL_TRUE "BOOL" "TRUE")
+test_variable(TEST_BOOL_FALSE "BOOL" "FALSE")
+test_variable(TEST_TYPED_BOOL_TRUE "STRING" "TRUE")
+test_variable(TEST_TYPED_BOOL_FALSE "STRING" "FALSE")
+test_variable(TEST_UNTYPED_BOOL_TRUE "UNINITIALIZED" "TRUE")
+test_variable(TEST_UNTYPED_BOOL_FALSE "UNINITIALIZED" "FALSE")
 test_variable(TEST_PRESET_NAME "STRING" "xGoodx")
 test_variable(TEST_GENERATOR "UNINITIALIZED" "x${CMAKE_GENERATOR}x")
 test_variable(TEST_DOLLAR "UNINITIALIZED" "$")
+test_variable(TEST_SOURCE_DIR_NAME "UNINITIALIZED" "Good")
 test_variable(TEST_ENV_REF "UNINITIALIZED" "Environment variable")
 test_variable(TEST_ENV "UNINITIALIZED" "Environment variable")
 test_variable(TEST_D_ENV_REF "UNINITIALIZED" "xEnvironment variablex")
diff --git a/Tests/RunCMake/CMakePresets/CMakeGeneratorConfigDefault-result.txt b/Tests/RunCMake/CMakePresets/InvalidArchitectureStrategy-result.txt
similarity index 100%
copy from Tests/RunCMake/CMakePresets/CMakeGeneratorConfigDefault-result.txt
copy to Tests/RunCMake/CMakePresets/InvalidArchitectureStrategy-result.txt
diff --git a/Tests/RunCMake/CMakePresets/InvalidArchitectureStrategy-stderr.txt b/Tests/RunCMake/CMakePresets/InvalidArchitectureStrategy-stderr.txt
new file mode 100644
index 0000000..4a4d4ce
--- /dev/null
+++ b/Tests/RunCMake/CMakePresets/InvalidArchitectureStrategy-stderr.txt
@@ -0,0 +1,2 @@
+^CMake Error: Could not read presets from [^
+]*/Tests/RunCMake/CMakePresets/InvalidArchitectureStrategy: Invalid preset$
diff --git a/Tests/RunCMake/CMakePresets/InvalidArchitectureStrategy.json.in b/Tests/RunCMake/CMakePresets/InvalidArchitectureStrategy.json.in
new file mode 100644
index 0000000..9ec2cee
--- /dev/null
+++ b/Tests/RunCMake/CMakePresets/InvalidArchitectureStrategy.json.in
@@ -0,0 +1,13 @@
+{
+  "version": 1,
+  "configurePresets": [
+    {
+      "name": "InvalidArchitectureStrategy",
+      "generator": "@RunCMake_GENERATOR@",
+      "binaryDir": "${sourceDir}/build",
+      "architecture": {
+        "strategy": {}
+      }
+    }
+  ]
+}
diff --git a/Tests/RunCMake/CMakePresets/InvalidCMakeGeneratorConfig-result.txt b/Tests/RunCMake/CMakePresets/InvalidCMakeGeneratorConfig-result.txt
deleted file mode 100644
index d00491f..0000000
--- a/Tests/RunCMake/CMakePresets/InvalidCMakeGeneratorConfig-result.txt
+++ /dev/null
@@ -1 +0,0 @@
-1
diff --git a/Tests/RunCMake/CMakePresets/InvalidCMakeGeneratorConfig-stderr.txt b/Tests/RunCMake/CMakePresets/InvalidCMakeGeneratorConfig-stderr.txt
deleted file mode 100644
index 72a20d5..0000000
--- a/Tests/RunCMake/CMakePresets/InvalidCMakeGeneratorConfig-stderr.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/InvalidCMakeGeneratorConfig: Invalid preset$
diff --git a/Tests/RunCMake/CMakePresets/InvalidCMakeGeneratorConfig.json.in b/Tests/RunCMake/CMakePresets/InvalidCMakeGeneratorConfig.json.in
deleted file mode 100644
index 1479c66..0000000
--- a/Tests/RunCMake/CMakePresets/InvalidCMakeGeneratorConfig.json.in
+++ /dev/null
@@ -1,11 +0,0 @@
-{
-  "version": 1,
-  "configurePresets": [
-    {
-      "name": "InvalidCMakeGeneratorConfig",
-      "generator": "@RunCMake_GENERATOR@",
-      "binaryDir": "${sourceDir}/build",
-      "cmakeGeneratorConfig": {}
-    }
-  ]
-}
diff --git a/Tests/RunCMake/CMakePresets/CMakeGeneratorConfigNone-result.txt b/Tests/RunCMake/CMakePresets/InvalidToolsetStrategy-result.txt
similarity index 100%
copy from Tests/RunCMake/CMakePresets/CMakeGeneratorConfigNone-result.txt
copy to Tests/RunCMake/CMakePresets/InvalidToolsetStrategy-result.txt
diff --git a/Tests/RunCMake/CMakePresets/InvalidToolsetStrategy-stderr.txt b/Tests/RunCMake/CMakePresets/InvalidToolsetStrategy-stderr.txt
new file mode 100644
index 0000000..fab3766
--- /dev/null
+++ b/Tests/RunCMake/CMakePresets/InvalidToolsetStrategy-stderr.txt
@@ -0,0 +1,2 @@
+^CMake Error: Could not read presets from [^
+]*/Tests/RunCMake/CMakePresets/InvalidToolsetStrategy: Invalid preset$
diff --git a/Tests/RunCMake/CMakePresets/UnknownCMakeGeneratorConfig.json.in b/Tests/RunCMake/CMakePresets/InvalidToolsetStrategy.json.in
similarity index 61%
copy from Tests/RunCMake/CMakePresets/UnknownCMakeGeneratorConfig.json.in
copy to Tests/RunCMake/CMakePresets/InvalidToolsetStrategy.json.in
index 900c6df..7d2ab1f 100644
--- a/Tests/RunCMake/CMakePresets/UnknownCMakeGeneratorConfig.json.in
+++ b/Tests/RunCMake/CMakePresets/InvalidToolsetStrategy.json.in
@@ -2,10 +2,12 @@
   "version": 1,
   "configurePresets": [
     {
-      "name": "UnknownCMakeGeneratorConfig",
+      "name": "InvalidToolsetStrategy",
       "generator": "@RunCMake_GENERATOR@",
       "binaryDir": "${sourceDir}/build",
-      "cmakeGeneratorConfig": "unknown"
+      "toolset": {
+        "strategy": {}
+      }
     }
   ]
 }
diff --git a/Tests/RunCMake/CMakePresets/ListPresets.json.in b/Tests/RunCMake/CMakePresets/ListPresets.json.in
index c7646c6..2ef3797 100644
--- a/Tests/RunCMake/CMakePresets/ListPresets.json.in
+++ b/Tests/RunCMake/CMakePresets/ListPresets.json.in
@@ -26,7 +26,7 @@
     {
       "name": "invalid-macro",
       "generator": "@RunCMake_GENERATOR@",
-      "binaryDir": "${noexist}"
+      "binaryDir": "$vendor{noexist}"
     },
     {
       "name": "ListPresetsHidden",
diff --git a/Tests/RunCMake/CMakePresets/NoSuchMacro-stderr.txt b/Tests/RunCMake/CMakePresets/NoSuchMacro-stderr.txt
index 08fa87b..7dafe62 100644
--- a/Tests/RunCMake/CMakePresets/NoSuchMacro-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/NoSuchMacro-stderr.txt
@@ -1 +1,2 @@
-^CMake Error: Could not evaluate preset "NoSuchMacro": Invalid macro expansion$
+^CMake Error: Could not read presets from [^
+]*/Tests/RunCMake/CMakePresets/NoSuchMacro: Invalid macro expansion$
diff --git a/Tests/RunCMake/CMakePresets/NoSuchMacro.json.in b/Tests/RunCMake/CMakePresets/NoSuchMacro.json.in
new file mode 100644
index 0000000..94d0b76
--- /dev/null
+++ b/Tests/RunCMake/CMakePresets/NoSuchMacro.json.in
@@ -0,0 +1,10 @@
+{
+  "version": 1,
+  "configurePresets": [
+    {
+      "name": "NoSuchMacro",
+      "generator": "@RunCMake_GENERATOR@",
+      "binaryDir": "${noexist}"
+    }
+  ]
+}
diff --git a/Tests/RunCMake/CMakePresets/RunCMakeTest.cmake b/Tests/RunCMake/CMakePresets/RunCMakeTest.cmake
index 18ea093..bd84510 100644
--- a/Tests/RunCMake/CMakePresets/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CMakePresets/RunCMakeTest.cmake
@@ -7,6 +7,24 @@
   set(RunCMake_GENERATOR "${CMAKE_MATCH_1}")
 endif()
 
+set(RunCMake-check-file check.cmake)
+
+function(validate_schema file expected_result)
+  execute_process(
+    COMMAND "${PYTHON_EXECUTABLE}" "${RunCMake_SOURCE_DIR}/validate_schema.py" "${file}"
+    RESULT_VARIABLE _result
+    OUTPUT_VARIABLE _output
+    ERROR_VARIABLE _error
+    )
+  if(NOT _result STREQUAL expected_result)
+    string(REPLACE "\n" "\n" _output_p "${_output}")
+    string(REPLACE "\n" "\n" _error_p "${_error}")
+    string(APPEND RunCMake_TEST_FAILED "Expected result of validating ${file}: ${expected_result}\nActual result: ${_result}\nOutput:\n${_output_p}\nError:\n${_error_p}")
+  endif()
+
+  set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}" PARENT_SCOPE)
+endfunction()
+
 function(run_cmake_presets name)
   set(RunCMake_TEST_SOURCE_DIR "${RunCMake_BINARY_DIR}/${name}")
   set(_source_arg "${RunCMake_TEST_SOURCE_DIR}")
@@ -57,6 +75,7 @@
 endfunction()
 
 # Test CMakePresets.json errors
+set(CMakePresets_SCHEMA_EXPECTED_RESULT 1)
 run_cmake_presets(NoCMakePresets)
 run_cmake_presets(JSONParseError)
 run_cmake_presets(InvalidRoot)
@@ -65,15 +84,21 @@
 run_cmake_presets(LowVersion)
 run_cmake_presets(HighVersion)
 run_cmake_presets(InvalidVendor)
+set(CMakePresets_SCHEMA_EXPECTED_RESULT 0)
 run_cmake_presets(NoPresets)
+set(CMakePresets_SCHEMA_EXPECTED_RESULT 1)
 run_cmake_presets(InvalidPresets)
 run_cmake_presets(PresetNotObject)
 run_cmake_presets(NoPresetName)
 run_cmake_presets(InvalidPresetName)
 run_cmake_presets(EmptyPresetName)
+set(CMakePresets_SCHEMA_EXPECTED_RESULT 0)
 run_cmake_presets(NoPresetGenerator)
+set(CMakePresets_SCHEMA_EXPECTED_RESULT 1)
 run_cmake_presets(InvalidPresetGenerator)
+set(CMakePresets_SCHEMA_EXPECTED_RESULT 0)
 run_cmake_presets(NoPresetBinaryDir)
+set(CMakePresets_SCHEMA_EXPECTED_RESULT 1)
 run_cmake_presets(InvalidPresetBinaryDir)
 run_cmake_presets(InvalidVariables)
 run_cmake_presets(VariableNotObject)
@@ -83,6 +108,7 @@
 run_cmake_presets(ExtraPresetField)
 run_cmake_presets(ExtraVariableField)
 run_cmake_presets(InvalidPresetVendor)
+set(CMakePresets_SCHEMA_EXPECTED_RESULT 0)
 run_cmake_presets(DuplicatePresets)
 run_cmake_presets(CyclicInheritance0)
 run_cmake_presets(CyclicInheritance1)
@@ -90,13 +116,24 @@
 run_cmake_presets(InvalidInheritance)
 run_cmake_presets(ErrorNoWarningDev)
 run_cmake_presets(ErrorNoWarningDeprecated)
-run_cmake_presets(InvalidCMakeGeneratorConfig)
-run_cmake_presets(UnknownCMakeGeneratorConfig)
+set(CMakePresets_SCHEMA_EXPECTED_RESULT 1)
+run_cmake_presets(InvalidArchitectureStrategy)
+run_cmake_presets(UnknownArchitectureStrategy)
+run_cmake_presets(InvalidToolsetStrategy)
+run_cmake_presets(UnknownToolsetStrategy)
 run_cmake_presets(EmptyCacheKey)
 run_cmake_presets(EmptyEnvKey)
+set(CMakePresets_SCHEMA_EXPECTED_RESULT 0)
+run_cmake_presets(UnclosedMacro)
+run_cmake_presets(NoSuchMacro)
+run_cmake_presets(EnvCycle)
+run_cmake_presets(EmptyEnv)
+run_cmake_presets(EmptyPenv)
+set(CMakePresets_SCHEMA_EXPECTED_RESULT 1)
 
 # Test cmakeMinimumRequired field
 run_cmake_presets(MinimumRequiredInvalid)
+set(CMakePresets_SCHEMA_EXPECTED_RESULT 0)
 run_cmake_presets(MinimumRequiredEmpty)
 run_cmake_presets(MinimumRequiredMajor)
 run_cmake_presets(MinimumRequiredMinor)
@@ -142,13 +179,8 @@
 run_cmake_presets(GoodInheritanceMacro)
 
 # Test bad preset arguments
-run_cmake_presets(UnclosedMacro)
-run_cmake_presets(NoSuchMacro)
 run_cmake_presets(VendorMacro)
 run_cmake_presets(InvalidGenerator)
-run_cmake_presets(EnvCycle)
-run_cmake_presets(EmptyEnv)
-run_cmake_presets(EmptyPenv)
 
 # Test Visual Studio-specific stuff
 if(RunCMake_GENERATOR MATCHES "^Visual Studio ")
@@ -166,9 +198,9 @@
     run_cmake_presets(VisualStudioInheritanceMultiSecond)
   endif()
 else()
-  run_cmake_presets(CMakeGeneratorConfigNone)
-  run_cmake_presets(CMakeGeneratorConfigDefault)
-  run_cmake_presets(CMakeGeneratorConfigIgnore)
+  run_cmake_presets(ArchToolsetStrategyNone)
+  run_cmake_presets(ArchToolsetStrategyDefault)
+  run_cmake_presets(ArchToolsetStrategyIgnore)
 endif()
 
 # Test bad command line arguments
diff --git a/Tests/RunCMake/CMakePresets/UnclosedMacro-stderr.txt b/Tests/RunCMake/CMakePresets/UnclosedMacro-stderr.txt
index 248510d..f9481f0 100644
--- a/Tests/RunCMake/CMakePresets/UnclosedMacro-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/UnclosedMacro-stderr.txt
@@ -1 +1,2 @@
-^CMake Error: Could not evaluate preset "UnclosedMacro": Invalid macro expansion$
+^CMake Error: Could not read presets from [^
+]*/Tests/RunCMake/CMakePresets/UnclosedMacro: Invalid macro expansion$
diff --git a/Tests/RunCMake/CMakePresets/UnclosedMacro.json.in b/Tests/RunCMake/CMakePresets/UnclosedMacro.json.in
new file mode 100644
index 0000000..ad6cf7d
--- /dev/null
+++ b/Tests/RunCMake/CMakePresets/UnclosedMacro.json.in
@@ -0,0 +1,10 @@
+{
+  "version": 1,
+  "configurePresets": [
+    {
+      "name": "UnclosedMacro",
+      "generator": "@RunCMake_GENERATOR@",
+      "binaryDir": "${sourceDir"
+    }
+  ]
+}
diff --git a/Tests/RunCMake/CMakePresets/CMakeGeneratorConfigDefault-result.txt b/Tests/RunCMake/CMakePresets/UnknownArchitectureStrategy-result.txt
similarity index 100%
copy from Tests/RunCMake/CMakePresets/CMakeGeneratorConfigDefault-result.txt
copy to Tests/RunCMake/CMakePresets/UnknownArchitectureStrategy-result.txt
diff --git a/Tests/RunCMake/CMakePresets/UnknownArchitectureStrategy-stderr.txt b/Tests/RunCMake/CMakePresets/UnknownArchitectureStrategy-stderr.txt
new file mode 100644
index 0000000..cf17881
--- /dev/null
+++ b/Tests/RunCMake/CMakePresets/UnknownArchitectureStrategy-stderr.txt
@@ -0,0 +1,2 @@
+^CMake Error: Could not read presets from [^
+]*/Tests/RunCMake/CMakePresets/UnknownArchitectureStrategy: Invalid preset$
diff --git a/Tests/RunCMake/CMakePresets/UnknownArchitectureStrategy.json.in b/Tests/RunCMake/CMakePresets/UnknownArchitectureStrategy.json.in
new file mode 100644
index 0000000..a3bf7c8
--- /dev/null
+++ b/Tests/RunCMake/CMakePresets/UnknownArchitectureStrategy.json.in
@@ -0,0 +1,13 @@
+{
+  "version": 1,
+  "configurePresets": [
+    {
+      "name": "UnknownArchitectureStrategy",
+      "generator": "@RunCMake_GENERATOR@",
+      "binaryDir": "${sourceDir}/build",
+      "architecture": {
+        "strategy": "unknown"
+      }
+    }
+  ]
+}
diff --git a/Tests/RunCMake/CMakePresets/UnknownCMakeGeneratorConfig-result.txt b/Tests/RunCMake/CMakePresets/UnknownCMakeGeneratorConfig-result.txt
deleted file mode 100644
index d00491f..0000000
--- a/Tests/RunCMake/CMakePresets/UnknownCMakeGeneratorConfig-result.txt
+++ /dev/null
@@ -1 +0,0 @@
-1
diff --git a/Tests/RunCMake/CMakePresets/UnknownCMakeGeneratorConfig-stderr.txt b/Tests/RunCMake/CMakePresets/UnknownCMakeGeneratorConfig-stderr.txt
deleted file mode 100644
index b1759b0..0000000
--- a/Tests/RunCMake/CMakePresets/UnknownCMakeGeneratorConfig-stderr.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/UnknownCMakeGeneratorConfig: Invalid preset$
diff --git a/Tests/RunCMake/CMakePresets/CMakeGeneratorConfigNone-result.txt b/Tests/RunCMake/CMakePresets/UnknownToolsetStrategy-result.txt
similarity index 100%
copy from Tests/RunCMake/CMakePresets/CMakeGeneratorConfigNone-result.txt
copy to Tests/RunCMake/CMakePresets/UnknownToolsetStrategy-result.txt
diff --git a/Tests/RunCMake/CMakePresets/UnknownToolsetStrategy-stderr.txt b/Tests/RunCMake/CMakePresets/UnknownToolsetStrategy-stderr.txt
new file mode 100644
index 0000000..8f9be29
--- /dev/null
+++ b/Tests/RunCMake/CMakePresets/UnknownToolsetStrategy-stderr.txt
@@ -0,0 +1,2 @@
+^CMake Error: Could not read presets from [^
+]*/Tests/RunCMake/CMakePresets/UnknownToolsetStrategy: Invalid preset$
diff --git a/Tests/RunCMake/CMakePresets/UnknownToolsetStrategy.json.in b/Tests/RunCMake/CMakePresets/UnknownToolsetStrategy.json.in
new file mode 100644
index 0000000..1668700
--- /dev/null
+++ b/Tests/RunCMake/CMakePresets/UnknownToolsetStrategy.json.in
@@ -0,0 +1,13 @@
+{
+  "version": 1,
+  "configurePresets": [
+    {
+      "name": "UnknownToolsetStrategy",
+      "generator": "@RunCMake_GENERATOR@",
+      "binaryDir": "${sourceDir}/build",
+      "toolset": {
+        "strategy": "unknown"
+      }
+    }
+  ]
+}
diff --git a/Tests/RunCMake/CMakePresets/check.cmake b/Tests/RunCMake/CMakePresets/check.cmake
new file mode 100644
index 0000000..bf43c7e
--- /dev/null
+++ b/Tests/RunCMake/CMakePresets/check.cmake
@@ -0,0 +1,15 @@
+if(PYTHON_EXECUTABLE AND CMake_TEST_JSON_SCHEMA)
+  if(NOT CMakePresets_SCHEMA_EXPECTED_RESULT)
+    set(CMakePresets_SCHEMA_EXPECTED_RESULT 0)
+  endif()
+  if(EXISTS "${RunCMake_TEST_SOURCE_DIR}/CMakePresets.json")
+    validate_schema("${RunCMake_TEST_SOURCE_DIR}/CMakePresets.json" "${CMakePresets_SCHEMA_EXPECTED_RESULT}")
+  endif()
+
+  if(NOT CMakeUserPresets_SCHEMA_EXPECTED_RESULT)
+    set(CMakeUserPresets_SCHEMA_EXPECTED_RESULT 0)
+  endif()
+  if(EXISTS "${RunCMake_TEST_SOURCE_DIR}/CMakeUserPresets.json")
+    validate_schema("${RunCMake_TEST_SOURCE_DIR}/CMakeUserPresets.json" "${CMakeUserPresets_SCHEMA_EXPECTED_RESULT}")
+  endif()
+endif()
diff --git a/Tests/RunCMake/CMakePresets/validate_schema.py b/Tests/RunCMake/CMakePresets/validate_schema.py
new file mode 100644
index 0000000..c9f84ee
--- /dev/null
+++ b/Tests/RunCMake/CMakePresets/validate_schema.py
@@ -0,0 +1,17 @@
+import jsmin
+import json
+import jsonschema
+import os.path
+import sys
+
+
+with open(sys.argv[1], "rb") as f:
+    contents = json.loads(jsmin.jsmin(f.read().decode("utf-8-sig")))
+
+schema_file = os.path.join(
+        os.path.dirname(__file__),
+        "..", "..", "..", "Help", "manual", "presets", "schema.json")
+with open(schema_file) as f:
+    schema = json.load(f)
+
+jsonschema.validate(contents, schema)
diff --git a/Tests/RunCMake/CTest/RunCMakeTest.cmake b/Tests/RunCMake/CTest/RunCMakeTest.cmake
index 62606f8..ffc8f78 100644
--- a/Tests/RunCMake/CTest/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CTest/RunCMakeTest.cmake
@@ -27,3 +27,14 @@
   run_cmake_command(TestfileErrors-test ${CMAKE_CTEST_COMMAND} -C Debug)
 endfunction()
 run_TestfileErrors()
+
+function(run_SingleConfig)
+  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/SingleConfig-build)
+  run_cmake(SingleConfig)
+  set(RunCMake_TEST_NO_CLEAN 1)
+  run_cmake_command(SingleConfig-build ${CMAKE_COMMAND} --build .)
+  run_cmake_command(SingleConfig-test ${CMAKE_CTEST_COMMAND}) # No -C Debug required for single-config.
+endfunction()
+if(NOT RunCMake_GENERATOR_IS_MULTI_CONFIG)
+  run_SingleConfig()
+endif()
diff --git a/Tests/RunCMake/CTest/SingleConfig-test-stdout.txt b/Tests/RunCMake/CTest/SingleConfig-test-stdout.txt
new file mode 100644
index 0000000..1c39ea1
--- /dev/null
+++ b/Tests/RunCMake/CTest/SingleConfig-test-stdout.txt
@@ -0,0 +1,8 @@
+^Test project [^
+]*/Tests/RunCMake/CTest/SingleConfig-build
+    Start 1: SingleConfig
+1/1 Test #1: SingleConfig \.+ +Passed +[0-9.]+ sec
++
+100% tests passed, 0 tests failed out of 1
++
+Total Test time \(real\) = +[0-9.]+ sec$
diff --git a/Tests/RunCMake/CTest/SingleConfig.cmake b/Tests/RunCMake/CTest/SingleConfig.cmake
new file mode 100644
index 0000000..7c10e06
--- /dev/null
+++ b/Tests/RunCMake/CTest/SingleConfig.cmake
@@ -0,0 +1,6 @@
+include(CTest)
+
+# This should be ignored by single-config generators.
+set(CMAKE_CONFIGURATION_TYPES "Release;Debug" CACHE INTERNAL "Supported configuration types")
+
+add_test(NAME SingleConfig COMMAND ${CMAKE_COMMAND} -E echo SingleConfig)
diff --git a/Tests/RunCMake/CheckSourceCompiles/RunCMakeTest.cmake b/Tests/RunCMake/CheckSourceCompiles/RunCMakeTest.cmake
index 22cb466..6e9088f 100644
--- a/Tests/RunCMake/CheckSourceCompiles/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CheckSourceCompiles/RunCMakeTest.cmake
@@ -2,6 +2,7 @@
 
 run_cmake(NotEnabledLanguage)
 run_cmake(NonExistentLanguage)
+run_cmake(UnknownArgument)
 
 run_cmake(CheckCSourceCompiles)
 run_cmake(CheckCXXSourceCompiles)
diff --git a/Tests/RunCMake/CMakePresets/CMakeGeneratorConfigDefault-result.txt b/Tests/RunCMake/CheckSourceCompiles/UnknownArgument-result.txt
similarity index 100%
copy from Tests/RunCMake/CMakePresets/CMakeGeneratorConfigDefault-result.txt
copy to Tests/RunCMake/CheckSourceCompiles/UnknownArgument-result.txt
diff --git a/Tests/RunCMake/CheckSourceCompiles/UnknownArgument-stderr.txt b/Tests/RunCMake/CheckSourceCompiles/UnknownArgument-stderr.txt
new file mode 100644
index 0000000..a7e0af5
--- /dev/null
+++ b/Tests/RunCMake/CheckSourceCompiles/UnknownArgument-stderr.txt
@@ -0,0 +1,11 @@
+^CMake Error at [^
+]*/Modules/Internal/CheckSourceCompiles.cmake:[0-9]+ \(message\):
+  Unknown argument:
+
+    BAD
+
+Call Stack \(most recent call first\):
+  [^
+]*/Modules/CheckSourceCompiles.cmake:[0-9]+ \(cmake_check_source_compiles\)
+  UnknownArgument.cmake:[0-9]+ \(check_source_compiles\)
+  CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/CheckSourceCompiles/UnknownArgument.cmake b/Tests/RunCMake/CheckSourceCompiles/UnknownArgument.cmake
new file mode 100644
index 0000000..3b861da
--- /dev/null
+++ b/Tests/RunCMake/CheckSourceCompiles/UnknownArgument.cmake
@@ -0,0 +1,5 @@
+
+enable_language (C)
+include(CheckSourceCompiles)
+
+check_source_compiles(C "int main() {return 0;}" SHOULD_BUILD SRC_EXT C BAD)
diff --git a/Tests/RunCMake/CheckSourceRuns/RunCMakeTest.cmake b/Tests/RunCMake/CheckSourceRuns/RunCMakeTest.cmake
index b27b08d..c99ac8b 100644
--- a/Tests/RunCMake/CheckSourceRuns/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CheckSourceRuns/RunCMakeTest.cmake
@@ -2,6 +2,7 @@
 
 run_cmake(NotEnabledLanguage)
 run_cmake(NonExistentLanguage)
+run_cmake(UnknownArgument)
 
 run_cmake(CheckCSourceRuns)
 run_cmake(CheckCXXSourceRuns)
diff --git a/Tests/RunCMake/CMakePresets/CMakeGeneratorConfigDefault-result.txt b/Tests/RunCMake/CheckSourceRuns/UnknownArgument-result.txt
similarity index 100%
copy from Tests/RunCMake/CMakePresets/CMakeGeneratorConfigDefault-result.txt
copy to Tests/RunCMake/CheckSourceRuns/UnknownArgument-result.txt
diff --git a/Tests/RunCMake/CheckSourceRuns/UnknownArgument-stderr.txt b/Tests/RunCMake/CheckSourceRuns/UnknownArgument-stderr.txt
new file mode 100644
index 0000000..9b576b5
--- /dev/null
+++ b/Tests/RunCMake/CheckSourceRuns/UnknownArgument-stderr.txt
@@ -0,0 +1,11 @@
+^CMake Error at [^
+]*/Modules/Internal/CheckSourceRuns.cmake:[0-9]+ \(message\):
+  Unknown argument:
+
+    BAD
+
+Call Stack \(most recent call first\):
+  [^
+]*/Modules/CheckSourceRuns.cmake:[0-9]+ \(cmake_check_source_runs\)
+  UnknownArgument.cmake:[0-9]+ \(check_source_runs\)
+  CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/CheckSourceRuns/UnknownArgument.cmake b/Tests/RunCMake/CheckSourceRuns/UnknownArgument.cmake
new file mode 100644
index 0000000..6e50fa7
--- /dev/null
+++ b/Tests/RunCMake/CheckSourceRuns/UnknownArgument.cmake
@@ -0,0 +1,5 @@
+
+enable_language (C)
+include(CheckSourceRuns)
+
+check_source_runs(C "int main() {return 0;}" SHOULD_BUILD SRC_EXT C BAD)
diff --git a/Tests/RunCMake/CommandLine/.gitattributes b/Tests/RunCMake/CommandLine/.gitattributes
new file mode 100644
index 0000000..b0b0588
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/.gitattributes
@@ -0,0 +1,2 @@
+E_cat_binary_files/binary.obj    -text
+E_cat_good_binary_cat-stdout.txt -text -whitespace
diff --git a/Tests/RunCMake/CommandLine/E_cat_binary_files/binary.obj b/Tests/RunCMake/CommandLine/E_cat_binary_files/binary.obj
new file mode 100644
index 0000000..73f1749
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_cat_binary_files/binary.obj
Binary files differ
diff --git a/Tests/RunCMake/CommandLine/E_cat_good_binary_cat-stdout.txt b/Tests/RunCMake/CommandLine/E_cat_good_binary_cat-stdout.txt
new file mode 100644
index 0000000..0951d85
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_cat_good_binary_cat-stdout.txt
Binary files differ
diff --git a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
index 2a5d5d3..b23c8c2 100644
--- a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
@@ -563,6 +563,9 @@
   ${CMAKE_COMMAND} -E cat "${out}/first_file.txt" "${out}/second_file.txt" "${out}/unicode_file.txt")
 unset(out)
 
+run_cmake_command(E_cat_good_binary_cat
+  ${CMAKE_COMMAND} -E cat "${RunCMake_SOURCE_DIR}/E_cat_binary_files/binary.obj" "${RunCMake_SOURCE_DIR}/E_cat_binary_files/binary.obj")
+
 run_cmake_command(E_env-no-command0 ${CMAKE_COMMAND} -E env)
 run_cmake_command(E_env-no-command1 ${CMAKE_COMMAND} -E env TEST_ENV=1)
 run_cmake_command(E_env-bad-arg1 ${CMAKE_COMMAND} -E env -bad-arg1)
diff --git a/Tests/RunCMake/File_Configure/AngleBracketsContent-stderr.txt b/Tests/RunCMake/File_Configure/AngleBracketsContent-stderr.txt
new file mode 100644
index 0000000..08c2ada
--- /dev/null
+++ b/Tests/RunCMake/File_Configure/AngleBracketsContent-stderr.txt
@@ -0,0 +1 @@
+^foo-\$<CONFIG>$
diff --git a/Tests/RunCMake/File_Configure/AngleBracketsContent.cmake b/Tests/RunCMake/File_Configure/AngleBracketsContent.cmake
new file mode 100644
index 0000000..04c63bb
--- /dev/null
+++ b/Tests/RunCMake/File_Configure/AngleBracketsContent.cmake
@@ -0,0 +1,6 @@
+file(CONFIGURE
+    OUTPUT "file.txt"
+    CONTENT "foo-$<CONFIG>"
+)
+file(READ ${CMAKE_CURRENT_BINARY_DIR}/file.txt out)
+message("${out}")
diff --git a/Tests/RunCMake/File_Configure/BadArgGeneratorExpressionContent-result.txt b/Tests/RunCMake/File_Configure/BadArgGeneratorExpressionContent-result.txt
deleted file mode 100644
index d00491f..0000000
--- a/Tests/RunCMake/File_Configure/BadArgGeneratorExpressionContent-result.txt
+++ /dev/null
@@ -1 +0,0 @@
-1
diff --git a/Tests/RunCMake/File_Configure/BadArgGeneratorExpressionContent-stderr.txt b/Tests/RunCMake/File_Configure/BadArgGeneratorExpressionContent-stderr.txt
deleted file mode 100644
index acda654..0000000
--- a/Tests/RunCMake/File_Configure/BadArgGeneratorExpressionContent-stderr.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-CMake Error at BadArgGeneratorExpressionContent.cmake:[0-9]+ \(file\):
-  file CONFIGURE called with CONTENT containing a "<".  This character is not
-  allowed.
-Call Stack \(most recent call first\):
-  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/File_Configure/BadArgGeneratorExpressionContent.cmake b/Tests/RunCMake/File_Configure/BadArgGeneratorExpressionContent.cmake
deleted file mode 100644
index 75fe9e5..0000000
--- a/Tests/RunCMake/File_Configure/BadArgGeneratorExpressionContent.cmake
+++ /dev/null
@@ -1,4 +0,0 @@
-file(CONFIGURE
-    OUTPUT "file.txt"
-    CONTENT "foo-$<CONFIG>"
-)
diff --git a/Tests/RunCMake/File_Configure/RunCMakeTest.cmake b/Tests/RunCMake/File_Configure/RunCMakeTest.cmake
index 0337014..e79de79 100644
--- a/Tests/RunCMake/File_Configure/RunCMakeTest.cmake
+++ b/Tests/RunCMake/File_Configure/RunCMakeTest.cmake
@@ -1,7 +1,7 @@
 include(RunCMake)
 
+run_cmake(AngleBracketsContent)
 run_cmake(BadArg)
-run_cmake(BadArgGeneratorExpressionContent)
 run_cmake(BadArgGeneratorExpressionOutput)
 run_cmake(DirOutput)
 run_cmake(NewLineStyle-NoArg)
diff --git a/Tests/RunCMake/NinjaMultiConfig/PerConfigSources.cmake b/Tests/RunCMake/NinjaMultiConfig/PerConfigSources.cmake
new file mode 100644
index 0000000..7483130
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/PerConfigSources.cmake
@@ -0,0 +1,8 @@
+enable_language(C)
+file(GENERATE OUTPUT "${CMAKE_BINARY_DIR}/main_$<CONFIG>.c" CONTENT
+[[int main(void)
+{
+  return 0;
+}
+]])
+add_executable(exe "${CMAKE_BINARY_DIR}/main_$<CONFIG>.c")
diff --git a/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake b/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake
index ec8804b..6699a09 100644
--- a/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake
+++ b/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake
@@ -246,6 +246,10 @@
 
 run_cmake(CustomCommandDepfile)
 
+set(RunCMake_TEST_OPTIONS "-DCMAKE_CROSS_CONFIGS=all")
+run_cmake(PerConfigSources)
+unset(RunCMake_TEST_OPTIONS)
+
 set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/PostfixAndLocation-build)
 set(RunCMake_TEST_OPTIONS "-DCMAKE_CONFIGURATION_TYPES=Debug\\;Release;-DCMAKE_CROSS_CONFIGS=all")
 run_cmake_configure(PostfixAndLocation)
diff --git a/Tests/RunCMake/separate_arguments/NativeCommand.cmake b/Tests/RunCMake/separate_arguments/NativeCommand.cmake
index 1cb009e..0051a79 100644
--- a/Tests/RunCMake/separate_arguments/NativeCommand.cmake
+++ b/Tests/RunCMake/separate_arguments/NativeCommand.cmake
@@ -17,3 +17,8 @@
   message(FATAL_ERROR "separate_arguments native-style failed.  "
     "Expected\n  [${native_exp}]\nbut got\n  [${native_out}]\n")
 endif()
+
+separate_arguments(empty_out NATIVE_COMMAND)
+if(NOT empty_out STREQUAL "")
+  message(FATAL_ERROR "separate_arguments native-style failed on no arguments")
+endif()
diff --git a/Tests/RunCMake/separate_arguments/UnixCommand.cmake b/Tests/RunCMake/separate_arguments/UnixCommand.cmake
index 0b5767a..c56cd63 100644
--- a/Tests/RunCMake/separate_arguments/UnixCommand.cmake
+++ b/Tests/RunCMake/separate_arguments/UnixCommand.cmake
@@ -6,3 +6,8 @@
   message(FATAL_ERROR "separate_arguments unix-style failed.  "
     "Expected\n  [${unix_exp}]\nbut got\n  [${unix_out}]\n")
 endif()
+
+separate_arguments(empty_out UNIX_COMMAND)
+if(NOT empty_out STREQUAL "")
+  message(FATAL_ERROR "separate_arguments unix-style failed on no arguments")
+endif()
diff --git a/Tests/RunCMake/separate_arguments/WindowsCommand.cmake b/Tests/RunCMake/separate_arguments/WindowsCommand.cmake
index 86aa14a..cd07494 100644
--- a/Tests/RunCMake/separate_arguments/WindowsCommand.cmake
+++ b/Tests/RunCMake/separate_arguments/WindowsCommand.cmake
@@ -6,3 +6,8 @@
   message(FATAL_ERROR "separate_arguments windows-style failed.  "
     "Expected\n  [${windows_exp}]\nbut got\n  [${windows_out}]\n")
 endif()
+
+separate_arguments(empty_out WINDOWS_COMMAND)
+if(NOT empty_out STREQUAL "")
+  message(FATAL_ERROR "separate_arguments windows-style failed on no arguments")
+endif()
diff --git a/bootstrap b/bootstrap
index feccde9..0c1368d 100755
--- a/bootstrap
+++ b/bootstrap
@@ -235,8 +235,8 @@
 
 CMAKE_KNOWN_C_COMPILERS="cc gcc clang xlc icc tcc"
 CMAKE_KNOWN_CXX_COMPILERS="aCC xlC CC g++ clang++ c++ icc como "
-CMAKE_KNOWN_MAKE_PROCESSORS="gmake make"
-CMAKE_KNOWN_NINJA_PROCESSORS="ninja-build ninja"
+CMAKE_KNOWN_MAKE_PROCESSORS="gmake make smake"
+CMAKE_KNOWN_NINJA_PROCESSORS="ninja-build ninja samu"
 
 CMAKE_PROBLEMATIC_FILES="\
   CMakeCache.txt \
@@ -302,6 +302,7 @@
   cmComputeLinkDepends \
   cmComputeLinkInformation \
   cmComputeTargetDepends \
+  cmConsoleBuf \
   cmConditionEvaluator \
   cmConfigureFileCommand \
   cmContinueCommand \