Merge branch 'release-3.18'
diff --git a/.clang-format b/.clang-format
index 8c015ef..cba23d6 100644
--- a/.clang-format
+++ b/.clang-format
@@ -20,6 +20,8 @@
 SpaceAfterTemplateKeyword: true
 IncludeBlocks: Regroup
 IncludeCategories:
+  - Regex:           '^[<"]cmSTL\.hxx'
+    Priority:        -2
   - Regex:           '^[<"]cmConfigure\.h'
     Priority:        -1
   - Regex:           '^<queue>'
diff --git a/.gitlab/artifacts.yml b/.gitlab/artifacts.yml
index c2d28da..be10e24 100644
--- a/.gitlab/artifacts.yml
+++ b/.gitlab/artifacts.yml
@@ -34,10 +34,12 @@
             - build/Tests/CMake*/PseudoMemcheck/purify
             - build/Tests/CMake*/PseudoMemcheck/memcheck_fail
             - build/Tests/CMake*/PseudoMemcheck/BC
+            - build/Tests/CMake*/PseudoMemcheck/cuda-memcheck
             - build/Tests/CMake*/PseudoMemcheck/valgrind.exe
             - build/Tests/CMake*/PseudoMemcheck/purify.exe
             - build/Tests/CMake*/PseudoMemcheck/memcheck_fail.exe
             - build/Tests/CMake*/PseudoMemcheck/BC.exe
+            - build/Tests/CMake*/PseudoMemcheck/cuda-memcheck.exe
             - build/Tests/CMake*/PseudoMemcheck/NoLog
             - build/Tests/CMake*Lib/*LibTests
             - build/Tests/CMake*Lib/*LibTests.exe
diff --git a/CMakeLists.txt b/CMakeLists.txt
index f62c666..2d860d4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -108,6 +108,11 @@
   endif()
 endif()
 
+# Inform STL library header wrappers whether to use system versions.
+configure_file(${CMake_SOURCE_DIR}/Utilities/std/cmSTL.hxx.in
+  ${CMake_BINARY_DIR}/Utilities/cmSTL.hxx
+  @ONLY)
+
 # set the internal encoding of CMake to UTF-8
 set(KWSYS_ENCODING_DEFAULT_CODEPAGE CP_UTF8)
 
diff --git a/CTestConfig.cmake b/CTestConfig.cmake
index 9ec9e8f..476a1c6 100644
--- a/CTestConfig.cmake
+++ b/CTestConfig.cmake
@@ -6,7 +6,9 @@
 set(CTEST_PROJECT_NAME "CMake")
 set(CTEST_NIGHTLY_START_TIME "1:00:00 UTC")
 
-set(CTEST_DROP_METHOD "http")
+if(NOT CTEST_DROP_METHOD STREQUAL "https")
+  set(CTEST_DROP_METHOD "http")
+endif()
 set(CTEST_DROP_SITE "open.cdash.org")
 set(CTEST_DROP_LOCATION "/submit.php?project=CMake")
 set(CTEST_DROP_SITE_CDASH TRUE)
diff --git a/Help/command/add_compile_definitions.rst b/Help/command/add_compile_definitions.rst
index e10aba0..48e33be 100644
--- a/Help/command/add_compile_definitions.rst
+++ b/Help/command/add_compile_definitions.rst
@@ -1,6 +1,8 @@
 add_compile_definitions
 -----------------------
 
+.. versionadded:: 3.12
+
 Add preprocessor definitions to the compilation of source files.
 
 .. code-block:: cmake
diff --git a/Help/command/add_library.rst b/Help/command/add_library.rst
index 01c415a..f3df631 100644
--- a/Help/command/add_library.rst
+++ b/Help/command/add_library.rst
@@ -64,42 +64,6 @@
 pre-processed, and you want to have the original sources reachable from
 within IDE.
 
-Imported Libraries
-^^^^^^^^^^^^^^^^^^
-
-.. code-block:: cmake
-
-  add_library(<name> <SHARED|STATIC|MODULE|OBJECT|UNKNOWN> IMPORTED
-              [GLOBAL])
-
-An :ref:`IMPORTED library target <Imported Targets>` references a library
-file located outside the project.  No rules are generated to build it, and
-the :prop_tgt:`IMPORTED` target property is ``True``.  The target name has
-scope in the directory in which it is created and below, but the ``GLOBAL``
-option extends visibility.  It may be referenced like any target built
-within the project.  ``IMPORTED`` libraries are useful for convenient
-reference from commands like :command:`target_link_libraries`.  Details
-about the imported library are specified by setting properties whose names
-begin in ``IMPORTED_`` and ``INTERFACE_``.
-
-The most important properties are:
-
-* :prop_tgt:`IMPORTED_LOCATION` (and its per-configuration
-  variant :prop_tgt:`IMPORTED_LOCATION_<CONFIG>`) which specifies the
-  location of the main library file on disk.
-* :prop_tgt:`IMPORTED_OBJECTS` (and :prop_tgt:`IMPORTED_OBJECTS_<CONFIG>`)
-  for object libraries, specifies the locations of object files on disk.
-* :prop_tgt:`PUBLIC_HEADER` files to be installed during :command:`install` invocation
-
-See documentation of the ``IMPORTED_*`` and ``INTERFACE_*`` properties
-for more information.
-
-An ``UNKNOWN`` library type is typically only used in the implementation of
-:ref:`Find Modules`.  It allows the path to an imported library (often found
-using the :command:`find_library` command) to be used without having to know
-what type of library it is.  This is especially useful on Windows where a
-static library and a DLL's import library both have the same file extension.
-
 Object Libraries
 ^^^^^^^^^^^^^^^^
 
@@ -129,6 +93,112 @@
 consider adding at least one real source file to any target that references
 ``$<TARGET_OBJECTS:objlib>``.
 
+Interface Libraries
+^^^^^^^^^^^^^^^^^^^
+
+.. code-block:: cmake
+
+  add_library(<name> INTERFACE)
+
+Creates an :ref:`Interface Library <Interface Libraries>`.
+An ``INTERFACE`` library target does not compile sources and does
+not produce a library artifact on disk.  However, it may have
+properties set on it and it may be installed and exported.
+Typically, ``INTERFACE_*`` properties are populated on an interface
+target using the commands:
+
+* :command:`set_property`,
+* :command:`target_link_libraries(INTERFACE)`,
+* :command:`target_link_options(INTERFACE)`,
+* :command:`target_include_directories(INTERFACE)`,
+* :command:`target_compile_options(INTERFACE)`,
+* :command:`target_compile_definitions(INTERFACE)`, and
+* :command:`target_sources(INTERFACE)`,
+
+and then it is used as an argument to :command:`target_link_libraries`
+like any other target.
+
+An interface library created with the above signature has no source files
+itself and is not included as a target in the generated buildsystem.
+
+Since CMake 3.19, an interface library target may be created with
+source files:
+
+.. code-block:: cmake
+
+  add_library(<name> INTERFACE [<source>...] [EXCLUDE_FROM_ALL])
+
+Source files may be listed directly in the ``add_library`` call or added
+later by calls to :command:`target_sources` with the ``PRIVATE`` or
+``PUBLIC`` keywords.
+
+If an interface library has source files (i.e. the :prop_tgt:`SOURCES`
+target property is set), it will appear in the generated buildsystem
+as a build target much like a target defined by the
+:command:`add_custom_target` command.  It does not compile any sources,
+but does contain build rules for custom commands created by the
+:command:`add_custom_command` command.
+
+.. note::
+  In most command signatures where the ``INTERFACE`` keyword appears,
+  the items listed after it only become part of that target's usage
+  requirements and are not part of the target's own settings.  However,
+  in this signature of ``add_library``, the ``INTERFACE`` keyword refers
+  to the library type only.  Sources listed after it in the ``add_library``
+  call are ``PRIVATE`` to the interface library and do not appear in its
+  :prop_tgt:`INTERFACE_SOURCES` target property.
+
+Imported Libraries
+^^^^^^^^^^^^^^^^^^
+
+.. code-block:: cmake
+
+  add_library(<name> <type> IMPORTED [GLOBAL])
+
+Creates an :ref:`IMPORTED library target <Imported Targets>` called ``<name>``.
+No rules are generated to build it, and the :prop_tgt:`IMPORTED` target
+property is ``True``.  The target name has scope in the directory in which
+it is created and below, but the ``GLOBAL`` option extends visibility.
+It may be referenced like any target built within the project.
+``IMPORTED`` libraries are useful for convenient reference from commands
+like :command:`target_link_libraries`.  Details about the imported library
+are specified by setting properties whose names begin in ``IMPORTED_`` and
+``INTERFACE_``.
+
+The ``<type>`` must be one of:
+
+``STATIC``, ``SHARED``, ``MODULE``, ``UNKNOWN``
+  References a library file located outside the project.  The
+  :prop_tgt:`IMPORTED_LOCATION` target property (or its per-configuration
+  variant :prop_tgt:`IMPORTED_LOCATION_<CONFIG>`) specifies the
+  location of the main library file on disk.  In the case of a ``SHARED``
+  library on Windows, the :prop_tgt:`IMPORTED_IMPLIB` target property
+  (or its per-configuration variant :prop_tgt:`IMPORTED_IMPLIB_<CONFIG>`)
+  specifies the location of the DLL import library file (``.lib`` or
+  ``.dll.a``) on disk, and the ``IMPORTED_LOCATION`` is the location of
+  the ``.dll`` runtime library (and is optional).
+  Additional usage requirements may be specified in ``INTERFACE_*`` properties.
+
+  An ``UNKNOWN`` library type is typically only used in the implementation of
+  :ref:`Find Modules`.  It allows the path to an imported library (often found
+  using the :command:`find_library` command) to be used without having to know
+  what type of library it is.  This is especially useful on Windows where a
+  static library and a DLL's import library both have the same file extension.
+
+``OBJECT``
+  References a set of object files located outside the project.
+  The :prop_tgt:`IMPORTED_OBJECTS` target property (or its per-configuration
+  variant :prop_tgt:`IMPORTED_OBJECTS_<CONFIG>`) specifies the locations of
+  object files on disk.
+  Additional usage requirements may be specified in ``INTERFACE_*`` properties.
+
+``INTERFACE``
+  Does not reference any library or object files on disk, but may
+  specify usage requirements in ``INTERFACE_*`` properties.
+
+See documentation of the ``IMPORTED_*`` and ``INTERFACE_*`` properties
+for more information.
+
 Alias Libraries
 ^^^^^^^^^^^^^^^
 
@@ -153,35 +223,3 @@
 operand of :command:`set_property`, :command:`set_target_properties`,
 :command:`target_link_libraries` etc.  An ``ALIAS`` target may not be
 installed or exported.
-
-Interface Libraries
-^^^^^^^^^^^^^^^^^^^
-
-.. code-block:: cmake
-
-  add_library(<name> INTERFACE [IMPORTED [GLOBAL]])
-
-Creates an :ref:`Interface Library <Interface Libraries>`.  An ``INTERFACE``
-library target does not directly create build output, though it may
-have properties set on it and it may be installed, exported and
-imported. Typically the ``INTERFACE_*`` properties are populated on
-the interface target using the commands:
-
-* :command:`set_property`,
-* :command:`target_link_libraries(INTERFACE)`,
-* :command:`target_link_options(INTERFACE)`,
-* :command:`target_include_directories(INTERFACE)`,
-* :command:`target_compile_options(INTERFACE)`,
-* :command:`target_compile_definitions(INTERFACE)`, and
-* :command:`target_sources(INTERFACE)`,
-
-and then it is used as an argument to :command:`target_link_libraries`
-like any other target.
-
-An ``INTERFACE`` :ref:`Imported Target <Imported Targets>` may also be
-created with this signature.  An ``IMPORTED`` library target references a
-library defined outside the project.  The target name has scope in the
-directory in which it is created and below, but the ``GLOBAL`` option
-extends visibility.  It may be referenced like any target built within
-the project.  ``IMPORTED`` libraries are useful for convenient reference
-from commands like :command:`target_link_libraries`.
diff --git a/Help/command/add_link_options.rst b/Help/command/add_link_options.rst
index faa4afb..f03e7c0 100644
--- a/Help/command/add_link_options.rst
+++ b/Help/command/add_link_options.rst
@@ -1,6 +1,8 @@
 add_link_options
 ----------------
 
+.. versionadded:: 3.13
+
 Add options to the link step for executable, shared library or module
 library targets in the current directory and below that are added after
 this command is invoked.
diff --git a/Help/command/cmake_language.rst b/Help/command/cmake_language.rst
index 0988097..9e98d79 100644
--- a/Help/command/cmake_language.rst
+++ b/Help/command/cmake_language.rst
@@ -1,6 +1,8 @@
 cmake_language
 --------------
 
+.. versionadded:: 3.18
+
 Call meta-operations on CMake commands.
 
 Synopsis
diff --git a/Help/command/cmake_parse_arguments.rst b/Help/command/cmake_parse_arguments.rst
index fcd36d0..8803ec8 100644
--- a/Help/command/cmake_parse_arguments.rst
+++ b/Help/command/cmake_parse_arguments.rst
@@ -1,6 +1,8 @@
 cmake_parse_arguments
 ---------------------
 
+.. versionadded:: 3.5
+
 Parse function or macro arguments.
 
 .. code-block:: cmake
diff --git a/Help/command/configure_file.rst b/Help/command/configure_file.rst
index 29e85bd..46d1a05 100644
--- a/Help/command/configure_file.rst
+++ b/Help/command/configure_file.rst
@@ -7,6 +7,7 @@
 
   configure_file(<input> <output>
                  [COPYONLY] [ESCAPE_QUOTES] [@ONLY]
+                 [NO_SOURCE_PERMISSIONS]
                  [NEWLINE_STYLE [UNIX|DOS|WIN32|LF|CRLF] ])
 
 Copies an ``<input>`` file to an ``<output>`` file and substitutes
@@ -82,6 +83,11 @@
   Restrict variable replacement to references of the form ``@VAR@``.
   This is useful for configuring scripts that use ``${VAR}`` syntax.
 
+ ``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--).
+
 ``NEWLINE_STYLE <style>``
   Specify the newline style for the output file.  Specify
   ``UNIX`` or ``LF`` for ``\n`` newlines, or specify
diff --git a/Help/command/continue.rst b/Help/command/continue.rst
index 31c7089..f62802e 100644
--- a/Help/command/continue.rst
+++ b/Help/command/continue.rst
@@ -1,6 +1,8 @@
 continue
 --------
 
+.. versionadded:: 3.2
+
 Continue to the top of enclosing foreach or while loop.
 
 .. code-block:: cmake
diff --git a/Help/command/file.rst b/Help/command/file.rst
index 693c059..2cf938b 100644
--- a/Help/command/file.rst
+++ b/Help/command/file.rst
@@ -776,11 +776,14 @@
 
 .. code-block:: cmake
 
-  file(DOWNLOAD <url> <file> [<options>...])
+  file(DOWNLOAD <url> [<file>] [<options>...])
   file(UPLOAD   <file> <url> [<options>...])
 
-The ``DOWNLOAD`` mode downloads the given ``<url>`` to a local ``<file>``.
-The ``UPLOAD`` mode uploads a local ``<file>`` to a given ``<url>``.
+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>``.
 
 Options to both ``DOWNLOAD`` and ``UPLOAD`` are:
 
@@ -853,10 +856,12 @@
 
   Verify that the downloaded content hash matches the expected value, where
   ``ALGO`` is one of the algorithms supported by ``file(<HASH>)``.
-  If it does not match, the operation fails with an error.
+  If it does not match, the operation fails with an error. It is an error to
+  specify this if ``DOWNLOAD`` is not given a ``<file>``.
 
 ``EXPECTED_MD5 <value>``
-  Historical short-hand for ``EXPECTED_HASH MD5=<value>``.
+  Historical short-hand for ``EXPECTED_HASH MD5=<value>``. It is an error to
+  specify this if ``DOWNLOAD`` is not given a ``<file>``.
 
 Locking
 ^^^^^^^
diff --git a/Help/command/include_guard.rst b/Help/command/include_guard.rst
index 877aa86..dca3b6f 100644
--- a/Help/command/include_guard.rst
+++ b/Help/command/include_guard.rst
@@ -1,6 +1,8 @@
 include_guard
 -------------
 
+.. versionadded:: 3.10
+
 Provides an include guard for the file currently being processed by CMake.
 
 .. code-block:: cmake
diff --git a/Help/command/install.rst b/Help/command/install.rst
index c8df7d9..c11eaf4 100644
--- a/Help/command/install.rst
+++ b/Help/command/install.rst
@@ -45,6 +45,9 @@
 
   As absolute paths are not supported by :manual:`cpack <cpack(1)>` installer
   generators, it is preferable to use relative paths throughout.
+  In particular, there is no need to make paths absolute by prepending
+  :variable:`CMAKE_INSTALL_PREFIX`; this prefix is used by default if
+  the DESTINATION is a relative path.
 
 ``PERMISSIONS``
   Specify permissions for installed files.  Valid permissions are
diff --git a/Help/command/target_compile_features.rst b/Help/command/target_compile_features.rst
index c5401e6..b50be34 100644
--- a/Help/command/target_compile_features.rst
+++ b/Help/command/target_compile_features.rst
@@ -1,6 +1,8 @@
 target_compile_features
 -----------------------
 
+.. versionadded:: 3.1
+
 Add expected compiler features to a target.
 
 .. code-block:: cmake
diff --git a/Help/command/target_link_directories.rst b/Help/command/target_link_directories.rst
index 76da94d..bb75a3d 100644
--- a/Help/command/target_link_directories.rst
+++ b/Help/command/target_link_directories.rst
@@ -1,6 +1,8 @@
 target_link_directories
 -----------------------
 
+.. versionadded:: 3.13
+
 Add link directories to a target.
 
 .. code-block:: cmake
diff --git a/Help/command/target_link_options.rst b/Help/command/target_link_options.rst
index 89038e3..e59e0e1 100644
--- a/Help/command/target_link_options.rst
+++ b/Help/command/target_link_options.rst
@@ -1,6 +1,8 @@
 target_link_options
 -------------------
 
+.. versionadded:: 3.13
+
 Add options to the link step for an executable, shared library or module
 library target.
 
diff --git a/Help/command/target_precompile_headers.rst b/Help/command/target_precompile_headers.rst
index d4280b1..7005180 100644
--- a/Help/command/target_precompile_headers.rst
+++ b/Help/command/target_precompile_headers.rst
@@ -1,6 +1,8 @@
 target_precompile_headers
 -------------------------
 
+.. versionadded:: 3.16
+
 Add a list of header files to precompile.
 
 Precompiling header files can speed up compilation by creating a partially
diff --git a/Help/command/target_sources.rst b/Help/command/target_sources.rst
index 27e737b..653b8d7 100644
--- a/Help/command/target_sources.rst
+++ b/Help/command/target_sources.rst
@@ -1,6 +1,8 @@
 target_sources
 --------------
 
+.. versionadded:: 3.1
+
 Add sources to a target.
 
 .. code-block:: cmake
@@ -9,19 +11,21 @@
     <INTERFACE|PUBLIC|PRIVATE> [items1...]
     [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
 
-Specifies sources to use when compiling a given target.  Relative
-source file paths are interpreted as being relative to the current
+Specifies sources to use when building a target and/or its dependents.
+Relative source file paths are interpreted as being relative to the current
 source directory (i.e. :variable:`CMAKE_CURRENT_SOURCE_DIR`).  The
 named ``<target>`` must have been created by a command such as
 :command:`add_executable` or :command:`add_library` and must not be an
 :ref:`ALIAS target <Alias Targets>`.
 
 The ``INTERFACE``, ``PUBLIC`` and ``PRIVATE`` keywords are required to
-specify the scope of the following arguments.  ``PRIVATE`` and ``PUBLIC``
+specify the scope of the items following them.  ``PRIVATE`` and ``PUBLIC``
 items will populate the :prop_tgt:`SOURCES` property of
-``<target>``.  ``PUBLIC`` and ``INTERFACE`` items will populate the
-:prop_tgt:`INTERFACE_SOURCES` property of ``<target>``.
-(:ref:`IMPORTED targets <Imported Targets>` only support ``INTERFACE`` items.)
+``<target>``, which are used when building the target itself.
+``PUBLIC`` and ``INTERFACE`` items will populate the
+:prop_tgt:`INTERFACE_SOURCES` property of ``<target>``, which are used
+when building dependents.  (:ref:`IMPORTED targets <Imported Targets>`
+only support ``INTERFACE`` items because they are not build targets.)
 The following arguments specify sources.  Repeated calls for the same
 ``<target>`` append items in the order called.
 
diff --git a/Help/command/variable_watch.rst b/Help/command/variable_watch.rst
index ce69bcf..8293f5a 100644
--- a/Help/command/variable_watch.rst
+++ b/Help/command/variable_watch.rst
@@ -7,9 +7,42 @@
 
   variable_watch(<variable> [<command>])
 
-If the specified ``<variable>`` changes, a message will be printed
-to inform about the change.
+If the specified ``<variable>`` changes and no ``<command>`` is given,
+a message will be printed to inform about the change.
 
-Additionally, if ``<command>`` is given, this command will be executed.
+If ``<command>`` is given, this command will be executed instead.
 The command will receive the following arguments:
 ``COMMAND(<variable> <access> <value> <current_list_file> <stack>)``
+
+``<variable>``
+ Name of the variable being accessed.
+
+``<access>``
+ One of ``READ_ACCESS``, ``UNKNOWN_READ_ACCESS``, ``MODIFIED_ACCESS``,
+ ``UNKNOWN_MODIFIED_ACCESS``, or ``REMOVED_ACCESS``.  The ``UNKNOWN_``
+ values are only used when the variable has never been set.  Once set,
+ they are never used again during the same CMake run, even if the
+ variable is later unset.
+
+``<value>``
+ The value of the variable.  On a modification, this is the new
+ (modified) value of the variable.  On removal, the value is empty.
+
+``<current_list_file>``
+ Full path to the file doing the access.
+
+``<stack>``
+ List of absolute paths of all files currently on the stack of file
+ inclusion, with the bottom-most file first and the currently
+ processed file (that is, ``current_list_file``) last.
+
+Note that for some accesses such as :command:`list(APPEND)`, the watcher
+is executed twice, first with a read access and then with a write one.
+Also note that an :command:`if(DEFINED)` query on the variable does not
+register as an access and the watcher is not executed.
+
+Only non-cache variables can be watched using this command.  Access to
+cache variables is never watched.  However, the existence of a cache
+variable ``var`` causes accesses to the non-cache variable ``var`` to
+not use the ``UNKNOWN_`` prefix, even if a non-cache variable ``var``
+has never existed.
diff --git a/Help/cpack_gen/external.rst b/Help/cpack_gen/external.rst
index 406f6be..7ef1071 100644
--- a/Help/cpack_gen/external.rst
+++ b/Help/cpack_gen/external.rst
@@ -281,3 +281,10 @@
   It is invoked after (optional) staging took place and may
   run an external packaging tool. The script has access to
   the variables defined by the CPack config file.
+
+.. 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.
diff --git a/Help/cpack_gen/packagemaker.rst b/Help/cpack_gen/packagemaker.rst
index c2a450e..357eb73 100644
--- a/Help/cpack_gen/packagemaker.rst
+++ b/Help/cpack_gen/packagemaker.rst
@@ -29,7 +29,7 @@
 
 .. variable:: CPACK_PACKAGEMAKER_BACKGROUND
 
- Adds a background to Distribtion XML if specified. The value contains the
+ Adds a background to Distribution XML if specified. The value contains the
  path to image in ``Resources`` directory.
 
 .. variable:: CPACK_PACKAGEMAKER_BACKGROUND_ALIGNMENT
diff --git a/Help/cpack_gen/productbuild.rst b/Help/cpack_gen/productbuild.rst
index 82b79ae..fd99e5a 100644
--- a/Help/cpack_gen/productbuild.rst
+++ b/Help/cpack_gen/productbuild.rst
@@ -68,7 +68,7 @@
 
 .. variable:: CPACK_PRODUCTBUILD_BACKGROUND
 
- Adds a background to Distribtion XML if specified. The value contains the
+ Adds a background to Distribution XML if specified. The value contains the
  path to image in ``Resources`` directory.
 
 .. variable:: CPACK_PRODUCTBUILD_BACKGROUND_ALIGNMENT
diff --git a/Help/dev/maint.rst b/Help/dev/maint.rst
index a1c1a6f..4c2c89f 100644
--- a/Help/dev/maint.rst
+++ b/Help/dev/maint.rst
@@ -200,6 +200,23 @@
   Add section headers similar to the $prev release notes and move each
   individual bullet into an appropriate section.  Revise a few bullets.
 
+Update Sphinx ``versionadded`` directives in documents added since
+the previous release by running the `update_versions.py`_ script:
+
+.. code-block:: shell
+
+  Utilities/Sphinx/update_versions.py --since v$prev.0 --overwrite
+
+.. _`update_versions.py`: ../../Utilities/Sphinx/update_versions.py
+
+Commit the changes with a message such as::
+
+  Help: Update Sphinx versionadded directives for $ver release
+
+  Run the script:
+
+      Utilities/Sphinx/update_versions.py --since v$prev.0 --overwrite
+
 Open a merge request with the ``doc-$ver-relnotes`` branch for review
 and integration.  Further steps may proceed after this has been merged
 to ``master``.
@@ -299,3 +316,28 @@
   before staging or merging.
 
 .. _`CMake Discourse Forum Development Category`: https://discourse.cmake.org/c/development
+
+Initial Post-Release Development
+--------------------------------
+
+Deprecate policies more than 8 release series old by updating the
+policy range check in ``cmMakefile::SetPolicy``.
+Commit with a message such as::
+
+  Add deprecation warnings for policies CMP#### and below
+
+  The OLD behaviors of all policies are deprecated, but only by
+  documentation.  Add an explicit deprecation diagnostic for policies
+  introduced in CMake $OLDVER and below to encourage projects to port
+  away from setting policies to OLD.
+
+Update the ``cmake_policy`` version range generated by ``install(EXPORT)``
+in ``cmExportFileGenerator::GeneratePolicyHeaderCode`` to end at the
+previous release.  We use one release back since we now know all the
+policies added for that version.  Commit with a message such as::
+
+  export: Increase maximum policy version in exported files to $prev
+
+  The files generatd by `install(EXPORT)` and `export()` commands
+  are known to work with policies as of CMake $prev, so enable them
+  in sufficiently new CMake versions.
diff --git a/Help/dev/review.rst b/Help/dev/review.rst
index 6c7e92c..f2a91c0 100644
--- a/Help/dev/review.rst
+++ b/Help/dev/review.rst
@@ -260,7 +260,7 @@
 If the commit is a fix for the mentioned commit, consider using a ``Fixes:``
 trailer in the commit message with the specified format. This trailer should
 not be word-wrapped. Note that if there is also an issue for what is being
-fixed, it is preferrable to link to the issue instead.
+fixed, it is preferable to link to the issue instead.
 
 If relevant, add the first release tag of CMake containing the commit after
 the ``<date>``, i.e., ``commit <shorthash> (<subject>, <date>, <tag>)``.
diff --git a/Help/dev/source.rst b/Help/dev/source.rst
index 0ccb8f4..d93e55c 100644
--- a/Help/dev/source.rst
+++ b/Help/dev/source.rst
@@ -35,6 +35,9 @@
 
 * From ``C++14``:
 
+  * ``<cm/iomanip>``:
+    ``cm::quoted``
+
   * ``<cm/iterator>``:
     ``cm::make_reverse_iterator``, ``cm::cbegin``, ``cm::cend``,
     ``cm::rbegin``, ``cm::rend``, ``cm::crbegin``, ``cm::crend``
@@ -53,6 +56,9 @@
   * ``<cm/algorithm>``:
     ``cm::clamp``
 
+  * ``cm/filesystem>``:
+    ``cm::filesystem::path``
+
   * ``<cm/iterator>``:
     ``cm::size``, ``cm::empty``, ``cm::data``
 
diff --git a/Help/envvar/ASM_DIALECT.rst b/Help/envvar/ASM_DIALECT.rst
index a06e3cb..a606280 100644
--- a/Help/envvar/ASM_DIALECT.rst
+++ b/Help/envvar/ASM_DIALECT.rst
@@ -1,6 +1,8 @@
 ASM<DIALECT>
 ------------
 
+.. versionadded:: 3.10
+
 .. include:: ENV_VAR.txt
 
 Preferred executable for compiling a specific dialect of assembly language
@@ -12,3 +14,11 @@
 :variable:`CMAKE_ASM<DIALECT>_COMPILER <CMAKE_<LANG>_COMPILER>`. For subsequent
 configuration runs, the environment variable will be ignored in favor of
 :variable:`CMAKE_ASM<DIALECT>_COMPILER <CMAKE_<LANG>_COMPILER>`.
+
+.. note::
+  Options that are required to make the compiler work correctly can be included;
+  they can not be changed.
+
+.. code-block:: console
+
+  $ export ASM="custom-compiler --arg1 --arg2"
diff --git a/Help/envvar/ASM_DIALECTFLAGS.rst b/Help/envvar/ASM_DIALECTFLAGS.rst
index 2e1c6d2..66a75e2 100644
--- a/Help/envvar/ASM_DIALECTFLAGS.rst
+++ b/Help/envvar/ASM_DIALECTFLAGS.rst
@@ -1,6 +1,8 @@
 ASM<DIALECT>FLAGS
 -----------------
 
+.. versionadded:: 3.10
+
 .. include:: ENV_VAR.txt
 
 Default compilation flags to be used when compiling a specific dialect of an
diff --git a/Help/envvar/CC.rst b/Help/envvar/CC.rst
index ef12059..4c970b4 100644
--- a/Help/envvar/CC.rst
+++ b/Help/envvar/CC.rst
@@ -1,6 +1,8 @@
 CC
 --
 
+.. versionadded:: 3.10
+
 .. include:: ENV_VAR.txt
 
 Preferred executable for compiling ``C`` language files. Will only be used by
@@ -9,3 +11,11 @@
 :variable:`CMAKE_C_COMPILER <CMAKE_<LANG>_COMPILER>`. For any configuration run
 (including the first), the environment variable will be ignored if the
 :variable:`CMAKE_C_COMPILER <CMAKE_<LANG>_COMPILER>` variable is defined.
+
+.. note::
+  Options that are required to make the compiler work correctly can be included;
+  they can not be changed.
+
+.. code-block:: console
+
+  $ export CC="custom-compiler --arg1 --arg2"
diff --git a/Help/envvar/CCMAKE_COLORS.rst b/Help/envvar/CCMAKE_COLORS.rst
index d4750c3..4e76bf8 100644
--- a/Help/envvar/CCMAKE_COLORS.rst
+++ b/Help/envvar/CCMAKE_COLORS.rst
@@ -1,6 +1,8 @@
 CCMAKE_COLORS
 -------------
 
+.. versionadded:: 3.18
+
 Determines what colors are used by the CMake curses interface,
 when run on a terminal that supports colors.
 The syntax follows the same conventions as ``LS_COLORS``;
diff --git a/Help/envvar/CFLAGS.rst b/Help/envvar/CFLAGS.rst
index 190b4f4..31db6a6 100644
--- a/Help/envvar/CFLAGS.rst
+++ b/Help/envvar/CFLAGS.rst
@@ -1,6 +1,8 @@
 CFLAGS
 ------
 
+.. versionadded:: 3.10
+
 .. include:: ENV_VAR.txt
 
 Default compilation flags to be used when compiling ``C`` files. Will only be
diff --git a/Help/envvar/CMAKE_BUILD_PARALLEL_LEVEL.rst b/Help/envvar/CMAKE_BUILD_PARALLEL_LEVEL.rst
index 199ca3e..dbc589a 100644
--- a/Help/envvar/CMAKE_BUILD_PARALLEL_LEVEL.rst
+++ b/Help/envvar/CMAKE_BUILD_PARALLEL_LEVEL.rst
@@ -1,6 +1,8 @@
 CMAKE_BUILD_PARALLEL_LEVEL
 --------------------------
 
+.. versionadded:: 3.12
+
 .. include:: ENV_VAR.txt
 
 Specifies the maximum number of concurrent processes to use when building
diff --git a/Help/envvar/CMAKE_CONFIG_TYPE.rst b/Help/envvar/CMAKE_CONFIG_TYPE.rst
index 168593d..c207a48 100644
--- a/Help/envvar/CMAKE_CONFIG_TYPE.rst
+++ b/Help/envvar/CMAKE_CONFIG_TYPE.rst
@@ -1,6 +1,8 @@
 CMAKE_CONFIG_TYPE
 -----------------
 
+.. versionadded:: 3.10
+
 .. include:: ENV_VAR.txt
 
 The default build configuration for :ref:`Build Tool Mode` and
diff --git a/Help/envvar/CMAKE_EXPORT_COMPILE_COMMANDS.rst b/Help/envvar/CMAKE_EXPORT_COMPILE_COMMANDS.rst
index e9e0810..9e678be 100644
--- a/Help/envvar/CMAKE_EXPORT_COMPILE_COMMANDS.rst
+++ b/Help/envvar/CMAKE_EXPORT_COMPILE_COMMANDS.rst
@@ -1,6 +1,8 @@
 CMAKE_EXPORT_COMPILE_COMMANDS
 -----------------------------
 
+.. versionadded:: 3.17
+
 .. include:: ENV_VAR.txt
 
 The default value for :variable:`CMAKE_EXPORT_COMPILE_COMMANDS` when there
diff --git a/Help/envvar/CMAKE_GENERATOR.rst b/Help/envvar/CMAKE_GENERATOR.rst
index f2d055f..3488b04 100644
--- a/Help/envvar/CMAKE_GENERATOR.rst
+++ b/Help/envvar/CMAKE_GENERATOR.rst
@@ -1,6 +1,8 @@
 CMAKE_GENERATOR
 ---------------
 
+.. versionadded:: 3.15
+
 .. include:: ENV_VAR.txt
 
 Specifies the CMake default generator to use when no generator is supplied
diff --git a/Help/envvar/CMAKE_GENERATOR_INSTANCE.rst b/Help/envvar/CMAKE_GENERATOR_INSTANCE.rst
index 1654fa1..8ca7d80 100644
--- a/Help/envvar/CMAKE_GENERATOR_INSTANCE.rst
+++ b/Help/envvar/CMAKE_GENERATOR_INSTANCE.rst
@@ -1,6 +1,8 @@
 CMAKE_GENERATOR_INSTANCE
 ------------------------
 
+.. versionadded:: 3.15
+
 .. include:: ENV_VAR.txt
 
 Default value for :variable:`CMAKE_GENERATOR_INSTANCE` if no Cache entry is
diff --git a/Help/envvar/CMAKE_GENERATOR_PLATFORM.rst b/Help/envvar/CMAKE_GENERATOR_PLATFORM.rst
index 917b30b..b039845 100644
--- a/Help/envvar/CMAKE_GENERATOR_PLATFORM.rst
+++ b/Help/envvar/CMAKE_GENERATOR_PLATFORM.rst
@@ -1,6 +1,8 @@
 CMAKE_GENERATOR_PLATFORM
 ------------------------
 
+.. versionadded:: 3.15
+
 .. include:: ENV_VAR.txt
 
 Default value for :variable:`CMAKE_GENERATOR_PLATFORM` if no Cache entry
diff --git a/Help/envvar/CMAKE_GENERATOR_TOOLSET.rst b/Help/envvar/CMAKE_GENERATOR_TOOLSET.rst
index 7ac3856..394dd88 100644
--- a/Help/envvar/CMAKE_GENERATOR_TOOLSET.rst
+++ b/Help/envvar/CMAKE_GENERATOR_TOOLSET.rst
@@ -1,6 +1,8 @@
 CMAKE_GENERATOR_TOOLSET
 -----------------------
 
+.. versionadded:: 3.15
+
 .. include:: ENV_VAR.txt
 
 Default value for :variable:`CMAKE_GENERATOR_TOOLSET` if no Cache entry
diff --git a/Help/envvar/CMAKE_LANG_COMPILER_LAUNCHER.rst b/Help/envvar/CMAKE_LANG_COMPILER_LAUNCHER.rst
index 4f91e9a..c384fa1 100644
--- a/Help/envvar/CMAKE_LANG_COMPILER_LAUNCHER.rst
+++ b/Help/envvar/CMAKE_LANG_COMPILER_LAUNCHER.rst
@@ -1,6 +1,8 @@
 CMAKE_<LANG>_COMPILER_LAUNCHER
 ------------------------------
 
+.. versionadded:: 3.17
+
 .. include:: ENV_VAR.txt
 
 Default compiler launcher to use for the specified language. Will only be used
diff --git a/Help/envvar/CMAKE_MSVCIDE_RUN_PATH.rst b/Help/envvar/CMAKE_MSVCIDE_RUN_PATH.rst
index 77ead4d..5babbe5 100644
--- a/Help/envvar/CMAKE_MSVCIDE_RUN_PATH.rst
+++ b/Help/envvar/CMAKE_MSVCIDE_RUN_PATH.rst
@@ -1,6 +1,8 @@
 CMAKE_MSVCIDE_RUN_PATH
 ----------------------
 
+.. versionadded:: 3.10
+
 .. include:: ENV_VAR.txt
 
 Extra PATH locations for custom commands when using
diff --git a/Help/envvar/CMAKE_NO_VERBOSE.rst b/Help/envvar/CMAKE_NO_VERBOSE.rst
index 149efbd..fe733f8 100644
--- a/Help/envvar/CMAKE_NO_VERBOSE.rst
+++ b/Help/envvar/CMAKE_NO_VERBOSE.rst
@@ -1,6 +1,8 @@
 CMAKE_NO_VERBOSE
 ----------------
 
+.. versionadded:: 3.14
+
 Disables verbose output from CMake when :envvar:`VERBOSE` environment variable
 is set.
 
diff --git a/Help/envvar/CMAKE_OSX_ARCHITECTURES.rst b/Help/envvar/CMAKE_OSX_ARCHITECTURES.rst
index ef7d547..4bfa36a 100644
--- a/Help/envvar/CMAKE_OSX_ARCHITECTURES.rst
+++ b/Help/envvar/CMAKE_OSX_ARCHITECTURES.rst
@@ -1,6 +1,8 @@
 CMAKE_OSX_ARCHITECTURES
 -----------------------
 
+.. versionadded:: 3.10
+
 .. include:: ENV_VAR.txt
 
 Target specific architectures for macOS.
diff --git a/Help/envvar/CMAKE_PREFIX_PATH.rst b/Help/envvar/CMAKE_PREFIX_PATH.rst
index 276fdd6..e5d6aa1 100644
--- a/Help/envvar/CMAKE_PREFIX_PATH.rst
+++ b/Help/envvar/CMAKE_PREFIX_PATH.rst
@@ -1,6 +1,8 @@
 CMAKE_PREFIX_PATH
 -----------------
 
+.. versionadded:: 3.18
+
 .. include:: ENV_VAR.txt
 
 The ``CMAKE_PREFIX_PATH`` environment variable may be set to a list of
diff --git a/Help/envvar/CSFLAGS.rst b/Help/envvar/CSFLAGS.rst
index 8762982..d875209 100644
--- a/Help/envvar/CSFLAGS.rst
+++ b/Help/envvar/CSFLAGS.rst
@@ -1,9 +1,11 @@
 CSFLAGS
 -------
 
+.. versionadded:: 3.10
+
 .. include:: ENV_VAR.txt
 
-Preferred executable for compiling ``CSharp`` language files. Will only be
+Default compilation flags to be used when compiling ``CSharp`` files. Will only be
 used by CMake on the first configuration to determine ``CSharp`` default
 compilation flags, after which the value for ``CSFLAGS`` is stored in the cache
 as :variable:`CMAKE_CSharp_FLAGS <CMAKE_<LANG>_FLAGS>`. For any configuration
diff --git a/Help/envvar/CTEST_INTERACTIVE_DEBUG_MODE.rst b/Help/envvar/CTEST_INTERACTIVE_DEBUG_MODE.rst
index e1991b2..b27bc09 100644
--- a/Help/envvar/CTEST_INTERACTIVE_DEBUG_MODE.rst
+++ b/Help/envvar/CTEST_INTERACTIVE_DEBUG_MODE.rst
@@ -1,6 +1,8 @@
 CTEST_INTERACTIVE_DEBUG_MODE
 ----------------------------
 
+.. versionadded:: 3.10
+
 .. include:: ENV_VAR.txt
 
 Environment variable that will exist and be set to ``1`` when a test executed
diff --git a/Help/envvar/CTEST_OUTPUT_ON_FAILURE.rst b/Help/envvar/CTEST_OUTPUT_ON_FAILURE.rst
index d8b4262..9c6bd03 100644
--- a/Help/envvar/CTEST_OUTPUT_ON_FAILURE.rst
+++ b/Help/envvar/CTEST_OUTPUT_ON_FAILURE.rst
@@ -1,6 +1,8 @@
 CTEST_OUTPUT_ON_FAILURE
 -----------------------
 
+.. versionadded:: 3.10
+
 .. include:: ENV_VAR.txt
 
 Boolean environment variable that controls if the output should be logged for
diff --git a/Help/envvar/CTEST_PARALLEL_LEVEL.rst b/Help/envvar/CTEST_PARALLEL_LEVEL.rst
index fd4936e..a21c783 100644
--- a/Help/envvar/CTEST_PARALLEL_LEVEL.rst
+++ b/Help/envvar/CTEST_PARALLEL_LEVEL.rst
@@ -1,6 +1,8 @@
 CTEST_PARALLEL_LEVEL
 --------------------
 
+.. versionadded:: 3.10
+
 .. include:: ENV_VAR.txt
 
 Specify the number of tests for CTest to run in parallel. See :manual:`ctest(1)`
diff --git a/Help/envvar/CTEST_PROGRESS_OUTPUT.rst b/Help/envvar/CTEST_PROGRESS_OUTPUT.rst
index b36a6b8..8c29d7d 100644
--- a/Help/envvar/CTEST_PROGRESS_OUTPUT.rst
+++ b/Help/envvar/CTEST_PROGRESS_OUTPUT.rst
@@ -1,6 +1,8 @@
 CTEST_PROGRESS_OUTPUT
 ---------------------
 
+.. versionadded:: 3.13
+
 .. include:: ENV_VAR.txt
 
 Boolean environment variable that affects how :manual:`ctest <ctest(1)>`
diff --git a/Help/envvar/CTEST_USE_LAUNCHERS_DEFAULT.rst b/Help/envvar/CTEST_USE_LAUNCHERS_DEFAULT.rst
index 79dbb79..dffd63d 100644
--- a/Help/envvar/CTEST_USE_LAUNCHERS_DEFAULT.rst
+++ b/Help/envvar/CTEST_USE_LAUNCHERS_DEFAULT.rst
@@ -1,6 +1,8 @@
 CTEST_USE_LAUNCHERS_DEFAULT
 ---------------------------
 
+.. versionadded:: 3.10
+
 .. include:: ENV_VAR.txt
 
 Initializes the :variable:`CTEST_USE_LAUNCHERS` variable if not already defined.
diff --git a/Help/envvar/CUDACXX.rst b/Help/envvar/CUDACXX.rst
index 10c0f9d..69471b0 100644
--- a/Help/envvar/CUDACXX.rst
+++ b/Help/envvar/CUDACXX.rst
@@ -1,6 +1,8 @@
 CUDACXX
 -------
 
+.. versionadded:: 3.10
+
 .. include:: ENV_VAR.txt
 
 Preferred executable for compiling ``CUDA`` language files. Will only be used by
@@ -9,3 +11,11 @@
 :variable:`CMAKE_CUDA_COMPILER <CMAKE_<LANG>_COMPILER>`. For any configuration
 run (including the first), the environment variable will be ignored if the
 :variable:`CMAKE_CUDA_COMPILER <CMAKE_<LANG>_COMPILER>` variable is defined.
+
+.. note::
+  Options that are required to make the compiler work correctly can be included;
+  they can not be changed.
+
+.. code-block:: console
+
+  $ export CUDACXX="custom-compiler --arg1 --arg2"
diff --git a/Help/envvar/CUDAFLAGS.rst b/Help/envvar/CUDAFLAGS.rst
index 14c5d84..1f1bde5 100644
--- a/Help/envvar/CUDAFLAGS.rst
+++ b/Help/envvar/CUDAFLAGS.rst
@@ -1,6 +1,8 @@
 CUDAFLAGS
 ---------
 
+.. versionadded:: 3.10
+
 .. include:: ENV_VAR.txt
 
 Default compilation flags to be used when compiling ``CUDA`` files. Will only be
diff --git a/Help/envvar/CUDAHOSTCXX.rst b/Help/envvar/CUDAHOSTCXX.rst
index b9f65bd..81c1228 100644
--- a/Help/envvar/CUDAHOSTCXX.rst
+++ b/Help/envvar/CUDAHOSTCXX.rst
@@ -1,6 +1,8 @@
 CUDAHOSTCXX
 -----------
 
+.. versionadded:: 3.10
+
 .. include:: ENV_VAR.txt
 
 Preferred executable for compiling host code when compiling ``CUDA``
diff --git a/Help/envvar/CXX.rst b/Help/envvar/CXX.rst
index d655350..908a521 100644
--- a/Help/envvar/CXX.rst
+++ b/Help/envvar/CXX.rst
@@ -1,6 +1,8 @@
 CXX
 ---
 
+.. versionadded:: 3.10
+
 .. include:: ENV_VAR.txt
 
 Preferred executable for compiling ``CXX`` language files. Will only be used by
@@ -9,3 +11,11 @@
 :variable:`CMAKE_CXX_COMPILER <CMAKE_<LANG>_COMPILER>`. For any configuration
 run (including the first), the environment variable will be ignored if the
 :variable:`CMAKE_CXX_COMPILER <CMAKE_<LANG>_COMPILER>` variable is defined.
+
+.. note::
+  Options that are required to make the compiler work correctly can be included;
+  they can not be changed.
+
+.. code-block:: console
+
+  $ export CXX="custom-compiler --arg1 --arg2"
diff --git a/Help/envvar/CXXFLAGS.rst b/Help/envvar/CXXFLAGS.rst
index 460a347..a3cef77 100644
--- a/Help/envvar/CXXFLAGS.rst
+++ b/Help/envvar/CXXFLAGS.rst
@@ -1,6 +1,8 @@
 CXXFLAGS
 --------
 
+.. versionadded:: 3.10
+
 .. include:: ENV_VAR.txt
 
 Default compilation flags to be used when compiling ``CXX`` (C++) files. Will
diff --git a/Help/envvar/DASHBOARD_TEST_FROM_CTEST.rst b/Help/envvar/DASHBOARD_TEST_FROM_CTEST.rst
index 6a52d64..7635342 100644
--- a/Help/envvar/DASHBOARD_TEST_FROM_CTEST.rst
+++ b/Help/envvar/DASHBOARD_TEST_FROM_CTEST.rst
@@ -1,6 +1,8 @@
 DASHBOARD_TEST_FROM_CTEST
 -------------------------
 
+.. versionadded:: 3.10
+
 .. include:: ENV_VAR.txt
 
 Environment variable that will exist when a test executed by :manual:`ctest(1)`
diff --git a/Help/envvar/DESTDIR.rst b/Help/envvar/DESTDIR.rst
index d2144ae..ee290f2 100644
--- a/Help/envvar/DESTDIR.rst
+++ b/Help/envvar/DESTDIR.rst
@@ -1,6 +1,8 @@
 DESTDIR
 -------
 
+.. versionadded:: 3.12
+
 .. include:: ENV_VAR.txt
 
 On UNIX one can use the ``DESTDIR`` mechanism in order to relocate the
diff --git a/Help/envvar/FC.rst b/Help/envvar/FC.rst
index d6cabbc..dcee02d 100644
--- a/Help/envvar/FC.rst
+++ b/Help/envvar/FC.rst
@@ -1,6 +1,8 @@
 FC
 --
 
+.. versionadded:: 3.10
+
 .. include:: ENV_VAR.txt
 
 Preferred executable for compiling ``Fortran`` language files. Will only be used
@@ -10,3 +12,11 @@
 configuration run (including the first), the environment variable will be
 ignored if the :variable:`CMAKE_Fortran_COMPILER <CMAKE_<LANG>_COMPILER>`
 variable is defined.
+
+.. note::
+  Options that are required to make the compiler work correctly can be included;
+  they can not be changed.
+
+.. code-block:: console
+
+  $ export FC="custom-compiler --arg1 --arg2"
diff --git a/Help/envvar/FFLAGS.rst b/Help/envvar/FFLAGS.rst
index 53bffb6..4c1f3d2 100644
--- a/Help/envvar/FFLAGS.rst
+++ b/Help/envvar/FFLAGS.rst
@@ -1,6 +1,8 @@
 FFLAGS
 ------
 
+.. versionadded:: 3.10
+
 .. include:: ENV_VAR.txt
 
 Default compilation flags to be used when compiling ``Fortran`` files. Will only
diff --git a/Help/envvar/LDFLAGS.rst b/Help/envvar/LDFLAGS.rst
index 816d6ef..78b34f4 100644
--- a/Help/envvar/LDFLAGS.rst
+++ b/Help/envvar/LDFLAGS.rst
@@ -1,6 +1,8 @@
 LDFLAGS
 -------
 
+.. versionadded:: 3.10
+
 .. include:: ENV_VAR.txt
 
 Will only be used by CMake on the first configuration to determine the default
diff --git a/Help/envvar/MACOSX_DEPLOYMENT_TARGET.rst b/Help/envvar/MACOSX_DEPLOYMENT_TARGET.rst
index 662bd03..1558704 100644
--- a/Help/envvar/MACOSX_DEPLOYMENT_TARGET.rst
+++ b/Help/envvar/MACOSX_DEPLOYMENT_TARGET.rst
@@ -1,6 +1,8 @@
 MACOSX_DEPLOYMENT_TARGET
 ------------------------
 
+.. versionadded:: 3.10
+
 .. include:: ENV_VAR.txt
 
 Specify the minimum version of macOS on which the target binaries are
diff --git a/Help/envvar/OBJC.rst b/Help/envvar/OBJC.rst
index 30c0d13..2d95806 100644
--- a/Help/envvar/OBJC.rst
+++ b/Help/envvar/OBJC.rst
@@ -1,6 +1,8 @@
 OBJC
 ----
 
+.. versionadded:: 3.16.7
+
 .. include:: ENV_VAR.txt
 
 Preferred executable for compiling ``OBJC`` language files. Will only be used
diff --git a/Help/envvar/OBJCXX.rst b/Help/envvar/OBJCXX.rst
index a72f7e7..71286d9 100644
--- a/Help/envvar/OBJCXX.rst
+++ b/Help/envvar/OBJCXX.rst
@@ -1,6 +1,8 @@
 OBJCXX
 ------
 
+.. versionadded:: 3.16.7
+
 .. include:: ENV_VAR.txt
 
 Preferred executable for compiling ``OBJCXX`` language files. Will only be used
diff --git a/Help/envvar/PackageName_ROOT.rst b/Help/envvar/PackageName_ROOT.rst
index 82b0a06..fc2a1d5 100644
--- a/Help/envvar/PackageName_ROOT.rst
+++ b/Help/envvar/PackageName_ROOT.rst
@@ -1,6 +1,8 @@
 <PackageName>_ROOT
 ------------------
 
+.. versionadded:: 3.12.1
+
 .. include:: ENV_VAR.txt
 
 Calls to :command:`find_package(<PackageName>)` will search in prefixes
diff --git a/Help/envvar/RC.rst b/Help/envvar/RC.rst
index 557520e..adfaecc 100644
--- a/Help/envvar/RC.rst
+++ b/Help/envvar/RC.rst
@@ -1,6 +1,8 @@
 RC
 --
 
+.. versionadded:: 3.10
+
 .. include:: ENV_VAR.txt
 
 Preferred executable for compiling ``resource`` files. Will only be used by CMake
@@ -9,3 +11,11 @@
 :variable:`CMAKE_RC_COMPILER <CMAKE_<LANG>_COMPILER>`. For any configuration run
 (including the first), the environment variable will be ignored if the
 :variable:`CMAKE_RC_COMPILER <CMAKE_<LANG>_COMPILER>` variable is defined.
+
+.. note::
+  Options that are required to make the compiler work correctly can be included;
+  they can not be changed.
+
+.. code-block:: console
+
+  $ export RC="custom-compiler --arg1 --arg2"
diff --git a/Help/envvar/RCFLAGS.rst b/Help/envvar/RCFLAGS.rst
index bc43cb2..f33a9a8 100644
--- a/Help/envvar/RCFLAGS.rst
+++ b/Help/envvar/RCFLAGS.rst
@@ -1,6 +1,8 @@
 RCFLAGS
 -------
 
+.. versionadded:: 3.10
+
 .. include:: ENV_VAR.txt
 
 Default compilation flags to be used when compiling ``resource`` files. Will
diff --git a/Help/envvar/SWIFTC.rst b/Help/envvar/SWIFTC.rst
index b12e51d..896e156 100644
--- a/Help/envvar/SWIFTC.rst
+++ b/Help/envvar/SWIFTC.rst
@@ -1,6 +1,8 @@
 SWIFTC
 ------
 
+.. versionadded:: 3.15
+
 .. include:: ENV_VAR.txt
 
 Preferred executable for compiling ``Swift`` language files. Will only be used by
@@ -9,3 +11,11 @@
 :variable:`CMAKE_Swift_COMPILER <CMAKE_<LANG>_COMPILER>`. For any configuration run
 (including the first), the environment variable will be ignored if the
 :variable:`CMAKE_Swift_COMPILER <CMAKE_<LANG>_COMPILER>` variable is defined.
+
+.. note::
+  Options that are required to make the compiler work correctly can be included;
+  they can not be changed.
+
+.. code-block:: console
+
+  $ export SWIFTC="custom-compiler --arg1 --arg2"
diff --git a/Help/envvar/VERBOSE.rst b/Help/envvar/VERBOSE.rst
index 2d775a5..5911951 100644
--- a/Help/envvar/VERBOSE.rst
+++ b/Help/envvar/VERBOSE.rst
@@ -1,6 +1,8 @@
 VERBOSE
 -------
 
+.. versionadded:: 3.14
+
 Activates verbose output from CMake and your build tools of choice when
 you start to actually build your project.
 
diff --git a/Help/generator/Green Hills MULTI.rst b/Help/generator/Green Hills MULTI.rst
index dffc679..2246699 100644
--- a/Help/generator/Green Hills MULTI.rst
+++ b/Help/generator/Green Hills MULTI.rst
@@ -1,6 +1,8 @@
 Green Hills MULTI
 -----------------
 
+.. versionadded:: 3.3
+
 Generates Green Hills MULTI project files (experimental, work-in-progress).
 
 The buildsystem has predetermined build-configuration settings that can be controlled
diff --git a/Help/generator/Ninja Multi-Config.rst b/Help/generator/Ninja Multi-Config.rst
index f480eb8..e6c7a1c 100644
--- a/Help/generator/Ninja Multi-Config.rst
+++ b/Help/generator/Ninja Multi-Config.rst
@@ -1,6 +1,8 @@
 Ninja Multi-Config
 ------------------
 
+.. versionadded:: 3.17
+
 Generates multiple ``build-<Config>.ninja`` files.
 
 This generator is very much like the :generator:`Ninja` generator, but with
diff --git a/Help/generator/Visual Studio 14 2015.rst b/Help/generator/Visual Studio 14 2015.rst
index 7383f7a..401845d 100644
--- a/Help/generator/Visual Studio 14 2015.rst
+++ b/Help/generator/Visual Studio 14 2015.rst
@@ -1,6 +1,8 @@
 Visual Studio 14 2015
 ---------------------
 
+.. versionadded:: 3.1
+
 Generates Visual Studio 14 (VS 2015) project files.
 
 Project Types
diff --git a/Help/generator/Visual Studio 15 2017.rst b/Help/generator/Visual Studio 15 2017.rst
index 7e6f0fb..e7baaad 100644
--- a/Help/generator/Visual Studio 15 2017.rst
+++ b/Help/generator/Visual Studio 15 2017.rst
@@ -1,6 +1,8 @@
 Visual Studio 15 2017
 ---------------------
 
+.. versionadded:: 3.7.1
+
 Generates Visual Studio 15 (VS 2017) project files.
 
 Project Types
diff --git a/Help/generator/Visual Studio 16 2019.rst b/Help/generator/Visual Studio 16 2019.rst
index 4aec7f7..3da8091 100644
--- a/Help/generator/Visual Studio 16 2019.rst
+++ b/Help/generator/Visual Studio 16 2019.rst
@@ -1,6 +1,8 @@
 Visual Studio 16 2019
 ---------------------
 
+.. versionadded:: 3.14
+
 Generates Visual Studio 16 (VS 2019) project files.
 
 Project Types
diff --git a/Help/guide/tutorial/Complete/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Complete/MathFunctions/CMakeLists.txt
index c911625..a47d5e0 100644
--- a/Help/guide/tutorial/Complete/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Complete/MathFunctions/CMakeLists.txt
@@ -57,7 +57,11 @@
 set_property(TARGET MathFunctions PROPERTY SOVERSION "1")
 
 # install rules
-install(TARGETS MathFunctions tutorial_compiler_flags
+set(installable_libs MathFunctions tutorial_compiler_flags)
+if(TARGET SqrtLibrary)
+  list(APPEND installable_libs SqrtLibrary)
+endif()
+install(TARGETS ${installable_libs}
         DESTINATION lib
         EXPORT MathFunctionsTargets)
 install(FILES MathFunctions.h DESTINATION include)
diff --git a/Help/guide/tutorial/Step10/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step10/MathFunctions/CMakeLists.txt
index e0c0621..0bfe20c 100644
--- a/Help/guide/tutorial/Step10/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step10/MathFunctions/CMakeLists.txt
@@ -47,5 +47,9 @@
 target_compile_definitions(MathFunctions PRIVATE "EXPORTING_MYMATH")
 
 # install rules
-install(TARGETS MathFunctions DESTINATION lib)
+set(installable_libs MathFunctions)
+if(TARGET SqrtLibrary)
+  list(APPEND installable_libs SqrtLibrary)
+endif()
+install(TARGETS ${installable_libs} DESTINATION lib)
 install(FILES MathFunctions.h DESTINATION include)
diff --git a/Help/guide/tutorial/Step11/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step11/MathFunctions/CMakeLists.txt
index 32f5e08..0d287ca 100644
--- a/Help/guide/tutorial/Step11/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step11/MathFunctions/CMakeLists.txt
@@ -51,5 +51,9 @@
 target_compile_definitions(MathFunctions PRIVATE "EXPORTING_MYMATH")
 
 # install rules
-install(TARGETS MathFunctions DESTINATION lib)
+set(installable_libs MathFunctions tutorial_compiler_flags)
+if(TARGET SqrtLibrary)
+  list(APPEND installable_libs SqrtLibrary)
+endif()
+install(TARGETS ${installable_libs} DESTINATION lib)
 install(FILES MathFunctions.h DESTINATION include)
diff --git a/Help/guide/tutorial/Step12/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step12/MathFunctions/CMakeLists.txt
index 720ee64..ea3861c 100644
--- a/Help/guide/tutorial/Step12/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step12/MathFunctions/CMakeLists.txt
@@ -53,7 +53,11 @@
 target_compile_definitions(MathFunctions PRIVATE "EXPORTING_MYMATH")
 
 # install rules
-install(TARGETS MathFunctions tutorial_compiler_flags
+set(installable_libs MathFunctions tutorial_compiler_flags)
+if(TARGET SqrtLibrary)
+  list(APPEND installable_libs SqrtLibrary)
+endif()
+install(TARGETS ${installable_libs}
         DESTINATION lib
         EXPORT MathFunctionsTargets)
 install(FILES MathFunctions.h DESTINATION include)
diff --git a/Help/guide/tutorial/index.rst b/Help/guide/tutorial/index.rst
index 6e26de9..665d123 100644
--- a/Help/guide/tutorial/index.rst
+++ b/Help/guide/tutorial/index.rst
@@ -81,8 +81,8 @@
 Next modify ``tutorial.cxx`` to include the configured header file,
 ``TutorialConfig.h``.
 
-Finally, let's print out the version number by updating ``tutorial.cxx`` as
-follows:
+Finally, let's print out the executable name and version number by updating
+``tutorial.cxx`` as follows:
 
 .. literalinclude:: Step2/tutorial.cxx
   :language: c++
@@ -106,7 +106,8 @@
 in CMake is by using the :variable:`CMAKE_CXX_STANDARD` variable. For this
 tutorial, set the :variable:`CMAKE_CXX_STANDARD` variable in the
 ``CMakeLists.txt`` file to 11 and :variable:`CMAKE_CXX_STANDARD_REQUIRED` to
-True:
+True. Make sure to add the ``CMAKE_CXX_STANDARD`` declarations above the call
+to ``add_executable``.
 
 .. literalinclude:: Step2/CMakeLists.txt
   :language: cmake
@@ -120,18 +121,28 @@
 with your chosen build tool.
 
 For example, from the command line we could navigate to the
-``Help/guide/tutorial`` directory of the CMake source code tree and run the
-following commands:
+``Help/guide/tutorial`` directory of the CMake source code tree and create a
+build directory:
 
 .. code-block:: console
 
   mkdir Step1_build
+
+Next, navigate to the build directory and run CMake to configure the project
+and generate a native build system:
+
+.. code-block:: console
+
   cd Step1_build
   cmake ../Step1
+
+Then call that build system to actually compile/link the project:
+
+.. code-block:: console
+
   cmake --build .
 
-Navigate to the directory where Tutorial was built (likely the make directory
-or a Debug or Release build configuration subdirectory) and run these commands:
+Finally, try to use the newly built ``Tutorial`` with these commands:
 
 .. code-block:: console
 
@@ -212,8 +223,9 @@
 classic approach when dealing with many optional components, we will cover
 the modern approach in the next step.
 
-The corresponding changes to the source code are fairly straightforward. First,
-in ``tutorial.cxx``, include the ``MathFunctions.h`` header if we need it:
+The corresponding changes to the source code are fairly straightforward.
+First, in ``tutorial.cxx``, include the ``MathFunctions.h`` header if we
+need it:
 
 .. literalinclude:: Step3/tutorial.cxx
   :language: c++
@@ -242,8 +254,17 @@
 :manual:`cmake-gui <cmake-gui(1)>` to configure the project and then build it
 with your chosen build tool. Then run the built Tutorial executable.
 
-Use the :manual:`ccmake <ccmake(1)>` executable or the :manual:`cmake-gui <cmake-gui(1)>`
-to update the value of ``USE_MYMATH``. Rebuild and run the tutorial again.
+Now let's update the value of ``USE_MYMATH``. The easiest way is to use the
+:manual:`cmake-gui <cmake-gui(1)>` or  :manual:`ccmake <ccmake(1)>` if you're
+in the terminal. Or, alternatively, if you want to change the option from the
+command-line, try:
+
+.. code-block:: console
+
+  cmake ../Step2 -DUSE_MYMATH=OFF
+
+Rebuild and run the tutorial again.
+
 Which function gives better results, sqrt or mysqrt?
 
 Adding Usage Requirements for Library (Step 3)
@@ -320,21 +341,32 @@
 
 That is all that is needed to create a basic local install of the tutorial.
 
-Run the :manual:`cmake  <cmake(1)>` executable or the
+Now run the :manual:`cmake  <cmake(1)>` executable or the
 :manual:`cmake-gui <cmake-gui(1)>` to configure the project and then build it
-with your chosen build tool. Run the install step by using the ``install``
-option of the :manual:`cmake  <cmake(1)>` command (introduced in 3.15, older
-versions of CMake must use ``make install``) from the command line, or build
-the ``INSTALL`` target from an IDE. This will install the appropriate header
-files, libraries, and executables.
+with your chosen build tool.
+
+Then run the install step by using the ``install`` option of the
+:manual:`cmake  <cmake(1)>` command (introduced in 3.15, older versions of
+CMake must use ``make install``) from the command line. For
+multi-configuration tools, don't forget to use the ``--config`` argument to
+specify the configuration. If using an IDE, simply build the ``INSTALL``
+target. This step will install the appropriate header files, libraries, and
+executables. For example:
+
+.. code-block:: console
+
+  cmake --install .
 
 The CMake variable :variable:`CMAKE_INSTALL_PREFIX` is used to determine the
-root of where the files will be installed. If using ``cmake --install`` a
-custom installation directory can be given via the ``--prefix`` argument. For
-multi-configuration tools, use the ``--config`` argument to specify the
-configuration.
+root of where the files will be installed. If using the ``cmake --install``
+command, the installation prefix can be overridden via the ``--prefix``
+argument. For example:
 
-Verify that the installed Tutorial runs.
+.. code-block:: console
+
+  cmake --install . --prefix "/home/myuser/installdir"
+
+Navigate to the install directory and verify that the installed Tutorial runs.
 
 Testing Support
 ---------------
@@ -520,6 +552,7 @@
 directories so that ``Table.h`` can be found and included by ``mysqrt.cxx``.
 
 .. literalinclude:: Step7/MathFunctions/CMakeLists.txt
+  :language: cmake
   :start-after: # state that we depend on our bin
   :end-before: # install rules
 
@@ -675,9 +708,9 @@
 
 Now that we have made MathFunctions always be used, we will need to update
 the logic of that library. So, in ``MathFunctions/CMakeLists.txt`` we need to
-create a SqrtLibrary that will conditionally be built when ``USE_MYMATH`` is
-enabled. Now, since this is a tutorial, we are going to explicitly require
-that SqrtLibrary is built statically.
+create a SqrtLibrary that will conditionally be built and installed when
+``USE_MYMATH`` is enabled. Now, since this is a tutorial, we are going to
+explicitly require that SqrtLibrary is built statically.
 
 The end result is that ``MathFunctions/CMakeLists.txt`` should look like:
 
@@ -703,7 +736,7 @@
 .. literalinclude:: Step10/MathFunctions/MathFunctions.h
   :language: c++
 
-At this point, if you build everything, you will notice that linking fails
+At this point, if you build everything, you may notice that linking fails
 as we are combining a static library without position independent code with a
 library that has position independent code. The solution to this is to
 explicitly set the :prop_tgt:`POSITION_INDEPENDENT_CODE` target property of
@@ -750,7 +783,7 @@
 :manual:`generator expressions <cmake-generator-expressions(7)>` is to
 conditionally add compiler flags, such as those for language levels or
 warnings. A nice pattern is to associate this information to an ``INTERFACE``
-target allowing this information to propagate. Lets start by constructing an
+target allowing this information to propagate. Let's start by constructing an
 ``INTERFACE`` target and specifying the required C++ standard level of ``11``
 instead of using :variable:`CMAKE_CXX_STANDARD`.
 
diff --git a/Help/manual/cmake-buildsystem.7.rst b/Help/manual/cmake-buildsystem.7.rst
index d8142a2..cd27316 100644
--- a/Help/manual/cmake-buildsystem.7.rst
+++ b/Help/manual/cmake-buildsystem.7.rst
@@ -922,8 +922,8 @@
 Interface Libraries
 -------------------
 
-An ``INTERFACE`` target has no :prop_tgt:`LOCATION` and is mutable, but is
-otherwise similar to an :prop_tgt:`IMPORTED` target.
+An ``INTERFACE`` library target does not compile sources and does not
+produce a library artifact on disk, so it has no :prop_tgt:`LOCATION`.
 
 It may specify usage requirements such as
 :prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES`,
@@ -937,11 +937,22 @@
 :command:`target_sources`, and :command:`target_link_libraries` commands
 may be used with ``INTERFACE`` libraries.
 
+Since CMake 3.19, an ``INTERFACE`` library target may optionally contain
+source files.  An interface library that contains source files will be
+included as a build target in the generated buildsystem.  It does not
+compile sources, but may contain custom commands to generate other sources.
+Additionally, IDEs will show the source files as part of the target for
+interactive reading and editing.
+
 A primary use-case for ``INTERFACE`` libraries is header-only libraries.
 
 .. code-block:: cmake
 
-  add_library(Eigen INTERFACE)
+  add_library(Eigen INTERFACE
+    src/eigen.h
+    src/vector.h
+    src/matrix.h
+    )
   target_include_directories(Eigen INTERFACE
     $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
     $<INSTALL_INTERFACE:include/Eigen>
@@ -975,25 +986,17 @@
 targets, and the complexity of compiler-specific flags is encapsulated in an
 ``INTERFACE`` library target.
 
-The properties permitted to be set on or read from an ``INTERFACE`` library
-are:
-
-* Properties matching ``INTERFACE_*``
-* Built-in properties matching ``COMPATIBLE_INTERFACE_*``
-* ``EXPORT_NAME``
-* ``EXPORT_PROPERTIES``
-* ``IMPORTED``
-* ``MANUALLY_ADDED_DEPENDENCIES``
-* ``NAME``
-* Properties matching ``IMPORTED_LIBNAME_*``
-* Properties matching ``MAP_IMPORTED_CONFIG_*``
-
 ``INTERFACE`` libraries may be installed and exported.  Any content they refer
 to must be installed separately:
 
 .. code-block:: cmake
 
-  add_library(Eigen INTERFACE)
+  set(Eigen_headers
+    src/eigen.h
+    src/vector.h
+    src/matrix.h
+    )
+  add_library(Eigen INTERFACE ${Eigen_headers})
   target_include_directories(Eigen INTERFACE
     $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
     $<INSTALL_INTERFACE:include/Eigen>
@@ -1003,9 +1006,6 @@
   install(EXPORT eigenExport NAMESPACE Upstream::
     DESTINATION lib/cmake/Eigen
   )
-  install(FILES
-      ${CMAKE_CURRENT_SOURCE_DIR}/src/eigen.h
-      ${CMAKE_CURRENT_SOURCE_DIR}/src/vector.h
-      ${CMAKE_CURRENT_SOURCE_DIR}/src/matrix.h
+  install(FILES ${Eigen_headers}
     DESTINATION include/Eigen
   )
diff --git a/Help/manual/cmake-file-api.7.rst b/Help/manual/cmake-file-api.7.rst
index cc50952..6876e1c 100644
--- a/Help/manual/cmake-file-api.7.rst
+++ b/Help/manual/cmake-file-api.7.rst
@@ -425,7 +425,7 @@
 
   {
     "kind": "codemodel",
-    "version": { "major": 2, "minor": 1 },
+    "version": { "major": 2, "minor": 2 },
     "paths": {
       "source": "/path/to/top-level-source-dir",
       "build": "/path/to/top-level-build-dir"
@@ -650,7 +650,8 @@
 ``type``
   A string specifying the type of the target.  The value is one of
   ``EXECUTABLE``, ``STATIC_LIBRARY``, ``SHARED_LIBRARY``,
-  ``MODULE_LIBRARY``, ``OBJECT_LIBRARY``, or ``UTILITY``.
+  ``MODULE_LIBRARY``, ``OBJECT_LIBRARY``, ``INTERFACE_LIBRARY``,
+  or ``UTILITY``.
 
 ``backtrace``
   Optional member that is present when a CMake language backtrace to
@@ -869,6 +870,26 @@
     A string specifying the language (e.g. ``C``, ``CXX``, ``Fortran``)
     of the toolchain is used to compile the source file.
 
+  ``languageStandard``
+    Optional member that is present when the language standard is set
+    explicitly (e.g. via :prop_tgt:`CXX_STANDARD`) or implicitly by
+    compile features.  Each entry is a JSON object with two members:
+
+    ``backtraces``
+      Optional member that is present when a CMake language backtrace to
+      the ``<LANG>_STANDARD`` setting is available.  If the language
+      standard was set implicitly by compile features those are used as
+      the backtrace(s).  It's possible for multiple compile features to
+      require the same language standard so there could be multiple
+      backtraces. The value is a JSON array with each entry being an
+      unsigned integer 0-based index into the ``backtraceGraph``
+      member's ``nodes`` array.
+
+    ``standard``
+      String representing the language standard.
+
+    This field was added in codemodel version 2.2.
+
   ``compileCommandFragments``
     Optional member that is present when fragments of the compiler command
     line invocation are available.  The value is a JSON array of entries
diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst
index 124da44..c7f6b27 100644
--- a/Help/manual/cmake-generator-expressions.7.rst
+++ b/Help/manual/cmake-generator-expressions.7.rst
@@ -105,10 +105,11 @@
 
 ``$<TARGET_EXISTS:target>``
   ``1`` if ``target`` exists, else ``0``.
-``$<CONFIG:cfg>``
-  ``1`` if config is ``cfg``, else ``0``. This is a case-insensitive comparison.
-  The mapping in :prop_tgt:`MAP_IMPORTED_CONFIG_<CONFIG>` is also considered by
-  this expression when it is evaluated on a property on an :prop_tgt:`IMPORTED`
+``$<CONFIG:cfgs>``
+  ``1`` if config is any one of the entries in ``cfgs``, else ``0``. This is a
+  case-insensitive comparison. The mapping in
+  :prop_tgt:`MAP_IMPORTED_CONFIG_<CONFIG>` is also considered by this
+  expression when it is evaluated on a property on an :prop_tgt:`IMPORTED`
   target.
 ``$<PLATFORM_ID:platform_ids>``
   where ``platform_ids`` is a comma-separated list.
diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst
index e98038a..3ceb1df 100644
--- a/Help/manual/cmake-policies.7.rst
+++ b/Help/manual/cmake-policies.7.rst
@@ -57,6 +57,14 @@
 .. toctree::
    :maxdepth: 1
 
+   CMP0109: find_program() requires permission to execute but not to read. </policy/CMP0109>
+
+Policies Introduced by CMake 3.18
+=================================
+
+.. toctree::
+   :maxdepth: 1
+
    CMP0108: A target cannot link to itself through an alias. </policy/CMP0108>
    CMP0107: An ALIAS target cannot overwrite another target. </policy/CMP0107>
    CMP0106: The Documentation module is removed. </policy/CMP0106>
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index 4ce8365..d780a65 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -158,6 +158,7 @@
    /variable/CMAKE_AUTOMOC_RELAXED_MODE
    /variable/CMAKE_BACKWARDS_COMPATIBILITY
    /variable/CMAKE_BUILD_TYPE
+   /variable/CMAKE_CLANG_VFS_OVERLAY
    /variable/CMAKE_CODEBLOCKS_COMPILER_ID
    /variable/CMAKE_CODEBLOCKS_EXCLUDE_EXTERNAL_FILES
    /variable/CMAKE_CODELITE_USE_TARGETS
diff --git a/Help/manual/cmake.1.rst b/Help/manual/cmake.1.rst
index 9becfc6..c5e0aae 100644
--- a/Help/manual/cmake.1.rst
+++ b/Help/manual/cmake.1.rst
@@ -341,9 +341,9 @@
  Print a warning when an uninitialized variable is used.
 
 ``--warn-unused-vars``
- Warn about unused variables.
-
- Find variables that are declared or set, but not used.
+ Does nothing.  In CMake versions 3.2 and below this enabled warnings about
+ unused variables.  In CMake versions 3.3 through 3.18 the option was broken.
+ In CMake 3.19 and above the option has been removed.
 
 ``--no-warn-unused-cli``
  Don't warn about command line options.
@@ -359,7 +359,7 @@
  This flag tells CMake to warn about other files as well.
 
 ``--profiling-output=<path>``
- Used in conjuction with ``--profiling-format`` to output to a given path.
+ Used in conjunction with ``--profiling-format`` to output to a given path.
 
 ``--profiling-format=<file>``
  Enable the output of profiling data of CMake script in the given format.
@@ -450,6 +450,9 @@
 ``--component <comp>``
   Component-based install. Only install component ``<comp>``.
 
+``--default-directory-permissions <permissions>``
+  Default directory install permissions. Permissions in format ``<u=rwx,g=rx,o=rx>``.
+
 ``--prefix <prefix>``
   Override the installation prefix, :variable:`CMAKE_INSTALL_PREFIX`.
 
@@ -566,7 +569,8 @@
 
 ``compare_files [--ignore-eol] <file1> <file2>``
   Check if ``<file1>`` is same as ``<file2>``. If files are the same,
-  then returns ``0``, if not it returns ``1``.  The ``--ignore-eol`` option
+  then returns ``0``, if not it returns ``1``.  In case of invalid
+  arguments, it returns 2. The ``--ignore-eol`` option
   implies line-wise comparison and ignores LF/CRLF differences.
 
 ``copy <file>... <destination>``
@@ -594,6 +598,13 @@
   .. note::
     Path to where ``<new>`` symbolic link will be created has to exist beforehand.
 
+``create_hardlink <old> <new>``
+  Create a hard link ``<new>`` naming ``<old>``.
+
+  .. note::
+    Path to where ``<new>`` hard link will be created has to exist beforehand.
+    ``<old>`` has to exist beforehand.
+
 ``echo [<string>...]``
   Displays arguments as text.
 
diff --git a/Help/manual/ctest.1.rst b/Help/manual/ctest.1.rst
index d3ab75a..b5bb1c1 100644
--- a/Help/manual/ctest.1.rst
+++ b/Help/manual/ctest.1.rst
@@ -1333,7 +1333,7 @@
 ===================
 
 CTest provides a mechanism for tests to specify the resources that they need
-in a fine-grained way, and for users to specify the resources availiable on
+in a fine-grained way, and for users to specify the resources available on
 the running machine. This allows CTest to internally keep track of which
 resources are in use and which are free, scheduling tests in a way that
 prevents them from trying to claim resources that are not available.
diff --git a/Help/module/CPackArchive.rst b/Help/module/CPackArchive.rst
index 8616098..f5d6da4 100644
--- a/Help/module/CPackArchive.rst
+++ b/Help/module/CPackArchive.rst
@@ -1,4 +1,6 @@
 CPackArchive
 ------------
 
+.. versionadded:: 3.9
+
 The documentation for the CPack Archive generator has moved here: :cpack_gen:`CPack Archive Generator`
diff --git a/Help/module/CPackFreeBSD.rst b/Help/module/CPackFreeBSD.rst
index 69701b8..7ae6164 100644
--- a/Help/module/CPackFreeBSD.rst
+++ b/Help/module/CPackFreeBSD.rst
@@ -1,4 +1,6 @@
 CPackFreeBSD
 ------------
 
+.. versionadded:: 3.10
+
 The documentation for the CPack FreeBSD generator has moved here: :cpack_gen:`CPack FreeBSD Generator`
diff --git a/Help/module/CPackNuGet.rst b/Help/module/CPackNuGet.rst
index 4f39b3a..bbed7f9 100644
--- a/Help/module/CPackNuGet.rst
+++ b/Help/module/CPackNuGet.rst
@@ -1,4 +1,6 @@
 CPackNuGet
 ----------
 
+.. versionadded:: 3.12
+
 The documentation for the CPack NuGet generator has moved here: :cpack_gen:`CPack NuGet Generator`
diff --git a/Help/module/CPackProductBuild.rst b/Help/module/CPackProductBuild.rst
index 8cd9198..e12cd32 100644
--- a/Help/module/CPackProductBuild.rst
+++ b/Help/module/CPackProductBuild.rst
@@ -1,4 +1,6 @@
 CPackProductBuild
 -----------------
 
+.. versionadded:: 3.7
+
 The documentation for the CPack productbuild generator has moved here: :cpack_gen:`CPack productbuild Generator`
diff --git a/Help/policy/CMP0051.rst b/Help/policy/CMP0051.rst
index 6b679e5..053bc97 100644
--- a/Help/policy/CMP0051.rst
+++ b/Help/policy/CMP0051.rst
@@ -1,6 +1,8 @@
 CMP0051
 -------
 
+.. versionadded:: 3.1
+
 List TARGET_OBJECTS in SOURCES target property.
 
 CMake 3.0 and lower did not include the ``TARGET_OBJECTS``
diff --git a/Help/policy/CMP0052.rst b/Help/policy/CMP0052.rst
index ee2e6e8..c75f9ab 100644
--- a/Help/policy/CMP0052.rst
+++ b/Help/policy/CMP0052.rst
@@ -1,6 +1,8 @@
 CMP0052
 -------
 
+.. versionadded:: 3.1
+
 Reject source and build dirs in installed
 :prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES`.
 
diff --git a/Help/policy/CMP0053.rst b/Help/policy/CMP0053.rst
index 032b3e5..9b18b2d 100644
--- a/Help/policy/CMP0053.rst
+++ b/Help/policy/CMP0053.rst
@@ -1,6 +1,8 @@
 CMP0053
 -------
 
+.. versionadded:: 3.1
+
 Simplify variable reference and escape sequence evaluation.
 
 CMake 3.1 introduced a much faster implementation of evaluation of the
diff --git a/Help/policy/CMP0054.rst b/Help/policy/CMP0054.rst
index 1e000a6..c7ae019 100644
--- a/Help/policy/CMP0054.rst
+++ b/Help/policy/CMP0054.rst
@@ -1,6 +1,8 @@
 CMP0054
 -------
 
+.. versionadded:: 3.1
+
 Only interpret :command:`if` arguments as variables or keywords when unquoted.
 
 CMake 3.1 and above no longer implicitly dereference variables or
diff --git a/Help/policy/CMP0055.rst b/Help/policy/CMP0055.rst
index bc5ad08..47cac8e 100644
--- a/Help/policy/CMP0055.rst
+++ b/Help/policy/CMP0055.rst
@@ -1,6 +1,8 @@
 CMP0055
 -------
 
+.. versionadded:: 3.2
+
 Strict checking for the :command:`break` command.
 
 CMake 3.1 and lower allowed calls to the :command:`break` command
diff --git a/Help/policy/CMP0056.rst b/Help/policy/CMP0056.rst
index 834da84..628a6a1 100644
--- a/Help/policy/CMP0056.rst
+++ b/Help/policy/CMP0056.rst
@@ -1,6 +1,8 @@
 CMP0056
 -------
 
+.. versionadded:: 3.2
+
 Honor link flags in :command:`try_compile` source-file signature.
 
 The :command:`try_compile` command source-file signature generates a
diff --git a/Help/policy/CMP0057.rst b/Help/policy/CMP0057.rst
index 83db186..76aebfb 100644
--- a/Help/policy/CMP0057.rst
+++ b/Help/policy/CMP0057.rst
@@ -1,6 +1,8 @@
 CMP0057
 -------
 
+.. versionadded:: 3.3
+
 Support new :command:`if` IN_LIST operator.
 
 CMake 3.3 adds support for the new IN_LIST operator.
diff --git a/Help/policy/CMP0058.rst b/Help/policy/CMP0058.rst
index 05efd48..06cc74b 100644
--- a/Help/policy/CMP0058.rst
+++ b/Help/policy/CMP0058.rst
@@ -1,6 +1,8 @@
 CMP0058
 -------
 
+.. versionadded:: 3.3
+
 Ninja requires custom command byproducts to be explicit.
 
 When an intermediate file generated during the build is consumed
diff --git a/Help/policy/CMP0059.rst b/Help/policy/CMP0059.rst
index bce982e..6317d05 100644
--- a/Help/policy/CMP0059.rst
+++ b/Help/policy/CMP0059.rst
@@ -1,6 +1,8 @@
 CMP0059
 -------
 
+.. versionadded:: 3.3
+
 Do not treat ``DEFINITIONS`` as a built-in directory property.
 
 CMake 3.3 and above no longer make a list of definitions available through
diff --git a/Help/policy/CMP0060.rst b/Help/policy/CMP0060.rst
index 98ac2cf..09257d1 100644
--- a/Help/policy/CMP0060.rst
+++ b/Help/policy/CMP0060.rst
@@ -1,6 +1,8 @@
 CMP0060
 -------
 
+.. versionadded:: 3.3
+
 Link libraries by full path even in implicit directories.
 
 Policy :policy:`CMP0003` was introduced with the intention of always
diff --git a/Help/policy/CMP0061.rst b/Help/policy/CMP0061.rst
index 57e4161..aca551d 100644
--- a/Help/policy/CMP0061.rst
+++ b/Help/policy/CMP0061.rst
@@ -1,6 +1,8 @@
 CMP0061
 -------
 
+.. versionadded:: 3.3
+
 CTest does not by default tell ``make`` to ignore errors (``-i``).
 
 The :command:`ctest_build` and :command:`build_command` commands no
diff --git a/Help/policy/CMP0062.rst b/Help/policy/CMP0062.rst
index 0db7aaf..01e93f0 100644
--- a/Help/policy/CMP0062.rst
+++ b/Help/policy/CMP0062.rst
@@ -1,6 +1,8 @@
 CMP0062
 -------
 
+.. versionadded:: 3.3
+
 Disallow :command:`install` of :command:`export` result.
 
 The :command:`export()` command generates a file containing
diff --git a/Help/policy/CMP0063.rst b/Help/policy/CMP0063.rst
index d736d06..fec3ad8 100644
--- a/Help/policy/CMP0063.rst
+++ b/Help/policy/CMP0063.rst
@@ -1,6 +1,8 @@
 CMP0063
 -------
 
+.. versionadded:: 3.3
+
 Honor visibility properties for all target types.
 
 The :prop_tgt:`<LANG>_VISIBILITY_PRESET` and
diff --git a/Help/policy/CMP0064.rst b/Help/policy/CMP0064.rst
index e9a061b..0c20c13 100644
--- a/Help/policy/CMP0064.rst
+++ b/Help/policy/CMP0064.rst
@@ -1,6 +1,8 @@
 CMP0064
 -------
 
+.. versionadded:: 3.4
+
 Recognize ``TEST`` as a operator for the :command:`if` command.
 
 The ``TEST`` operator was added to the :command:`if` command to determine if a
diff --git a/Help/policy/CMP0065.rst b/Help/policy/CMP0065.rst
index b820aad..8968b91 100644
--- a/Help/policy/CMP0065.rst
+++ b/Help/policy/CMP0065.rst
@@ -1,6 +1,8 @@
 CMP0065
 -------
 
+.. versionadded:: 3.4
+
 Do not add flags to export symbols from executables without
 the :prop_tgt:`ENABLE_EXPORTS` target property.
 
diff --git a/Help/policy/CMP0066.rst b/Help/policy/CMP0066.rst
index e110ae1..b08430f 100644
--- a/Help/policy/CMP0066.rst
+++ b/Help/policy/CMP0066.rst
@@ -1,6 +1,8 @@
 CMP0066
 -------
 
+.. versionadded:: 3.7
+
 Honor per-config flags in :command:`try_compile` source-file signature.
 
 The source file signature of the :command:`try_compile` command uses the value
diff --git a/Help/policy/CMP0067.rst b/Help/policy/CMP0067.rst
index f802787..8358bb2 100644
--- a/Help/policy/CMP0067.rst
+++ b/Help/policy/CMP0067.rst
@@ -1,6 +1,8 @@
 CMP0067
 -------
 
+.. versionadded:: 3.8
+
 Honor language standard in :command:`try_compile` source-file signature.
 
 The :command:`try_compile` source file signature is intended to allow
diff --git a/Help/policy/CMP0068.rst b/Help/policy/CMP0068.rst
index 978a6e3..5d2a4b1 100644
--- a/Help/policy/CMP0068.rst
+++ b/Help/policy/CMP0068.rst
@@ -1,6 +1,8 @@
 CMP0068
 -------
 
+.. versionadded:: 3.9
+
 ``RPATH`` settings on macOS do not affect ``install_name``.
 
 CMake 3.9 and newer remove any effect the following settings may have on the
diff --git a/Help/policy/CMP0069.rst b/Help/policy/CMP0069.rst
index 0d5ddfd..eafac45 100644
--- a/Help/policy/CMP0069.rst
+++ b/Help/policy/CMP0069.rst
@@ -1,6 +1,8 @@
 CMP0069
 -------
 
+.. versionadded:: 3.9
+
 :prop_tgt:`INTERPROCEDURAL_OPTIMIZATION` is enforced when enabled.
 
 CMake 3.9 and newer prefer to add IPO flags whenever the
diff --git a/Help/policy/CMP0070.rst b/Help/policy/CMP0070.rst
index 0fb3617..c880d1f 100644
--- a/Help/policy/CMP0070.rst
+++ b/Help/policy/CMP0070.rst
@@ -1,6 +1,8 @@
 CMP0070
 -------
 
+.. versionadded:: 3.10
+
 Define :command:`file(GENERATE)` behavior for relative paths.
 
 CMake 3.10 and newer define that relative paths given to ``INPUT`` and
diff --git a/Help/policy/CMP0071.rst b/Help/policy/CMP0071.rst
index 855ecf0..700d3b0 100644
--- a/Help/policy/CMP0071.rst
+++ b/Help/policy/CMP0071.rst
@@ -1,6 +1,8 @@
 CMP0071
 -------
 
+.. versionadded:: 3.10
+
 Let :prop_tgt:`AUTOMOC` and :prop_tgt:`AUTOUIC` process
 :prop_sf:`GENERATED` files.
 
diff --git a/Help/policy/CMP0072.rst b/Help/policy/CMP0072.rst
index 3abbad7..1dcdfef 100644
--- a/Help/policy/CMP0072.rst
+++ b/Help/policy/CMP0072.rst
@@ -1,6 +1,8 @@
 CMP0072
 -------
 
+.. versionadded:: 3.11
+
 :module:`FindOpenGL` prefers GLVND by default when available.
 
 The :module:`FindOpenGL` module provides an ``OpenGL::GL`` target and an
diff --git a/Help/policy/CMP0073.rst b/Help/policy/CMP0073.rst
index 9bfa0e9..8f0345c 100644
--- a/Help/policy/CMP0073.rst
+++ b/Help/policy/CMP0073.rst
@@ -1,6 +1,8 @@
 CMP0073
 -------
 
+.. versionadded:: 3.12
+
 Do not produce legacy ``_LIB_DEPENDS`` cache entries.
 
 Ancient CMake versions once used ``<tgt>_LIB_DEPENDS`` cache entries to
diff --git a/Help/policy/CMP0074.rst b/Help/policy/CMP0074.rst
index 63ebf7b..863bbb2 100644
--- a/Help/policy/CMP0074.rst
+++ b/Help/policy/CMP0074.rst
@@ -1,6 +1,8 @@
 CMP0074
 -------
 
+.. versionadded:: 3.12
+
 :command:`find_package` uses ``<PackageName>_ROOT`` variables.
 
 In CMake 3.12 and above the :command:`find_package(<PackageName>)` command now
diff --git a/Help/policy/CMP0075.rst b/Help/policy/CMP0075.rst
index aa5c3f7..4213782 100644
--- a/Help/policy/CMP0075.rst
+++ b/Help/policy/CMP0075.rst
@@ -1,6 +1,8 @@
 CMP0075
 -------
 
+.. versionadded:: 3.12
+
 Include file check macros honor ``CMAKE_REQUIRED_LIBRARIES``.
 
 In CMake 3.12 and above, the
diff --git a/Help/policy/CMP0076.rst b/Help/policy/CMP0076.rst
index dd25f80..edca742 100644
--- a/Help/policy/CMP0076.rst
+++ b/Help/policy/CMP0076.rst
@@ -1,6 +1,8 @@
 CMP0076
 -------
 
+.. versionadded:: 3.13
+
 The :command:`target_sources` command converts relative paths to absolute.
 
 In CMake 3.13 and above, the :command:`target_sources` command now converts
diff --git a/Help/policy/CMP0077.rst b/Help/policy/CMP0077.rst
index 44797b6..174cde9 100644
--- a/Help/policy/CMP0077.rst
+++ b/Help/policy/CMP0077.rst
@@ -1,6 +1,8 @@
 CMP0077
 -------
 
+.. versionadded:: 3.13
+
 :command:`option` honors normal variables.
 
 The :command:`option` command is typically used to create a cache entry
diff --git a/Help/policy/CMP0078.rst b/Help/policy/CMP0078.rst
index 2e97934..89fdb0b 100644
--- a/Help/policy/CMP0078.rst
+++ b/Help/policy/CMP0078.rst
@@ -1,6 +1,8 @@
 CMP0078
 -------
 
+.. versionadded:: 3.13
+
 :module:`UseSWIG` generates standard target names.
 
 Starting with CMake 3.13, :module:`UseSWIG` generates now standard target
diff --git a/Help/policy/CMP0079.rst b/Help/policy/CMP0079.rst
index 0244d6c..01aa08d 100644
--- a/Help/policy/CMP0079.rst
+++ b/Help/policy/CMP0079.rst
@@ -1,6 +1,8 @@
 CMP0079
 -------
 
+.. versionadded:: 3.13
+
 :command:`target_link_libraries` allows use with targets in other directories.
 
 Prior to CMake 3.13 the :command:`target_link_libraries` command did not
diff --git a/Help/policy/CMP0080.rst b/Help/policy/CMP0080.rst
index 5ce9591..789efea 100644
--- a/Help/policy/CMP0080.rst
+++ b/Help/policy/CMP0080.rst
@@ -1,6 +1,8 @@
 CMP0080
 -------
 
+.. versionadded:: 3.13
+
 :module:`BundleUtilities` cannot be included at configure time.
 
 The macros provided by :module:`BundleUtilities` are intended to be invoked
diff --git a/Help/policy/CMP0081.rst b/Help/policy/CMP0081.rst
index d3b2872..d1573dd 100644
--- a/Help/policy/CMP0081.rst
+++ b/Help/policy/CMP0081.rst
@@ -1,6 +1,8 @@
 CMP0081
 -------
 
+.. versionadded:: 3.13
+
 Relative paths not allowed in :prop_tgt:`LINK_DIRECTORIES` target property.
 
 CMake 3.12 and lower allowed the :prop_dir:`LINK_DIRECTORIES` directory
diff --git a/Help/policy/CMP0082.rst b/Help/policy/CMP0082.rst
index d887616..25c9580 100644
--- a/Help/policy/CMP0082.rst
+++ b/Help/policy/CMP0082.rst
@@ -1,6 +1,8 @@
 CMP0082
 -------
 
+.. versionadded:: 3.14
+
 Install rules from :command:`add_subdirectory` calls are interleaved with
 those in caller.
 
diff --git a/Help/policy/CMP0083.rst b/Help/policy/CMP0083.rst
index e0b09cf..7518ee3 100644
--- a/Help/policy/CMP0083.rst
+++ b/Help/policy/CMP0083.rst
@@ -1,6 +1,8 @@
 CMP0083
 -------
 
+.. versionadded:: 3.14
+
 To control generation of Position Independent Executable (``PIE``) or not, some
 flags are required at link time.
 
diff --git a/Help/policy/CMP0084.rst b/Help/policy/CMP0084.rst
index 713d295..9547701 100644
--- a/Help/policy/CMP0084.rst
+++ b/Help/policy/CMP0084.rst
@@ -1,6 +1,8 @@
 CMP0084
 -------
 
+.. versionadded:: 3.14
+
 The :module:`FindQt` module does not exist for :command:`find_package`.
 
 The existence of :module:`FindQt` means that for Qt upstream to provide
diff --git a/Help/policy/CMP0085.rst b/Help/policy/CMP0085.rst
index d9ec9a2..d90c72f 100644
--- a/Help/policy/CMP0085.rst
+++ b/Help/policy/CMP0085.rst
@@ -1,6 +1,8 @@
 CMP0085
 -------
 
+.. versionadded:: 3.14
+
 ``$<IN_LIST:...>`` handles empty list items.
 
 In CMake 3.13 and lower, the ``$<IN_LIST:...>`` generator expression always
diff --git a/Help/policy/CMP0086.rst b/Help/policy/CMP0086.rst
index 4a9e8b8..725b502 100644
--- a/Help/policy/CMP0086.rst
+++ b/Help/policy/CMP0086.rst
@@ -1,6 +1,8 @@
 CMP0086
 -------
 
+.. versionadded:: 3.14
+
 :module:`UseSWIG` honors ``SWIG_MODULE_NAME`` via ``-module`` flag.
 
 Starting with CMake 3.14, :module:`UseSWIG` passes option
diff --git a/Help/policy/CMP0087.rst b/Help/policy/CMP0087.rst
index 4c45b99..4a65506 100644
--- a/Help/policy/CMP0087.rst
+++ b/Help/policy/CMP0087.rst
@@ -1,6 +1,8 @@
 CMP0087
 -------
 
+.. versionadded:: 3.14
+
 :command:`install(CODE)` and :command:`install(SCRIPT)` support generator
 expressions.
 
diff --git a/Help/policy/CMP0088.rst b/Help/policy/CMP0088.rst
index 82c04ef..1840a58 100644
--- a/Help/policy/CMP0088.rst
+++ b/Help/policy/CMP0088.rst
@@ -1,6 +1,8 @@
 CMP0088
 -------
 
+.. versionadded:: 3.14
+
 :module:`FindBISON` runs bison in :variable:`CMAKE_CURRENT_BINARY_DIR`
 when executing.
 
diff --git a/Help/policy/CMP0089.rst b/Help/policy/CMP0089.rst
index 029de55..e3fc77a 100644
--- a/Help/policy/CMP0089.rst
+++ b/Help/policy/CMP0089.rst
@@ -1,6 +1,8 @@
 CMP0089
 -------
 
+.. versionadded:: 3.15
+
 Compiler id for IBM Clang-based XL compilers is now ``XLClang``.
 
 CMake 3.15 and above recognize that IBM's Clang-based XL compilers
diff --git a/Help/policy/CMP0090.rst b/Help/policy/CMP0090.rst
index 720c17c..58dd999 100644
--- a/Help/policy/CMP0090.rst
+++ b/Help/policy/CMP0090.rst
@@ -1,6 +1,8 @@
 CMP0090
 -------
 
+.. versionadded:: 3.15
+
 :command:`export(PACKAGE)` does not populate package registry by default.
 
 In CMake 3.14 and below the :command:`export(PACKAGE)` command populated the
diff --git a/Help/policy/CMP0091.rst b/Help/policy/CMP0091.rst
index 1a5878a..ffc0ade 100644
--- a/Help/policy/CMP0091.rst
+++ b/Help/policy/CMP0091.rst
@@ -1,6 +1,8 @@
 CMP0091
 -------
 
+.. versionadded:: 3.15
+
 MSVC runtime library flags are selected by an abstraction.
 
 Compilers targeting the MSVC ABI have flags to select the MSVC runtime library.
diff --git a/Help/policy/CMP0092.rst b/Help/policy/CMP0092.rst
index 8d3a288..2f39830 100644
--- a/Help/policy/CMP0092.rst
+++ b/Help/policy/CMP0092.rst
@@ -1,6 +1,8 @@
 CMP0092
 -------
 
+.. versionadded:: 3.15
+
 MSVC warning flags are not in :variable:`CMAKE_<LANG>_FLAGS` by default.
 
 When using MSVC-like compilers in CMake 3.14 and below, warning flags
@@ -16,7 +18,7 @@
 This policy provides compatibility with projects that have not been updated
 to expect the lack of warning flags.  The policy setting takes effect as of
 the first :command:`project` or :command:`enable_language` command that
-initializes :variable:`CMAKE_<LANG>_FLAGS` for a given lanuage ``<LANG>``.
+initializes :variable:`CMAKE_<LANG>_FLAGS` for a given language ``<LANG>``.
 
 .. note::
 
diff --git a/Help/policy/CMP0093.rst b/Help/policy/CMP0093.rst
index 0ffc493..4a9955f 100644
--- a/Help/policy/CMP0093.rst
+++ b/Help/policy/CMP0093.rst
@@ -1,6 +1,8 @@
 CMP0093
 -------
 
+.. versionadded:: 3.15
+
 :module:`FindBoost` reports ``Boost_VERSION`` in ``x.y.z`` format.
 
 In CMake 3.14 and below the module would report the Boost version
diff --git a/Help/policy/CMP0094.rst b/Help/policy/CMP0094.rst
index 836f30f..1b57658 100644
--- a/Help/policy/CMP0094.rst
+++ b/Help/policy/CMP0094.rst
@@ -1,6 +1,8 @@
 CMP0094
 -------
 
+.. versionadded:: 3.15
+
 Modules :module:`FindPython3`, :module:`FindPython2` and :module:`FindPython`
 use ``LOCATION`` for lookup strategy.
 
diff --git a/Help/policy/CMP0095.rst b/Help/policy/CMP0095.rst
index 4c56a05..ebdbab6 100644
--- a/Help/policy/CMP0095.rst
+++ b/Help/policy/CMP0095.rst
@@ -1,6 +1,8 @@
 CMP0095
 -------
 
+.. versionadded:: 3.16
+
 ``RPATH`` entries are properly escaped in the intermediary CMake install script.
 
 In CMake 3.15 and earlier, ``RPATH`` entries set via
diff --git a/Help/policy/CMP0096.rst b/Help/policy/CMP0096.rst
index 8eaf0f9..8fd6f72 100644
--- a/Help/policy/CMP0096.rst
+++ b/Help/policy/CMP0096.rst
@@ -1,6 +1,8 @@
 CMP0096
 -------
 
+.. versionadded:: 3.16
+
 The :command:`project` command preserves leading zeros in version components.
 
 When a ``VERSION <major>[.<minor>[.<patch>[.<tweak>]]]]`` argument is given
diff --git a/Help/policy/CMP0097.rst b/Help/policy/CMP0097.rst
index 4840aa6..2240874 100644
--- a/Help/policy/CMP0097.rst
+++ b/Help/policy/CMP0097.rst
@@ -1,6 +1,8 @@
 CMP0097
 -------
 
+.. versionadded:: 3.16
+
 :command:`ExternalProject_Add` with ``GIT_SUBMODULES ""`` initializes no
 submodules.
 
diff --git a/Help/policy/CMP0098.rst b/Help/policy/CMP0098.rst
index 6d1443b..e793380 100644
--- a/Help/policy/CMP0098.rst
+++ b/Help/policy/CMP0098.rst
@@ -1,6 +1,8 @@
 CMP0098
 -------
 
+.. versionadded:: 3.17
+
 :module:`FindFLEX` runs ``flex`` in directory
 :variable:`CMAKE_CURRENT_BINARY_DIR` when executing.
 
diff --git a/Help/policy/CMP0099.rst b/Help/policy/CMP0099.rst
index c897e7b..0c64949 100644
--- a/Help/policy/CMP0099.rst
+++ b/Help/policy/CMP0099.rst
@@ -1,6 +1,8 @@
 CMP0099
 -------
 
+.. versionadded:: 3.17
+
 Target link properties :prop_tgt:`INTERFACE_LINK_OPTIONS`,
 :prop_tgt:`INTERFACE_LINK_DIRECTORIES` and :prop_tgt:`INTERFACE_LINK_DEPENDS`
 are now transitive over private dependencies of static libraries.
diff --git a/Help/policy/CMP0100.rst b/Help/policy/CMP0100.rst
index b24d013..730fa82 100644
--- a/Help/policy/CMP0100.rst
+++ b/Help/policy/CMP0100.rst
@@ -1,6 +1,8 @@
 CMP0100
 -------
 
+.. versionadded:: 3.17
+
 Let :prop_tgt:`AUTOMOC` and :prop_tgt:`AUTOUIC` process
 header files that end with a ``.hh`` extension.
 
diff --git a/Help/policy/CMP0101.rst b/Help/policy/CMP0101.rst
index 9941acf..f02bccc 100644
--- a/Help/policy/CMP0101.rst
+++ b/Help/policy/CMP0101.rst
@@ -1,6 +1,8 @@
 CMP0101
 -------
 
+.. versionadded:: 3.17
+
 :command:`target_compile_options` now honors ``BEFORE`` keyword in all scopes.
 
 In CMake 3.16 and below the :command:`target_compile_options` ignores the
diff --git a/Help/policy/CMP0102.rst b/Help/policy/CMP0102.rst
index 9859006..78b5584 100644
--- a/Help/policy/CMP0102.rst
+++ b/Help/policy/CMP0102.rst
@@ -1,6 +1,8 @@
 CMP0102
 -------
 
+.. versionadded:: 3.17
+
 The :command:`mark_as_advanced` command no longer creates a cache entry if one
 does not already exist.
 
diff --git a/Help/policy/CMP0103.rst b/Help/policy/CMP0103.rst
index 223e0cb..b5f44d1 100644
--- a/Help/policy/CMP0103.rst
+++ b/Help/policy/CMP0103.rst
@@ -1,6 +1,8 @@
 CMP0103
 -------
 
+.. versionadded:: 3.18
+
 Multiple calls to :command:`export` command with same ``FILE`` without
 ``APPEND`` is no longer allowed.
 
diff --git a/Help/policy/CMP0104.rst b/Help/policy/CMP0104.rst
index 8516716..7c7a16e 100644
--- a/Help/policy/CMP0104.rst
+++ b/Help/policy/CMP0104.rst
@@ -1,6 +1,8 @@
 CMP0104
 -------
 
+.. versionadded:: 3.18
+
 Initialize :variable:`CMAKE_CUDA_ARCHITECTURES` when
 :variable:`CMAKE_CUDA_COMPILER_ID <CMAKE_<LANG>_COMPILER_ID>` is ``NVIDIA``.
 Raise an error if :prop_tgt:`CUDA_ARCHITECTURES` is empty.
diff --git a/Help/policy/CMP0105.rst b/Help/policy/CMP0105.rst
index 19a1edb..097a59a 100644
--- a/Help/policy/CMP0105.rst
+++ b/Help/policy/CMP0105.rst
@@ -1,6 +1,8 @@
 CMP0105
 -------
 
+.. versionadded:: 3.18
+
 :prop_tgt:`LINK_OPTIONS` and :prop_tgt:`INTERFACE_LINK_OPTIONS` target
 properties are now used for the device link step.
 
diff --git a/Help/policy/CMP0106.rst b/Help/policy/CMP0106.rst
index e34d15a..18a6635 100644
--- a/Help/policy/CMP0106.rst
+++ b/Help/policy/CMP0106.rst
@@ -1,6 +1,8 @@
 CMP0106
 -------
 
+.. versionadded:: 3.18
+
 The :module:`Documentation` module is removed.
 
 The :module:`Documentation` was added as a support mechanism for the VTK
diff --git a/Help/policy/CMP0107.rst b/Help/policy/CMP0107.rst
index 111bef7..da5ae06 100644
--- a/Help/policy/CMP0107.rst
+++ b/Help/policy/CMP0107.rst
@@ -1,6 +1,8 @@
 CMP0107
 -------
 
+.. versionadded:: 3.18
+
 It is not allowed to create an ``ALIAS`` target with the same name as an
 another target.
 
diff --git a/Help/policy/CMP0108.rst b/Help/policy/CMP0108.rst
index 0d54cfa..4d1091d 100644
--- a/Help/policy/CMP0108.rst
+++ b/Help/policy/CMP0108.rst
@@ -1,6 +1,8 @@
 CMP0108
 -------
 
+.. versionadded:: 3.18
+
 A target is not allowed to link to itself even through an ``ALIAS`` target.
 
 In CMake 3.17 and below, a target can link to a target aliased to itself.
diff --git a/Help/policy/CMP0109.rst b/Help/policy/CMP0109.rst
new file mode 100644
index 0000000..f86287f
--- /dev/null
+++ b/Help/policy/CMP0109.rst
@@ -0,0 +1,24 @@
+CMP0109
+-------
+
+.. versionadded:: 3.19
+
+:command:`find_program` requires permission to execute but not to read.
+
+In CMake 3.18 and below, the :command:`find_program` command on UNIX
+would find files that are readable without requiring execute permission,
+and would not find files that are executable without read permission.
+In CMake 3.19 and above, ``find_program`` now prefers to require execute
+permission but not read permission.  This policy provides compatibility
+with projects that have not been updated to expect the new behavior.
+
+The ``OLD`` behavior for this policy is for ``find_program`` to require
+read permission but not execute permission.
+The ``NEW`` behavior for this policy is for ``find_program`` to require
+execute permission but not read permission.
+
+This policy was introduced in CMake version 3.19.  CMake version |release|
+warns when the policy is not set and uses ``OLD`` behavior.  Use the
+:command:`cmake_policy` command to set it to ``OLD`` or ``NEW`` explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/prop_dir/ADDITIONAL_CLEAN_FILES.rst b/Help/prop_dir/ADDITIONAL_CLEAN_FILES.rst
index 051d22a..6097d14 100644
--- a/Help/prop_dir/ADDITIONAL_CLEAN_FILES.rst
+++ b/Help/prop_dir/ADDITIONAL_CLEAN_FILES.rst
@@ -1,6 +1,8 @@
 ADDITIONAL_CLEAN_FILES
 ----------------------
 
+.. versionadded:: 3.15
+
 A :ref:`;-list <CMake Language Lists>` of files or directories that will be
 removed as a part of the global ``clean`` target.  It is useful for
 specifying generated files or directories that are used by multiple targets
diff --git a/Help/prop_dir/BINARY_DIR.rst b/Help/prop_dir/BINARY_DIR.rst
index 597c79a..fcf9d17 100644
--- a/Help/prop_dir/BINARY_DIR.rst
+++ b/Help/prop_dir/BINARY_DIR.rst
@@ -1,5 +1,7 @@
 BINARY_DIR
 ----------
 
+.. versionadded:: 3.7
+
 This read-only directory property reports absolute path to the binary
 directory corresponding to the source on which it is read.
diff --git a/Help/prop_dir/BUILDSYSTEM_TARGETS.rst b/Help/prop_dir/BUILDSYSTEM_TARGETS.rst
index 04bb56e..5c5893d 100644
--- a/Help/prop_dir/BUILDSYSTEM_TARGETS.rst
+++ b/Help/prop_dir/BUILDSYSTEM_TARGETS.rst
@@ -1,6 +1,8 @@
 BUILDSYSTEM_TARGETS
 -------------------
 
+.. versionadded:: 3.7
+
 This read-only directory property contains a
 :ref:`semicolon-separated list <CMake Language Lists>` of buildsystem targets added in the
 directory by calls to the :command:`add_library`, :command:`add_executable`,
diff --git a/Help/prop_dir/LABELS.rst b/Help/prop_dir/LABELS.rst
index de27d90..bf14368 100644
--- a/Help/prop_dir/LABELS.rst
+++ b/Help/prop_dir/LABELS.rst
@@ -1,6 +1,8 @@
 LABELS
 ------
 
+.. versionadded:: 3.10
+
 Specify a list of text labels associated with a directory and all of its
 subdirectories. This is equivalent to setting the :prop_tgt:`LABELS` target
 property and the :prop_test:`LABELS` test property on all targets and tests in
diff --git a/Help/prop_dir/LINK_OPTIONS.rst b/Help/prop_dir/LINK_OPTIONS.rst
index f229ba6..3a5c72f 100644
--- a/Help/prop_dir/LINK_OPTIONS.rst
+++ b/Help/prop_dir/LINK_OPTIONS.rst
@@ -1,6 +1,8 @@
 LINK_OPTIONS
 ------------
 
+.. versionadded:: 3.13
+
 List of options to use for the link step of shared library, module
 and executable targets as well as the device link step.
 
diff --git a/Help/prop_dir/SOURCE_DIR.rst b/Help/prop_dir/SOURCE_DIR.rst
index ac98c3b..d73707d 100644
--- a/Help/prop_dir/SOURCE_DIR.rst
+++ b/Help/prop_dir/SOURCE_DIR.rst
@@ -1,5 +1,7 @@
 SOURCE_DIR
 ----------
 
+.. versionadded:: 3.7
+
 This read-only directory property reports absolute path to the source
 directory on which it is read.
diff --git a/Help/prop_dir/SUBDIRECTORIES.rst b/Help/prop_dir/SUBDIRECTORIES.rst
index 6a0ac80..71ea496 100644
--- a/Help/prop_dir/SUBDIRECTORIES.rst
+++ b/Help/prop_dir/SUBDIRECTORIES.rst
@@ -1,6 +1,8 @@
 SUBDIRECTORIES
 --------------
 
+.. versionadded:: 3.7
+
 This read-only directory property contains a
 :ref:`semicolon-separated list <CMake Language Lists>` of subdirectories processed so far by
 the :command:`add_subdirectory` or :command:`subdirs` commands.  Each entry is
diff --git a/Help/prop_dir/TESTS.rst b/Help/prop_dir/TESTS.rst
index 1c9f6e5..294be17 100644
--- a/Help/prop_dir/TESTS.rst
+++ b/Help/prop_dir/TESTS.rst
@@ -1,6 +1,8 @@
 TESTS
 -----
 
+.. versionadded:: 3.12
+
 List of tests.
 
 This read-only property holds a
diff --git a/Help/prop_dir/TEST_INCLUDE_FILES.rst b/Help/prop_dir/TEST_INCLUDE_FILES.rst
index c3e4602..f9a66f4 100644
--- a/Help/prop_dir/TEST_INCLUDE_FILES.rst
+++ b/Help/prop_dir/TEST_INCLUDE_FILES.rst
@@ -1,6 +1,8 @@
 TEST_INCLUDE_FILES
 ------------------
 
+.. versionadded:: 3.10
+
 A list of cmake files that will be included when ctest is run.
 
 If you specify ``TEST_INCLUDE_FILES``, those files will be included and
diff --git a/Help/prop_dir/VS_STARTUP_PROJECT.rst b/Help/prop_dir/VS_STARTUP_PROJECT.rst
index 2680dfa..8a0c3c8 100644
--- a/Help/prop_dir/VS_STARTUP_PROJECT.rst
+++ b/Help/prop_dir/VS_STARTUP_PROJECT.rst
@@ -1,6 +1,8 @@
 VS_STARTUP_PROJECT
 ------------------
 
+.. versionadded:: 3.6
+
 Specify the default startup project in a Visual Studio solution.
 
 The :ref:`Visual Studio Generators` create a ``.sln`` file for each directory
diff --git a/Help/prop_gbl/AUTOGEN_SOURCE_GROUP.rst b/Help/prop_gbl/AUTOGEN_SOURCE_GROUP.rst
index d294eb1..2e32320 100644
--- a/Help/prop_gbl/AUTOGEN_SOURCE_GROUP.rst
+++ b/Help/prop_gbl/AUTOGEN_SOURCE_GROUP.rst
@@ -1,6 +1,8 @@
 AUTOGEN_SOURCE_GROUP
 --------------------
 
+.. versionadded:: 3.9
+
 Name of the  :command:`source_group` for :prop_tgt:`AUTOMOC` and
 :prop_tgt:`AUTORCC` generated files.
 
diff --git a/Help/prop_gbl/AUTOMOC_SOURCE_GROUP.rst b/Help/prop_gbl/AUTOMOC_SOURCE_GROUP.rst
index 2455dc7..a266fde 100644
--- a/Help/prop_gbl/AUTOMOC_SOURCE_GROUP.rst
+++ b/Help/prop_gbl/AUTOMOC_SOURCE_GROUP.rst
@@ -1,6 +1,8 @@
 AUTOMOC_SOURCE_GROUP
 --------------------
 
+.. versionadded:: 3.9
+
 Name of the  :command:`source_group` for :prop_tgt:`AUTOMOC` generated files.
 
 When set this is used instead of :prop_gbl:`AUTOGEN_SOURCE_GROUP` for
diff --git a/Help/prop_gbl/AUTORCC_SOURCE_GROUP.rst b/Help/prop_gbl/AUTORCC_SOURCE_GROUP.rst
index 65ea95b..54ebabb 100644
--- a/Help/prop_gbl/AUTORCC_SOURCE_GROUP.rst
+++ b/Help/prop_gbl/AUTORCC_SOURCE_GROUP.rst
@@ -1,6 +1,8 @@
 AUTORCC_SOURCE_GROUP
 --------------------
 
+.. versionadded:: 3.9
+
 Name of the  :command:`source_group` for :prop_tgt:`AUTORCC` generated files.
 
 When set this is used instead of :prop_gbl:`AUTOGEN_SOURCE_GROUP` for
diff --git a/Help/prop_gbl/CMAKE_CUDA_KNOWN_FEATURES.rst b/Help/prop_gbl/CMAKE_CUDA_KNOWN_FEATURES.rst
index 44e37fe..e8e3148 100644
--- a/Help/prop_gbl/CMAKE_CUDA_KNOWN_FEATURES.rst
+++ b/Help/prop_gbl/CMAKE_CUDA_KNOWN_FEATURES.rst
@@ -1,6 +1,8 @@
 CMAKE_CUDA_KNOWN_FEATURES
 -------------------------
 
+.. versionadded:: 3.17
+
 List of CUDA features known to this version of CMake.
 
 The features listed in this global property may be known to be available to the
diff --git a/Help/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.rst b/Help/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.rst
index b921c6b..9b53282 100644
--- a/Help/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.rst
+++ b/Help/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.rst
@@ -1,6 +1,8 @@
 CMAKE_CXX_KNOWN_FEATURES
 ------------------------
 
+.. versionadded:: 3.1
+
 List of C++ features known to this version of CMake.
 
 The features listed in this global property may be known to be available to the
diff --git a/Help/prop_gbl/CMAKE_C_KNOWN_FEATURES.rst b/Help/prop_gbl/CMAKE_C_KNOWN_FEATURES.rst
index e5f896e..7166381 100644
--- a/Help/prop_gbl/CMAKE_C_KNOWN_FEATURES.rst
+++ b/Help/prop_gbl/CMAKE_C_KNOWN_FEATURES.rst
@@ -1,6 +1,8 @@
 CMAKE_C_KNOWN_FEATURES
 ----------------------
 
+.. versionadded:: 3.1
+
 List of C features known to this version of CMake.
 
 The features listed in this global property may be known to be available to the
diff --git a/Help/prop_gbl/CMAKE_ROLE.rst b/Help/prop_gbl/CMAKE_ROLE.rst
index 27512fa..3f4492f 100644
--- a/Help/prop_gbl/CMAKE_ROLE.rst
+++ b/Help/prop_gbl/CMAKE_ROLE.rst
@@ -1,6 +1,8 @@
 CMAKE_ROLE
 ----------
 
+.. versionadded:: 3.14
+
 Tells what mode the current running script is in. Could be one of several
 values:
 
diff --git a/Help/prop_gbl/ECLIPSE_EXTRA_CPROJECT_CONTENTS.rst b/Help/prop_gbl/ECLIPSE_EXTRA_CPROJECT_CONTENTS.rst
index 50c41a9..2f110a7 100644
--- a/Help/prop_gbl/ECLIPSE_EXTRA_CPROJECT_CONTENTS.rst
+++ b/Help/prop_gbl/ECLIPSE_EXTRA_CPROJECT_CONTENTS.rst
@@ -1,6 +1,8 @@
 ECLIPSE_EXTRA_CPROJECT_CONTENTS
 -------------------------------
 
+.. versionadded:: 3.12
+
 Additional contents to be inserted into the generated Eclipse cproject file.
 
 The cproject file defines the CDT specific information. Some third party IDE's
diff --git a/Help/prop_gbl/FIND_LIBRARY_USE_LIB32_PATHS.rst b/Help/prop_gbl/FIND_LIBRARY_USE_LIB32_PATHS.rst
index 8396026..f6cad66 100644
--- a/Help/prop_gbl/FIND_LIBRARY_USE_LIB32_PATHS.rst
+++ b/Help/prop_gbl/FIND_LIBRARY_USE_LIB32_PATHS.rst
@@ -1,6 +1,8 @@
 FIND_LIBRARY_USE_LIB32_PATHS
 ----------------------------
 
+.. versionadded:: 3.7
+
 Whether the :command:`find_library` command should automatically search
 ``lib32`` directories.
 
diff --git a/Help/prop_gbl/FIND_LIBRARY_USE_LIBX32_PATHS.rst b/Help/prop_gbl/FIND_LIBRARY_USE_LIBX32_PATHS.rst
index b87b09b..851f859 100644
--- a/Help/prop_gbl/FIND_LIBRARY_USE_LIBX32_PATHS.rst
+++ b/Help/prop_gbl/FIND_LIBRARY_USE_LIBX32_PATHS.rst
@@ -1,6 +1,8 @@
 FIND_LIBRARY_USE_LIBX32_PATHS
 -----------------------------
 
+.. versionadded:: 3.9
+
 Whether the :command:`find_library` command should automatically search
 ``libx32`` directories.
 
diff --git a/Help/prop_gbl/GENERATOR_IS_MULTI_CONFIG.rst b/Help/prop_gbl/GENERATOR_IS_MULTI_CONFIG.rst
index b8ec8a6..6f1a9e1 100644
--- a/Help/prop_gbl/GENERATOR_IS_MULTI_CONFIG.rst
+++ b/Help/prop_gbl/GENERATOR_IS_MULTI_CONFIG.rst
@@ -1,6 +1,8 @@
 GENERATOR_IS_MULTI_CONFIG
 -------------------------
 
+.. versionadded:: 3.9
+
 Read-only property that is true on multi-configuration generators.
 
 True when using a multi-configuration generator
diff --git a/Help/prop_gbl/TARGET_MESSAGES.rst b/Help/prop_gbl/TARGET_MESSAGES.rst
index 275b074..bb91772 100644
--- a/Help/prop_gbl/TARGET_MESSAGES.rst
+++ b/Help/prop_gbl/TARGET_MESSAGES.rst
@@ -1,6 +1,8 @@
 TARGET_MESSAGES
 ---------------
 
+.. versionadded:: 3.4
+
 Specify whether to report the completion of each target.
 
 This property specifies whether :ref:`Makefile Generators` should
diff --git a/Help/prop_gbl/XCODE_EMIT_EFFECTIVE_PLATFORM_NAME.rst b/Help/prop_gbl/XCODE_EMIT_EFFECTIVE_PLATFORM_NAME.rst
index 9500443..392b704 100644
--- a/Help/prop_gbl/XCODE_EMIT_EFFECTIVE_PLATFORM_NAME.rst
+++ b/Help/prop_gbl/XCODE_EMIT_EFFECTIVE_PLATFORM_NAME.rst
@@ -1,6 +1,8 @@
 XCODE_EMIT_EFFECTIVE_PLATFORM_NAME
 ----------------------------------
 
+.. versionadded:: 3.8
+
 Control emission of ``EFFECTIVE_PLATFORM_NAME`` by the :generator:`Xcode`
 generator.
 
diff --git a/Help/prop_inst/CPACK_DESKTOP_SHORTCUTS.rst b/Help/prop_inst/CPACK_DESKTOP_SHORTCUTS.rst
index 729ab60..55e9a20 100644
--- a/Help/prop_inst/CPACK_DESKTOP_SHORTCUTS.rst
+++ b/Help/prop_inst/CPACK_DESKTOP_SHORTCUTS.rst
@@ -1,6 +1,8 @@
 CPACK_DESKTOP_SHORTCUTS
 -----------------------
 
+.. versionadded:: 3.3
+
 Species a list of shortcut names that should be created on the `Desktop`
 for this file.
 
diff --git a/Help/prop_inst/CPACK_NEVER_OVERWRITE.rst b/Help/prop_inst/CPACK_NEVER_OVERWRITE.rst
index 4789e25..12eef9e 100644
--- a/Help/prop_inst/CPACK_NEVER_OVERWRITE.rst
+++ b/Help/prop_inst/CPACK_NEVER_OVERWRITE.rst
@@ -1,6 +1,8 @@
 CPACK_NEVER_OVERWRITE
 ---------------------
 
+.. versionadded:: 3.1
+
 Request that this file not be overwritten on install or reinstall.
 
 The property is currently only supported by the :cpack_gen:`CPack WIX Generator`.
diff --git a/Help/prop_inst/CPACK_PERMANENT.rst b/Help/prop_inst/CPACK_PERMANENT.rst
index 985de0d..e89c552 100644
--- a/Help/prop_inst/CPACK_PERMANENT.rst
+++ b/Help/prop_inst/CPACK_PERMANENT.rst
@@ -1,6 +1,8 @@
 CPACK_PERMANENT
 ---------------
 
+.. versionadded:: 3.1
+
 Request that this file not be removed on uninstall.
 
 The property is currently only supported by the :cpack_gen:`CPack WIX Generator`.
diff --git a/Help/prop_inst/CPACK_STARTUP_SHORTCUTS.rst b/Help/prop_inst/CPACK_STARTUP_SHORTCUTS.rst
index d9208b9..e896acd 100644
--- a/Help/prop_inst/CPACK_STARTUP_SHORTCUTS.rst
+++ b/Help/prop_inst/CPACK_STARTUP_SHORTCUTS.rst
@@ -1,6 +1,8 @@
 CPACK_STARTUP_SHORTCUTS
 -----------------------
 
+.. versionadded:: 3.3
+
 Species a list of shortcut names that should be created in the `Startup` folder
 for this file.
 
diff --git a/Help/prop_inst/CPACK_START_MENU_SHORTCUTS.rst b/Help/prop_inst/CPACK_START_MENU_SHORTCUTS.rst
index 092334a..fb8807f 100644
--- a/Help/prop_inst/CPACK_START_MENU_SHORTCUTS.rst
+++ b/Help/prop_inst/CPACK_START_MENU_SHORTCUTS.rst
@@ -1,6 +1,8 @@
 CPACK_START_MENU_SHORTCUTS
 --------------------------
 
+.. versionadded:: 3.3
+
 Species a list of shortcut names that should be created in the `Start Menu`
 for this file.
 
diff --git a/Help/prop_inst/CPACK_WIX_ACL.rst b/Help/prop_inst/CPACK_WIX_ACL.rst
index c88f426..8b4fb5c 100644
--- a/Help/prop_inst/CPACK_WIX_ACL.rst
+++ b/Help/prop_inst/CPACK_WIX_ACL.rst
@@ -1,6 +1,8 @@
 CPACK_WIX_ACL
 -------------
 
+.. versionadded:: 3.1
+
 Specifies access permissions for files or directories
 installed by a WiX installer.
 
diff --git a/Help/prop_sf/COMPILE_OPTIONS.rst b/Help/prop_sf/COMPILE_OPTIONS.rst
index 537dcec..a694c3e 100644
--- a/Help/prop_sf/COMPILE_OPTIONS.rst
+++ b/Help/prop_sf/COMPILE_OPTIONS.rst
@@ -1,6 +1,8 @@
 COMPILE_OPTIONS
 ---------------
 
+.. versionadded:: 3.11
+
 List of additional options to pass to the compiler.
 
 This property holds a :ref:`semicolon-separated list <CMake Language Lists>` of options
diff --git a/Help/prop_sf/Fortran_PREPROCESS.rst b/Help/prop_sf/Fortran_PREPROCESS.rst
index 25ea827..548a97b 100644
--- a/Help/prop_sf/Fortran_PREPROCESS.rst
+++ b/Help/prop_sf/Fortran_PREPROCESS.rst
@@ -1,6 +1,8 @@
 Fortran_PREPROCESS
 ------------------
 
+.. versionadded:: 3.18
+
 Control whether the Fortran source file should be unconditionally preprocessed.
 
 If unset or empty, rely on the compiler to determine whether the file
diff --git a/Help/prop_sf/INCLUDE_DIRECTORIES.rst b/Help/prop_sf/INCLUDE_DIRECTORIES.rst
index 23de70e..89ffd15 100644
--- a/Help/prop_sf/INCLUDE_DIRECTORIES.rst
+++ b/Help/prop_sf/INCLUDE_DIRECTORIES.rst
@@ -1,6 +1,8 @@
 INCLUDE_DIRECTORIES
 -------------------
 
+.. versionadded:: 3.11
+
 List of preprocessor include file search directories.
 
 This property holds a :ref:`semicolon-separated list <CMake Language Lists>` of paths
diff --git a/Help/prop_sf/SKIP_AUTOGEN.rst b/Help/prop_sf/SKIP_AUTOGEN.rst
index f31185a..2173f59 100644
--- a/Help/prop_sf/SKIP_AUTOGEN.rst
+++ b/Help/prop_sf/SKIP_AUTOGEN.rst
@@ -1,6 +1,8 @@
 SKIP_AUTOGEN
 ------------
 
+.. versionadded:: 3.8
+
 Exclude the source file from :prop_tgt:`AUTOMOC`, :prop_tgt:`AUTOUIC` and
 :prop_tgt:`AUTORCC` processing (for Qt projects).
 
diff --git a/Help/prop_sf/SKIP_AUTOMOC.rst b/Help/prop_sf/SKIP_AUTOMOC.rst
index a929448..e92cfe0 100644
--- a/Help/prop_sf/SKIP_AUTOMOC.rst
+++ b/Help/prop_sf/SKIP_AUTOMOC.rst
@@ -1,6 +1,8 @@
 SKIP_AUTOMOC
 ------------
 
+.. versionadded:: 3.8
+
 Exclude the source file from :prop_tgt:`AUTOMOC` processing (for Qt projects).
 
 For broader exclusion control see :prop_sf:`SKIP_AUTOGEN`.
diff --git a/Help/prop_sf/SKIP_AUTORCC.rst b/Help/prop_sf/SKIP_AUTORCC.rst
index bccccfc..2829c25 100644
--- a/Help/prop_sf/SKIP_AUTORCC.rst
+++ b/Help/prop_sf/SKIP_AUTORCC.rst
@@ -1,6 +1,8 @@
 SKIP_AUTORCC
 ------------
 
+.. versionadded:: 3.8
+
 Exclude the source file from :prop_tgt:`AUTORCC` processing (for Qt projects).
 
 For broader exclusion control see :prop_sf:`SKIP_AUTOGEN`.
diff --git a/Help/prop_sf/SKIP_AUTOUIC.rst b/Help/prop_sf/SKIP_AUTOUIC.rst
index 8c962db..ae9725a 100644
--- a/Help/prop_sf/SKIP_AUTOUIC.rst
+++ b/Help/prop_sf/SKIP_AUTOUIC.rst
@@ -1,6 +1,8 @@
 SKIP_AUTOUIC
 ------------
 
+.. versionadded:: 3.8
+
 Exclude the source file from :prop_tgt:`AUTOUIC` processing (for Qt projects).
 
 :prop_sf:`SKIP_AUTOUIC` can be set on C++ header and source files and on
diff --git a/Help/prop_sf/SKIP_PRECOMPILE_HEADERS.rst b/Help/prop_sf/SKIP_PRECOMPILE_HEADERS.rst
index 0031da3..660de3f 100644
--- a/Help/prop_sf/SKIP_PRECOMPILE_HEADERS.rst
+++ b/Help/prop_sf/SKIP_PRECOMPILE_HEADERS.rst
@@ -1,6 +1,8 @@
 SKIP_PRECOMPILE_HEADERS
 -----------------------
 
+.. versionadded:: 3.16
+
 Is this source file skipped by :prop_tgt:`PRECOMPILE_HEADERS` feature.
 
 This property helps with build problems that one would run into
diff --git a/Help/prop_sf/SKIP_UNITY_BUILD_INCLUSION.rst b/Help/prop_sf/SKIP_UNITY_BUILD_INCLUSION.rst
index 6d1e60d..ae526ac 100644
--- a/Help/prop_sf/SKIP_UNITY_BUILD_INCLUSION.rst
+++ b/Help/prop_sf/SKIP_UNITY_BUILD_INCLUSION.rst
@@ -1,6 +1,8 @@
 SKIP_UNITY_BUILD_INCLUSION
 --------------------------
 
+.. versionadded:: 3.16
+
 Setting this property to true ensures the source file will be skipped by
 unity builds when its associated target has its :prop_tgt:`UNITY_BUILD`
 property set to true.  The source file will instead be compiled on its own
diff --git a/Help/prop_sf/Swift_DEPENDENCIES_FILE.rst b/Help/prop_sf/Swift_DEPENDENCIES_FILE.rst
index faac2df..a90c7eb 100644
--- a/Help/prop_sf/Swift_DEPENDENCIES_FILE.rst
+++ b/Help/prop_sf/Swift_DEPENDENCIES_FILE.rst
@@ -1,5 +1,7 @@
 Swift_DEPENDENCIES_FILE
 -----------------------
 
+.. versionadded:: 3.15
+
 This property sets the path for the Swift dependency file (swiftdeps) for the
 source.  If one is not specified, it will default to ``<OBJECT>.swiftdeps``.
diff --git a/Help/prop_sf/Swift_DIAGNOSTICS_FILE.rst b/Help/prop_sf/Swift_DIAGNOSTICS_FILE.rst
index 5bf5d59..47d5ac3 100644
--- a/Help/prop_sf/Swift_DIAGNOSTICS_FILE.rst
+++ b/Help/prop_sf/Swift_DIAGNOSTICS_FILE.rst
@@ -1,4 +1,6 @@
 Swift_DIAGNOSTICS_FILE
 ----------------------
 
+.. versionadded:: 3.15
+
 This property controls where the Swift diagnostics are serialized.
diff --git a/Help/prop_sf/UNITY_GROUP.rst b/Help/prop_sf/UNITY_GROUP.rst
index ec6b0f6..9c18b70 100644
--- a/Help/prop_sf/UNITY_GROUP.rst
+++ b/Help/prop_sf/UNITY_GROUP.rst
@@ -1,5 +1,7 @@
 UNITY_GROUP
 -----------
 
+.. versionadded:: 3.18
+
 This property controls which *bucket* the source will be part of when
 the :prop_tgt:`UNITY_BUILD_MODE` is set to ``GROUP``.
diff --git a/Help/prop_sf/VS_COPY_TO_OUT_DIR.rst b/Help/prop_sf/VS_COPY_TO_OUT_DIR.rst
index 16c8d83..ebc3061 100644
--- a/Help/prop_sf/VS_COPY_TO_OUT_DIR.rst
+++ b/Help/prop_sf/VS_COPY_TO_OUT_DIR.rst
@@ -1,6 +1,8 @@
 VS_COPY_TO_OUT_DIR
 ------------------
 
+.. versionadded:: 3.8
+
 Sets the ``<CopyToOutputDirectory>`` tag for a source file in a
 Visual Studio project file. Valid values are ``Never``, ``Always``
 and ``PreserveNewest``.
diff --git a/Help/prop_sf/VS_CSHARP_tagname.rst b/Help/prop_sf/VS_CSHARP_tagname.rst
index 91c4a06..75720f8 100644
--- a/Help/prop_sf/VS_CSHARP_tagname.rst
+++ b/Help/prop_sf/VS_CSHARP_tagname.rst
@@ -1,6 +1,8 @@
 VS_CSHARP_<tagname>
 -------------------
 
+.. versionadded:: 3.8
+
 Visual Studio and CSharp source-file-specific configuration.
 
 Tell the :manual:`Visual Studio generators <cmake-generators(7)>`
diff --git a/Help/prop_sf/VS_DEPLOYMENT_CONTENT.rst b/Help/prop_sf/VS_DEPLOYMENT_CONTENT.rst
index 6a38478..ee49b27 100644
--- a/Help/prop_sf/VS_DEPLOYMENT_CONTENT.rst
+++ b/Help/prop_sf/VS_DEPLOYMENT_CONTENT.rst
@@ -1,6 +1,8 @@
 VS_DEPLOYMENT_CONTENT
 ---------------------
 
+.. versionadded:: 3.1
+
 Mark a source file as content for deployment with a Windows Phone or
 Windows Store application when built with a
 :manual:`Visual Studio generators <cmake-generators(7)>`.
diff --git a/Help/prop_sf/VS_DEPLOYMENT_LOCATION.rst b/Help/prop_sf/VS_DEPLOYMENT_LOCATION.rst
index 2ce22fc..b170544 100644
--- a/Help/prop_sf/VS_DEPLOYMENT_LOCATION.rst
+++ b/Help/prop_sf/VS_DEPLOYMENT_LOCATION.rst
@@ -1,6 +1,8 @@
 VS_DEPLOYMENT_LOCATION
 ----------------------
 
+.. versionadded:: 3.1
+
 Specifies the deployment location for a content source file with a Windows
 Phone or Windows Store application when built
 with a :manual:`Visual Studio generators <cmake-generators(7)>`.
diff --git a/Help/prop_sf/VS_INCLUDE_IN_VSIX.rst b/Help/prop_sf/VS_INCLUDE_IN_VSIX.rst
index db470ef..16c56bf 100644
--- a/Help/prop_sf/VS_INCLUDE_IN_VSIX.rst
+++ b/Help/prop_sf/VS_INCLUDE_IN_VSIX.rst
@@ -1,6 +1,8 @@
 VS_INCLUDE_IN_VSIX
 ------------------
 
+.. versionadded:: 3.8
+
 Boolean property to specify if the file should be included within a
 VSIX (Visual Studio Integration Extension) extension package.
 This is needed for development of Visual Studio extensions.
diff --git a/Help/prop_sf/VS_RESOURCE_GENERATOR.rst b/Help/prop_sf/VS_RESOURCE_GENERATOR.rst
index 97e5aac..c5bb4f6 100644
--- a/Help/prop_sf/VS_RESOURCE_GENERATOR.rst
+++ b/Help/prop_sf/VS_RESOURCE_GENERATOR.rst
@@ -1,6 +1,8 @@
 VS_RESOURCE_GENERATOR
 ---------------------
 
+.. versionadded:: 3.8
+
 This property allows to specify the resource generator to be used
 on this file. It defaults to ``PublicResXFileCodeGenerator`` if
 not set.
diff --git a/Help/prop_sf/VS_SETTINGS.rst b/Help/prop_sf/VS_SETTINGS.rst
index 50034fb..322f5a6 100644
--- a/Help/prop_sf/VS_SETTINGS.rst
+++ b/Help/prop_sf/VS_SETTINGS.rst
@@ -1,6 +1,8 @@
 VS_SETTINGS
 -----------
 
+.. versionadded:: 3.18
+
 Set any item metadata on a non-built file.
 
 Takes a list of ``Key=Value`` pairs. Tells the Visual Studio generator to set
diff --git a/Help/prop_sf/VS_SHADER_DISABLE_OPTIMIZATIONS.rst b/Help/prop_sf/VS_SHADER_DISABLE_OPTIMIZATIONS.rst
index 446dd26..6fb6778 100644
--- a/Help/prop_sf/VS_SHADER_DISABLE_OPTIMIZATIONS.rst
+++ b/Help/prop_sf/VS_SHADER_DISABLE_OPTIMIZATIONS.rst
@@ -1,6 +1,8 @@
 VS_SHADER_DISABLE_OPTIMIZATIONS
 -------------------------------
 
+.. versionadded:: 3.11
+
 Disable compiler optimizations for an ``.hlsl`` source file.  This adds the
 ``-Od`` flag to the command line for the FxCompiler tool.  Specify the value
 ``true`` for this property to disable compiler optimizations.
diff --git a/Help/prop_sf/VS_SHADER_ENABLE_DEBUG.rst b/Help/prop_sf/VS_SHADER_ENABLE_DEBUG.rst
index c0e60a3..9c8f9d7 100644
--- a/Help/prop_sf/VS_SHADER_ENABLE_DEBUG.rst
+++ b/Help/prop_sf/VS_SHADER_ENABLE_DEBUG.rst
@@ -1,6 +1,8 @@
 VS_SHADER_ENABLE_DEBUG
 ----------------------
 
+.. versionadded:: 3.11
+
 Enable debugging information for an ``.hlsl`` source file.  This adds the
 ``-Zi`` flag to the command line for the FxCompiler tool.  Specify the value
 ``true`` to generate debugging information for the compiled shader.
diff --git a/Help/prop_sf/VS_SHADER_ENTRYPOINT.rst b/Help/prop_sf/VS_SHADER_ENTRYPOINT.rst
index fe3471f..4b311ba 100644
--- a/Help/prop_sf/VS_SHADER_ENTRYPOINT.rst
+++ b/Help/prop_sf/VS_SHADER_ENTRYPOINT.rst
@@ -1,5 +1,7 @@
 VS_SHADER_ENTRYPOINT
 --------------------
 
+.. versionadded:: 3.1
+
 Specifies the name of the entry point for the shader of a ``.hlsl`` source
 file.
diff --git a/Help/prop_sf/VS_SHADER_FLAGS.rst b/Help/prop_sf/VS_SHADER_FLAGS.rst
index 0a53afd..07f8497 100644
--- a/Help/prop_sf/VS_SHADER_FLAGS.rst
+++ b/Help/prop_sf/VS_SHADER_FLAGS.rst
@@ -1,4 +1,6 @@
 VS_SHADER_FLAGS
 ---------------
 
+.. versionadded:: 3.2
+
 Set additional Visual Studio shader flags of a ``.hlsl`` source file.
diff --git a/Help/prop_sf/VS_SHADER_MODEL.rst b/Help/prop_sf/VS_SHADER_MODEL.rst
index b1cf0df..072df89 100644
--- a/Help/prop_sf/VS_SHADER_MODEL.rst
+++ b/Help/prop_sf/VS_SHADER_MODEL.rst
@@ -1,5 +1,7 @@
 VS_SHADER_MODEL
 ---------------
 
+.. versionadded:: 3.1
+
 Specifies the shader model of a ``.hlsl`` source file. Some shader types can
 only be used with recent shader models
diff --git a/Help/prop_sf/VS_SHADER_OBJECT_FILE_NAME.rst b/Help/prop_sf/VS_SHADER_OBJECT_FILE_NAME.rst
index 093bcc6..3647a5e 100644
--- a/Help/prop_sf/VS_SHADER_OBJECT_FILE_NAME.rst
+++ b/Help/prop_sf/VS_SHADER_OBJECT_FILE_NAME.rst
@@ -1,6 +1,8 @@
 VS_SHADER_OBJECT_FILE_NAME
 --------------------------
 
+.. versionadded:: 3.12
+
 Specifies a file name for the compiled shader object file for an ``.hlsl``
 source file.  This adds the ``-Fo`` flag to the command line for the FxCompiler
 tool.
diff --git a/Help/prop_sf/VS_SHADER_OUTPUT_HEADER_FILE.rst b/Help/prop_sf/VS_SHADER_OUTPUT_HEADER_FILE.rst
index e6763d3..4113a16 100644
--- a/Help/prop_sf/VS_SHADER_OUTPUT_HEADER_FILE.rst
+++ b/Help/prop_sf/VS_SHADER_OUTPUT_HEADER_FILE.rst
@@ -1,5 +1,7 @@
 VS_SHADER_OUTPUT_HEADER_FILE
 ----------------------------
 
+.. versionadded:: 3.10
+
 Set filename for output header file containing object code of a ``.hlsl``
 source file.
diff --git a/Help/prop_sf/VS_SHADER_TYPE.rst b/Help/prop_sf/VS_SHADER_TYPE.rst
index f104837..3fb7e60 100644
--- a/Help/prop_sf/VS_SHADER_TYPE.rst
+++ b/Help/prop_sf/VS_SHADER_TYPE.rst
@@ -1,4 +1,6 @@
 VS_SHADER_TYPE
 --------------
 
+.. versionadded:: 3.1
+
 Set the Visual Studio shader type of a ``.hlsl`` source file.
diff --git a/Help/prop_sf/VS_SHADER_VARIABLE_NAME.rst b/Help/prop_sf/VS_SHADER_VARIABLE_NAME.rst
index 1a5e369..3361b40 100644
--- a/Help/prop_sf/VS_SHADER_VARIABLE_NAME.rst
+++ b/Help/prop_sf/VS_SHADER_VARIABLE_NAME.rst
@@ -1,5 +1,7 @@
 VS_SHADER_VARIABLE_NAME
 -----------------------
 
+.. versionadded:: 3.10
+
 Set name of variable in header file containing object code of a ``.hlsl``
 source file.
diff --git a/Help/prop_sf/VS_TOOL_OVERRIDE.rst b/Help/prop_sf/VS_TOOL_OVERRIDE.rst
index 8bdc5ca..b2f4112 100644
--- a/Help/prop_sf/VS_TOOL_OVERRIDE.rst
+++ b/Help/prop_sf/VS_TOOL_OVERRIDE.rst
@@ -1,5 +1,7 @@
 VS_TOOL_OVERRIDE
 ----------------
 
+.. versionadded:: 3.7
+
 Override the default Visual Studio tool that will be applied to the source file
 with a new tool not based on the extension of the file.
diff --git a/Help/prop_sf/VS_XAML_TYPE.rst b/Help/prop_sf/VS_XAML_TYPE.rst
index 1a274ba..612b07b 100644
--- a/Help/prop_sf/VS_XAML_TYPE.rst
+++ b/Help/prop_sf/VS_XAML_TYPE.rst
@@ -1,6 +1,8 @@
 VS_XAML_TYPE
 ------------
 
+.. versionadded:: 3.3
+
 Mark a Extensible Application Markup Language (XAML) source file
 as a different type than the default ``Page``.
 The most common usage would be to set the default ``App.xaml`` file as
diff --git a/Help/prop_sf/XCODE_EXPLICIT_FILE_TYPE.rst b/Help/prop_sf/XCODE_EXPLICIT_FILE_TYPE.rst
index b8cf946..5a50d7d 100644
--- a/Help/prop_sf/XCODE_EXPLICIT_FILE_TYPE.rst
+++ b/Help/prop_sf/XCODE_EXPLICIT_FILE_TYPE.rst
@@ -1,6 +1,8 @@
 XCODE_EXPLICIT_FILE_TYPE
 ------------------------
 
+.. versionadded:: 3.1
+
 Set the :generator:`Xcode` ``explicitFileType`` attribute on its reference to a
 source file.  CMake computes a default based on file extension but
 can be told explicitly with this property.
diff --git a/Help/prop_sf/XCODE_FILE_ATTRIBUTES.rst b/Help/prop_sf/XCODE_FILE_ATTRIBUTES.rst
index 4c93f44..ba51e00 100644
--- a/Help/prop_sf/XCODE_FILE_ATTRIBUTES.rst
+++ b/Help/prop_sf/XCODE_FILE_ATTRIBUTES.rst
@@ -1,6 +1,8 @@
 XCODE_FILE_ATTRIBUTES
 ---------------------
 
+.. versionadded:: 3.7
+
 Add values to the :generator:`Xcode` ``ATTRIBUTES`` setting on its reference to a
 source file.  Among other things, this can be used to set the role on
 a ``.mig`` file::
diff --git a/Help/prop_sf/XCODE_LAST_KNOWN_FILE_TYPE.rst b/Help/prop_sf/XCODE_LAST_KNOWN_FILE_TYPE.rst
index b21891f..0b84e31 100644
--- a/Help/prop_sf/XCODE_LAST_KNOWN_FILE_TYPE.rst
+++ b/Help/prop_sf/XCODE_LAST_KNOWN_FILE_TYPE.rst
@@ -1,6 +1,8 @@
 XCODE_LAST_KNOWN_FILE_TYPE
 --------------------------
 
+.. versionadded:: 3.1
+
 Set the :generator:`Xcode` ``lastKnownFileType`` attribute on its reference to
 a source file.  CMake computes a default based on file extension but
 can be told explicitly with this property.
diff --git a/Help/prop_test/DISABLED.rst b/Help/prop_test/DISABLED.rst
index 1d469e8..cbf07a5 100644
--- a/Help/prop_test/DISABLED.rst
+++ b/Help/prop_test/DISABLED.rst
@@ -1,6 +1,8 @@
 DISABLED
 --------
 
+.. versionadded:: 3.9
+
 If set to ``True``, the test will be skipped and its status will be 'Not Run'. A
 ``DISABLED`` test will not be counted in the total number of tests and its
 completion status will be reported to CDash as ``Disabled``.
diff --git a/Help/prop_test/FIXTURES_CLEANUP.rst b/Help/prop_test/FIXTURES_CLEANUP.rst
index 3075b4d..aa043da 100644
--- a/Help/prop_test/FIXTURES_CLEANUP.rst
+++ b/Help/prop_test/FIXTURES_CLEANUP.rst
@@ -1,6 +1,8 @@
 FIXTURES_CLEANUP
 ----------------
 
+.. versionadded:: 3.7
+
 Specifies a list of fixtures for which the test is to be treated as a cleanup
 test. These fixture names are distinct from test case names and are not
 required to have any similarity to the names of tests associated with them.
diff --git a/Help/prop_test/FIXTURES_REQUIRED.rst b/Help/prop_test/FIXTURES_REQUIRED.rst
index e3f60c4..d92808a 100644
--- a/Help/prop_test/FIXTURES_REQUIRED.rst
+++ b/Help/prop_test/FIXTURES_REQUIRED.rst
@@ -1,6 +1,8 @@
 FIXTURES_REQUIRED
 -----------------
 
+.. versionadded:: 3.7
+
 Specifies a list of fixtures the test requires. Fixture names are case
 sensitive and they are not required to have any similarity to test names.
 
diff --git a/Help/prop_test/FIXTURES_SETUP.rst b/Help/prop_test/FIXTURES_SETUP.rst
index fdb21cc..04a09d8 100644
--- a/Help/prop_test/FIXTURES_SETUP.rst
+++ b/Help/prop_test/FIXTURES_SETUP.rst
@@ -1,6 +1,8 @@
 FIXTURES_SETUP
 --------------
 
+.. versionadded:: 3.7
+
 Specifies a list of fixtures for which the test is to be treated as a setup
 test. These fixture names are distinct from test case names and are not
 required to have any similarity to the names of tests associated with them.
diff --git a/Help/prop_test/PROCESSOR_AFFINITY.rst b/Help/prop_test/PROCESSOR_AFFINITY.rst
index 38ec179..f48a69c 100644
--- a/Help/prop_test/PROCESSOR_AFFINITY.rst
+++ b/Help/prop_test/PROCESSOR_AFFINITY.rst
@@ -1,6 +1,8 @@
 PROCESSOR_AFFINITY
 ------------------
 
+.. versionadded:: 3.12
+
 Set to a true value to ask CTest to launch the test process with CPU affinity
 for a fixed set of processors.  If enabled and supported for the current
 platform, CTest will choose a set of processors to place in the CPU affinity
diff --git a/Help/prop_test/RESOURCE_GROUPS.rst b/Help/prop_test/RESOURCE_GROUPS.rst
index 63c56ce..26c8fa2 100644
--- a/Help/prop_test/RESOURCE_GROUPS.rst
+++ b/Help/prop_test/RESOURCE_GROUPS.rst
@@ -1,6 +1,8 @@
 RESOURCE_GROUPS
 ---------------
 
+.. versionadded:: 3.16
+
 Specify resources required by a test, grouped in a way that is meaningful to
 the test.  See :ref:`resource allocation <ctest-resource-allocation>`
 for more information on how this property integrates into the CTest resource
diff --git a/Help/prop_test/SKIP_REGULAR_EXPRESSION.rst b/Help/prop_test/SKIP_REGULAR_EXPRESSION.rst
index 2c6d980..46c4363 100644
--- a/Help/prop_test/SKIP_REGULAR_EXPRESSION.rst
+++ b/Help/prop_test/SKIP_REGULAR_EXPRESSION.rst
@@ -1,6 +1,8 @@
 SKIP_REGULAR_EXPRESSION
 -----------------------
 
+.. versionadded:: 3.16
+
 If the output matches this regular expression the test will be marked as skipped.
 
 If set, if the output matches one of specified regular expressions,
diff --git a/Help/prop_test/TIMEOUT_AFTER_MATCH.rst b/Help/prop_test/TIMEOUT_AFTER_MATCH.rst
index d607992..726dcab 100644
--- a/Help/prop_test/TIMEOUT_AFTER_MATCH.rst
+++ b/Help/prop_test/TIMEOUT_AFTER_MATCH.rst
@@ -1,6 +1,8 @@
 TIMEOUT_AFTER_MATCH
 -------------------
 
+.. versionadded:: 3.6
+
 Change a test's timeout duration after a matching line is encountered
 in its output.
 
diff --git a/Help/prop_tgt/ADDITIONAL_CLEAN_FILES.rst b/Help/prop_tgt/ADDITIONAL_CLEAN_FILES.rst
index 3b9d965..dc87d23 100644
--- a/Help/prop_tgt/ADDITIONAL_CLEAN_FILES.rst
+++ b/Help/prop_tgt/ADDITIONAL_CLEAN_FILES.rst
@@ -1,6 +1,8 @@
 ADDITIONAL_CLEAN_FILES
 ----------------------
 
+.. versionadded:: 3.15
+
 A :ref:`;-list <CMake Language Lists>` of files or directories that will be
 removed as a part of the global ``clean`` target.  It can be used to specify
 files and directories that are generated as part of building the target or
diff --git a/Help/prop_tgt/AIX_EXPORT_ALL_SYMBOLS.rst b/Help/prop_tgt/AIX_EXPORT_ALL_SYMBOLS.rst
index 15ddc0b..de98fdf 100644
--- a/Help/prop_tgt/AIX_EXPORT_ALL_SYMBOLS.rst
+++ b/Help/prop_tgt/AIX_EXPORT_ALL_SYMBOLS.rst
@@ -1,6 +1,8 @@
 AIX_EXPORT_ALL_SYMBOLS
 ----------------------
 
+.. versionadded:: 3.17
+
 On AIX, CMake automatically exports all symbols from shared libraries, and
 from executables with the :prop_tgt:`ENABLE_EXPORTS` target property set.
 Explicitly disable this boolean property to suppress the behavior and
diff --git a/Help/prop_tgt/ALIAS_GLOBAL.rst b/Help/prop_tgt/ALIAS_GLOBAL.rst
index 8854f57..a8859c6 100644
--- a/Help/prop_tgt/ALIAS_GLOBAL.rst
+++ b/Help/prop_tgt/ALIAS_GLOBAL.rst
@@ -1,6 +1,8 @@
 ALIAS_GLOBAL
 ------------
 
+.. versionadded:: 3.18
+
 Read-only property indicating of whether an :ref:`ALIAS target <Alias Targets>`
 is globally visible.
 
diff --git a/Help/prop_tgt/ANDROID_ANT_ADDITIONAL_OPTIONS.rst b/Help/prop_tgt/ANDROID_ANT_ADDITIONAL_OPTIONS.rst
index af6b405..eceb17d 100644
--- a/Help/prop_tgt/ANDROID_ANT_ADDITIONAL_OPTIONS.rst
+++ b/Help/prop_tgt/ANDROID_ANT_ADDITIONAL_OPTIONS.rst
@@ -1,6 +1,8 @@
 ANDROID_ANT_ADDITIONAL_OPTIONS
 ------------------------------
 
+.. versionadded:: 3.4
+
 Set the additional options for Android Ant build system. This is
 a string value containing all command line options for the Ant build.
 This property is initialized by the value of the
diff --git a/Help/prop_tgt/ANDROID_API.rst b/Help/prop_tgt/ANDROID_API.rst
index 63464d7..7664f18 100644
--- a/Help/prop_tgt/ANDROID_API.rst
+++ b/Help/prop_tgt/ANDROID_API.rst
@@ -1,6 +1,8 @@
 ANDROID_API
 -----------
 
+.. versionadded:: 3.1
+
 When :ref:`Cross Compiling for Android with NVIDIA Nsight Tegra Visual Studio
 Edition`, this property sets the Android target API version (e.g. ``15``).
 The version number must be a positive decimal integer.  This property is
diff --git a/Help/prop_tgt/ANDROID_API_MIN.rst b/Help/prop_tgt/ANDROID_API_MIN.rst
index 773ab3f..7ca2455 100644
--- a/Help/prop_tgt/ANDROID_API_MIN.rst
+++ b/Help/prop_tgt/ANDROID_API_MIN.rst
@@ -1,6 +1,8 @@
 ANDROID_API_MIN
 ---------------
 
+.. versionadded:: 3.2
+
 Set the Android MIN API version (e.g. ``9``).  The version number
 must be a positive decimal integer.  This property is initialized by
 the value of the :variable:`CMAKE_ANDROID_API_MIN` variable if it is set
diff --git a/Help/prop_tgt/ANDROID_ARCH.rst b/Help/prop_tgt/ANDROID_ARCH.rst
index 3e07e5a..94b76dd 100644
--- a/Help/prop_tgt/ANDROID_ARCH.rst
+++ b/Help/prop_tgt/ANDROID_ARCH.rst
@@ -1,6 +1,8 @@
 ANDROID_ARCH
 ------------
 
+.. versionadded:: 3.4
+
 When :ref:`Cross Compiling for Android with NVIDIA Nsight Tegra Visual Studio
 Edition`, this property sets the Android target architecture.
 
diff --git a/Help/prop_tgt/ANDROID_ASSETS_DIRECTORIES.rst b/Help/prop_tgt/ANDROID_ASSETS_DIRECTORIES.rst
index 764a582..b09a8b7 100644
--- a/Help/prop_tgt/ANDROID_ASSETS_DIRECTORIES.rst
+++ b/Help/prop_tgt/ANDROID_ASSETS_DIRECTORIES.rst
@@ -1,6 +1,8 @@
 ANDROID_ASSETS_DIRECTORIES
 --------------------------
 
+.. versionadded:: 3.4
+
 Set the Android assets directories to copy into the main assets
 folder before build. This a string property that contains the
 directory paths separated by semicolon.
diff --git a/Help/prop_tgt/ANDROID_GUI.rst b/Help/prop_tgt/ANDROID_GUI.rst
index 92e2041..cc022db 100644
--- a/Help/prop_tgt/ANDROID_GUI.rst
+++ b/Help/prop_tgt/ANDROID_GUI.rst
@@ -1,6 +1,8 @@
 ANDROID_GUI
 -----------
 
+.. versionadded:: 3.1
+
 When :ref:`Cross Compiling for Android with NVIDIA Nsight Tegra Visual Studio
 Edition`, this property specifies whether to build an executable as an
 application package on Android.
diff --git a/Help/prop_tgt/ANDROID_JAR_DEPENDENCIES.rst b/Help/prop_tgt/ANDROID_JAR_DEPENDENCIES.rst
index 42937c1..9880daf 100644
--- a/Help/prop_tgt/ANDROID_JAR_DEPENDENCIES.rst
+++ b/Help/prop_tgt/ANDROID_JAR_DEPENDENCIES.rst
@@ -1,6 +1,8 @@
 ANDROID_JAR_DEPENDENCIES
 ------------------------
 
+.. versionadded:: 3.4
+
 Set the Android property that specifies JAR dependencies.
 This is a string value property. This property is initialized
 by the value of the :variable:`CMAKE_ANDROID_JAR_DEPENDENCIES`
diff --git a/Help/prop_tgt/ANDROID_JAR_DIRECTORIES.rst b/Help/prop_tgt/ANDROID_JAR_DIRECTORIES.rst
index 54f0a8f..6fef50b 100644
--- a/Help/prop_tgt/ANDROID_JAR_DIRECTORIES.rst
+++ b/Help/prop_tgt/ANDROID_JAR_DIRECTORIES.rst
@@ -1,6 +1,8 @@
 ANDROID_JAR_DIRECTORIES
 -----------------------
 
+.. versionadded:: 3.4
+
 Set the Android property that specifies directories to search for
 the JAR libraries.
 
diff --git a/Help/prop_tgt/ANDROID_JAVA_SOURCE_DIR.rst b/Help/prop_tgt/ANDROID_JAVA_SOURCE_DIR.rst
index 90ef1ce..9ea9884 100644
--- a/Help/prop_tgt/ANDROID_JAVA_SOURCE_DIR.rst
+++ b/Help/prop_tgt/ANDROID_JAVA_SOURCE_DIR.rst
@@ -1,6 +1,8 @@
 ANDROID_JAVA_SOURCE_DIR
 -----------------------
 
+.. versionadded:: 3.4
+
 Set the Android property that defines the Java source code root directories.
 This a string property that contains the directory paths separated by semicolon.
 This property is initialized by the value of the
diff --git a/Help/prop_tgt/ANDROID_NATIVE_LIB_DEPENDENCIES.rst b/Help/prop_tgt/ANDROID_NATIVE_LIB_DEPENDENCIES.rst
index 759a37b..3aa741f 100644
--- a/Help/prop_tgt/ANDROID_NATIVE_LIB_DEPENDENCIES.rst
+++ b/Help/prop_tgt/ANDROID_NATIVE_LIB_DEPENDENCIES.rst
@@ -1,6 +1,8 @@
 ANDROID_NATIVE_LIB_DEPENDENCIES
 -------------------------------
 
+.. versionadded:: 3.4
+
 Set the Android property that specifies the .so dependencies.
 This is a string property.
 
diff --git a/Help/prop_tgt/ANDROID_NATIVE_LIB_DIRECTORIES.rst b/Help/prop_tgt/ANDROID_NATIVE_LIB_DIRECTORIES.rst
index d0cd29d..98200d9 100644
--- a/Help/prop_tgt/ANDROID_NATIVE_LIB_DIRECTORIES.rst
+++ b/Help/prop_tgt/ANDROID_NATIVE_LIB_DIRECTORIES.rst
@@ -1,6 +1,8 @@
 ANDROID_NATIVE_LIB_DIRECTORIES
 ------------------------------
 
+.. versionadded:: 3.4
+
 Set the Android property that specifies directories to search for the ``.so``
 libraries.
 
diff --git a/Help/prop_tgt/ANDROID_PROCESS_MAX.rst b/Help/prop_tgt/ANDROID_PROCESS_MAX.rst
index 847acae..0b6aba7 100644
--- a/Help/prop_tgt/ANDROID_PROCESS_MAX.rst
+++ b/Help/prop_tgt/ANDROID_PROCESS_MAX.rst
@@ -1,6 +1,8 @@
 ANDROID_PROCESS_MAX
 -------------------
 
+.. versionadded:: 3.4
+
 Set the Android property that defines the maximum number of a
 parallel Android NDK compiler processes (e.g. ``4``).
 This property is initialized by the value of the
diff --git a/Help/prop_tgt/ANDROID_PROGUARD.rst b/Help/prop_tgt/ANDROID_PROGUARD.rst
index dafc51e..b5ce166 100644
--- a/Help/prop_tgt/ANDROID_PROGUARD.rst
+++ b/Help/prop_tgt/ANDROID_PROGUARD.rst
@@ -1,6 +1,8 @@
 ANDROID_PROGUARD
 ----------------
 
+.. versionadded:: 3.4
+
 When this property is set to true that enables the ProGuard tool to shrink,
 optimize, and obfuscate the code by removing unused code and renaming
 classes, fields, and methods with semantically obscure names.
diff --git a/Help/prop_tgt/ANDROID_PROGUARD_CONFIG_PATH.rst b/Help/prop_tgt/ANDROID_PROGUARD_CONFIG_PATH.rst
index 0e929d1..6ac59d8 100644
--- a/Help/prop_tgt/ANDROID_PROGUARD_CONFIG_PATH.rst
+++ b/Help/prop_tgt/ANDROID_PROGUARD_CONFIG_PATH.rst
@@ -1,6 +1,8 @@
 ANDROID_PROGUARD_CONFIG_PATH
 ----------------------------
 
+.. versionadded:: 3.4
+
 Set the Android property that specifies the location of the ProGuard
 config file. Leave empty to use the default one.
 This a string property that contains the path to ProGuard config file.
diff --git a/Help/prop_tgt/ANDROID_SECURE_PROPS_PATH.rst b/Help/prop_tgt/ANDROID_SECURE_PROPS_PATH.rst
index 9533f1a..f2ffa2e 100644
--- a/Help/prop_tgt/ANDROID_SECURE_PROPS_PATH.rst
+++ b/Help/prop_tgt/ANDROID_SECURE_PROPS_PATH.rst
@@ -1,6 +1,8 @@
 ANDROID_SECURE_PROPS_PATH
 -------------------------
 
+.. versionadded:: 3.4
+
 Set the Android property that states the location of the secure properties file.
 This is a string property that contains the file path.
 This property is initialized by the value of the
diff --git a/Help/prop_tgt/ANDROID_SKIP_ANT_STEP.rst b/Help/prop_tgt/ANDROID_SKIP_ANT_STEP.rst
index 6361896..1a54bce 100644
--- a/Help/prop_tgt/ANDROID_SKIP_ANT_STEP.rst
+++ b/Help/prop_tgt/ANDROID_SKIP_ANT_STEP.rst
@@ -1,6 +1,8 @@
 ANDROID_SKIP_ANT_STEP
 ---------------------
 
+.. versionadded:: 3.4
+
 Set the Android property that defines whether or not to skip the Ant build step.
 This is a boolean property initialized by the value of the
 :variable:`CMAKE_ANDROID_SKIP_ANT_STEP` variable if it is set when a target is created.
diff --git a/Help/prop_tgt/ANDROID_STL_TYPE.rst b/Help/prop_tgt/ANDROID_STL_TYPE.rst
index 386e96e..c83712b 100644
--- a/Help/prop_tgt/ANDROID_STL_TYPE.rst
+++ b/Help/prop_tgt/ANDROID_STL_TYPE.rst
@@ -1,6 +1,8 @@
 ANDROID_STL_TYPE
 ----------------
 
+.. versionadded:: 3.4
+
 When :ref:`Cross Compiling for Android with NVIDIA Nsight Tegra Visual Studio
 Edition`, this property specifies the type of STL support for the project.
 This is a string property that could set to the one of the following values:
diff --git a/Help/prop_tgt/AUTOGEN_BUILD_DIR.rst b/Help/prop_tgt/AUTOGEN_BUILD_DIR.rst
index 909b14c..ff42ae8 100644
--- a/Help/prop_tgt/AUTOGEN_BUILD_DIR.rst
+++ b/Help/prop_tgt/AUTOGEN_BUILD_DIR.rst
@@ -1,6 +1,8 @@
 AUTOGEN_BUILD_DIR
 -----------------
 
+.. versionadded:: 3.9
+
 Directory where :prop_tgt:`AUTOMOC`, :prop_tgt:`AUTOUIC` and :prop_tgt:`AUTORCC`
 generate files for the target.
 
diff --git a/Help/prop_tgt/AUTOGEN_ORIGIN_DEPENDS.rst b/Help/prop_tgt/AUTOGEN_ORIGIN_DEPENDS.rst
index 022bab5..563190a 100644
--- a/Help/prop_tgt/AUTOGEN_ORIGIN_DEPENDS.rst
+++ b/Help/prop_tgt/AUTOGEN_ORIGIN_DEPENDS.rst
@@ -1,6 +1,8 @@
 AUTOGEN_ORIGIN_DEPENDS
 ----------------------
 
+.. versionadded:: 3.14
+
 Switch for forwarding origin target dependencies to the corresponding
 ``_autogen`` target.
 
diff --git a/Help/prop_tgt/AUTOGEN_PARALLEL.rst b/Help/prop_tgt/AUTOGEN_PARALLEL.rst
index 968b619..663b54e 100644
--- a/Help/prop_tgt/AUTOGEN_PARALLEL.rst
+++ b/Help/prop_tgt/AUTOGEN_PARALLEL.rst
@@ -1,6 +1,8 @@
 AUTOGEN_PARALLEL
 ----------------
 
+.. versionadded:: 3.11
+
 Number of parallel ``moc`` or ``uic`` processes to start when using
 :prop_tgt:`AUTOMOC` and :prop_tgt:`AUTOUIC`.
 
diff --git a/Help/prop_tgt/AUTOMOC_COMPILER_PREDEFINES.rst b/Help/prop_tgt/AUTOMOC_COMPILER_PREDEFINES.rst
index 57a647f..8998284 100644
--- a/Help/prop_tgt/AUTOMOC_COMPILER_PREDEFINES.rst
+++ b/Help/prop_tgt/AUTOMOC_COMPILER_PREDEFINES.rst
@@ -1,6 +1,8 @@
 AUTOMOC_COMPILER_PREDEFINES
 ---------------------------
 
+.. versionadded:: 3.10
+
 Boolean value used by :prop_tgt:`AUTOMOC` to determine if the
 compiler pre definitions file ``moc_predefs.h`` should be generated.
 
diff --git a/Help/prop_tgt/AUTOMOC_DEPEND_FILTERS.rst b/Help/prop_tgt/AUTOMOC_DEPEND_FILTERS.rst
index 6eda26c..1f31700 100644
--- a/Help/prop_tgt/AUTOMOC_DEPEND_FILTERS.rst
+++ b/Help/prop_tgt/AUTOMOC_DEPEND_FILTERS.rst
@@ -1,6 +1,8 @@
 AUTOMOC_DEPEND_FILTERS
 ----------------------
 
+.. versionadded:: 3.9
+
 Filter definitions used by :prop_tgt:`AUTOMOC` to extract file names from a
 source file that are registered as additional dependencies for the
 ``moc`` file of the source file.
diff --git a/Help/prop_tgt/AUTOMOC_EXECUTABLE.rst b/Help/prop_tgt/AUTOMOC_EXECUTABLE.rst
index 6b66ce8..f4b8396 100644
--- a/Help/prop_tgt/AUTOMOC_EXECUTABLE.rst
+++ b/Help/prop_tgt/AUTOMOC_EXECUTABLE.rst
@@ -1,6 +1,8 @@
 AUTOMOC_EXECUTABLE
 ------------------
 
+.. versionadded:: 3.14
+
 :prop_tgt:`AUTOMOC_EXECUTABLE` is file path pointing to the ``moc``
 executable to use for :prop_tgt:`AUTOMOC` enabled files. Setting
 this property will make CMake skip the automatic detection of the
diff --git a/Help/prop_tgt/AUTOMOC_MACRO_NAMES.rst b/Help/prop_tgt/AUTOMOC_MACRO_NAMES.rst
index 5329bba..a53810d 100644
--- a/Help/prop_tgt/AUTOMOC_MACRO_NAMES.rst
+++ b/Help/prop_tgt/AUTOMOC_MACRO_NAMES.rst
@@ -1,6 +1,8 @@
 AUTOMOC_MACRO_NAMES
 -------------------
 
+.. versionadded:: 3.10
+
 A :ref:`semicolon-separated list <CMake Language Lists>` list of macro names used by
 :prop_tgt:`AUTOMOC` to determine if a C++ file needs to be processed by ``moc``.
 
diff --git a/Help/prop_tgt/AUTOMOC_PATH_PREFIX.rst b/Help/prop_tgt/AUTOMOC_PATH_PREFIX.rst
index 5ed504f..836d953 100644
--- a/Help/prop_tgt/AUTOMOC_PATH_PREFIX.rst
+++ b/Help/prop_tgt/AUTOMOC_PATH_PREFIX.rst
@@ -1,6 +1,8 @@
 AUTOMOC_PATH_PREFIX
 -------------------
 
+.. versionadded:: 3.16
+
 When this property is ``ON``, CMake will generate the ``-p`` path prefix
 option for ``moc`` on :prop_tgt:`AUTOMOC` enabled Qt targets.
 
diff --git a/Help/prop_tgt/AUTORCC_EXECUTABLE.rst b/Help/prop_tgt/AUTORCC_EXECUTABLE.rst
index ca0fbd7..4f85fba 100644
--- a/Help/prop_tgt/AUTORCC_EXECUTABLE.rst
+++ b/Help/prop_tgt/AUTORCC_EXECUTABLE.rst
@@ -1,6 +1,8 @@
 AUTORCC_EXECUTABLE
 ------------------
 
+.. versionadded:: 3.14
+
 :prop_tgt:`AUTORCC_EXECUTABLE` is file path pointing to the ``rcc``
 executable to use for :prop_tgt:`AUTORCC` enabled files. Setting
 this property will make CMake skip the automatic detection of the
diff --git a/Help/prop_tgt/AUTOUIC_EXECUTABLE.rst b/Help/prop_tgt/AUTOUIC_EXECUTABLE.rst
index 03bd554..5966326 100644
--- a/Help/prop_tgt/AUTOUIC_EXECUTABLE.rst
+++ b/Help/prop_tgt/AUTOUIC_EXECUTABLE.rst
@@ -1,6 +1,8 @@
 AUTOUIC_EXECUTABLE
 ------------------
 
+.. versionadded:: 3.14
+
 :prop_tgt:`AUTOUIC_EXECUTABLE` is file path pointing to the ``uic``
 executable to use for :prop_tgt:`AUTOUIC` enabled files. Setting
 this property will make CMake skip the automatic detection of the
diff --git a/Help/prop_tgt/AUTOUIC_SEARCH_PATHS.rst b/Help/prop_tgt/AUTOUIC_SEARCH_PATHS.rst
index 96d9f89..87fea48 100644
--- a/Help/prop_tgt/AUTOUIC_SEARCH_PATHS.rst
+++ b/Help/prop_tgt/AUTOUIC_SEARCH_PATHS.rst
@@ -1,6 +1,8 @@
 AUTOUIC_SEARCH_PATHS
 --------------------
 
+.. versionadded:: 3.9
+
 Search path list used by :prop_tgt:`AUTOUIC` to find included
 ``.ui`` files.
 
diff --git a/Help/prop_tgt/BINARY_DIR.rst b/Help/prop_tgt/BINARY_DIR.rst
index 246f7e6..beab12c 100644
--- a/Help/prop_tgt/BINARY_DIR.rst
+++ b/Help/prop_tgt/BINARY_DIR.rst
@@ -1,6 +1,8 @@
 BINARY_DIR
 ----------
 
+.. versionadded:: 3.4
+
 This read-only property reports the value of the
 :variable:`CMAKE_CURRENT_BINARY_DIR` variable in the directory in which
 the target was defined.
diff --git a/Help/prop_tgt/BUILD_RPATH.rst b/Help/prop_tgt/BUILD_RPATH.rst
index d978b94..1f917a5 100644
--- a/Help/prop_tgt/BUILD_RPATH.rst
+++ b/Help/prop_tgt/BUILD_RPATH.rst
@@ -1,6 +1,8 @@
 BUILD_RPATH
 -----------
 
+.. versionadded:: 3.8
+
 A :ref:`semicolon-separated list <CMake Language Lists>` specifying runtime path (``RPATH``)
 entries to add to binaries linked in the build tree (for platforms that
 support it).  The entries will *not* be used for binaries in the install
diff --git a/Help/prop_tgt/BUILD_RPATH_USE_ORIGIN.rst b/Help/prop_tgt/BUILD_RPATH_USE_ORIGIN.rst
index 3378797..2cdfa0d 100644
--- a/Help/prop_tgt/BUILD_RPATH_USE_ORIGIN.rst
+++ b/Help/prop_tgt/BUILD_RPATH_USE_ORIGIN.rst
@@ -1,6 +1,8 @@
 BUILD_RPATH_USE_ORIGIN
 ----------------------
 
+.. versionadded:: 3.14
+
 Whether to use relative paths for the build ``RPATH``.
 
 This property is initialized by the value of the variable
diff --git a/Help/prop_tgt/BUILD_WITH_INSTALL_NAME_DIR.rst b/Help/prop_tgt/BUILD_WITH_INSTALL_NAME_DIR.rst
index bbb9a24..073dce5 100644
--- a/Help/prop_tgt/BUILD_WITH_INSTALL_NAME_DIR.rst
+++ b/Help/prop_tgt/BUILD_WITH_INSTALL_NAME_DIR.rst
@@ -1,6 +1,8 @@
 BUILD_WITH_INSTALL_NAME_DIR
 ---------------------------
 
+.. versionadded:: 3.9
+
 ``BUILD_WITH_INSTALL_NAME_DIR`` is a boolean specifying whether the macOS
 ``install_name`` of a target in the build tree uses the directory given by
 :prop_tgt:`INSTALL_NAME_DIR`.  This setting only applies to targets on macOS.
diff --git a/Help/prop_tgt/COMMON_LANGUAGE_RUNTIME.rst b/Help/prop_tgt/COMMON_LANGUAGE_RUNTIME.rst
index 052ac6d..adfa6f7 100644
--- a/Help/prop_tgt/COMMON_LANGUAGE_RUNTIME.rst
+++ b/Help/prop_tgt/COMMON_LANGUAGE_RUNTIME.rst
@@ -1,6 +1,8 @@
 COMMON_LANGUAGE_RUNTIME
 -----------------------
 
+.. versionadded:: 3.12
+
 By setting this target property, the target is configured to build with
 ``C++/CLI`` support.
 
diff --git a/Help/prop_tgt/COMPILE_FEATURES.rst b/Help/prop_tgt/COMPILE_FEATURES.rst
index 46aec4f..9b937ed 100644
--- a/Help/prop_tgt/COMPILE_FEATURES.rst
+++ b/Help/prop_tgt/COMPILE_FEATURES.rst
@@ -1,6 +1,8 @@
 COMPILE_FEATURES
 ----------------
 
+.. versionadded:: 3.1
+
 Compiler features enabled for this target.
 
 The list of features in this property are a subset of the features listed
diff --git a/Help/prop_tgt/COMPILE_PDB_NAME.rst b/Help/prop_tgt/COMPILE_PDB_NAME.rst
index 24a9f62..b76afeb 100644
--- a/Help/prop_tgt/COMPILE_PDB_NAME.rst
+++ b/Help/prop_tgt/COMPILE_PDB_NAME.rst
@@ -1,6 +1,8 @@
 COMPILE_PDB_NAME
 ----------------
 
+.. versionadded:: 3.1
+
 Output name for the MS debug symbol ``.pdb`` file generated by the
 compiler while building source files.
 
diff --git a/Help/prop_tgt/COMPILE_PDB_NAME_CONFIG.rst b/Help/prop_tgt/COMPILE_PDB_NAME_CONFIG.rst
index e4077f5..4c9825d 100644
--- a/Help/prop_tgt/COMPILE_PDB_NAME_CONFIG.rst
+++ b/Help/prop_tgt/COMPILE_PDB_NAME_CONFIG.rst
@@ -1,6 +1,8 @@
 COMPILE_PDB_NAME_<CONFIG>
 -------------------------
 
+.. versionadded:: 3.1
+
 Per-configuration output name for the MS debug symbol ``.pdb`` file
 generated by the compiler while building source files.
 
diff --git a/Help/prop_tgt/COMPILE_PDB_OUTPUT_DIRECTORY.rst b/Help/prop_tgt/COMPILE_PDB_OUTPUT_DIRECTORY.rst
index 34f49be..3f3df66 100644
--- a/Help/prop_tgt/COMPILE_PDB_OUTPUT_DIRECTORY.rst
+++ b/Help/prop_tgt/COMPILE_PDB_OUTPUT_DIRECTORY.rst
@@ -1,6 +1,8 @@
 COMPILE_PDB_OUTPUT_DIRECTORY
 ----------------------------
 
+.. versionadded:: 3.1
+
 Output directory for the MS debug symbol ``.pdb`` file
 generated by the compiler while building source files.
 
diff --git a/Help/prop_tgt/COMPILE_PDB_OUTPUT_DIRECTORY_CONFIG.rst b/Help/prop_tgt/COMPILE_PDB_OUTPUT_DIRECTORY_CONFIG.rst
index f261756..c25c2fc 100644
--- a/Help/prop_tgt/COMPILE_PDB_OUTPUT_DIRECTORY_CONFIG.rst
+++ b/Help/prop_tgt/COMPILE_PDB_OUTPUT_DIRECTORY_CONFIG.rst
@@ -1,6 +1,8 @@
 COMPILE_PDB_OUTPUT_DIRECTORY_<CONFIG>
 -------------------------------------
 
+.. versionadded:: 3.1
+
 Per-configuration output directory for the MS debug symbol ``.pdb`` file
 generated by the compiler while building source files.
 
diff --git a/Help/prop_tgt/CROSSCOMPILING_EMULATOR.rst b/Help/prop_tgt/CROSSCOMPILING_EMULATOR.rst
index 87c5978..d7fb9b1 100644
--- a/Help/prop_tgt/CROSSCOMPILING_EMULATOR.rst
+++ b/Help/prop_tgt/CROSSCOMPILING_EMULATOR.rst
@@ -1,6 +1,8 @@
 CROSSCOMPILING_EMULATOR
 -----------------------
 
+.. versionadded:: 3.3
+
 Use the given emulator to run executables created when crosscompiling.
 This command will be added as a prefix to :command:`add_test`,
 :command:`add_custom_command`, and :command:`add_custom_target` commands
diff --git a/Help/prop_tgt/CUDA_ARCHITECTURES.rst b/Help/prop_tgt/CUDA_ARCHITECTURES.rst
index bae3c6f..d56b769 100644
--- a/Help/prop_tgt/CUDA_ARCHITECTURES.rst
+++ b/Help/prop_tgt/CUDA_ARCHITECTURES.rst
@@ -1,6 +1,8 @@
 CUDA_ARCHITECTURES
 ------------------
 
+.. versionadded:: 3.18
+
 List of architectures to generate device code for.
 
 An architecture can be suffixed by either ``-real`` or ``-virtual`` to specify
diff --git a/Help/prop_tgt/CUDA_EXTENSIONS.rst b/Help/prop_tgt/CUDA_EXTENSIONS.rst
index 098ca3c..2ddba0b 100644
--- a/Help/prop_tgt/CUDA_EXTENSIONS.rst
+++ b/Help/prop_tgt/CUDA_EXTENSIONS.rst
@@ -1,6 +1,8 @@
 CUDA_EXTENSIONS
 ---------------
 
+.. versionadded:: 3.8
+
 Boolean specifying whether compiler specific extensions are requested.
 
 This property specifies whether compiler specific extensions should be
diff --git a/Help/prop_tgt/CUDA_PTX_COMPILATION.rst b/Help/prop_tgt/CUDA_PTX_COMPILATION.rst
index 0ee372b..4e90afe 100644
--- a/Help/prop_tgt/CUDA_PTX_COMPILATION.rst
+++ b/Help/prop_tgt/CUDA_PTX_COMPILATION.rst
@@ -1,6 +1,8 @@
 CUDA_PTX_COMPILATION
 --------------------
 
+.. versionadded:: 3.9
+
 Compile CUDA sources to ``.ptx`` files instead of ``.obj`` files
 within :ref:`Object Libraries`.
 
diff --git a/Help/prop_tgt/CUDA_RESOLVE_DEVICE_SYMBOLS.rst b/Help/prop_tgt/CUDA_RESOLVE_DEVICE_SYMBOLS.rst
index dae960f..819ce3e 100644
--- a/Help/prop_tgt/CUDA_RESOLVE_DEVICE_SYMBOLS.rst
+++ b/Help/prop_tgt/CUDA_RESOLVE_DEVICE_SYMBOLS.rst
@@ -1,6 +1,8 @@
 CUDA_RESOLVE_DEVICE_SYMBOLS
 ---------------------------
 
+.. versionadded:: 3.9
+
 CUDA only: Enables device linking for the specific library target where
 required.
 
diff --git a/Help/prop_tgt/CUDA_RUNTIME_LIBRARY.rst b/Help/prop_tgt/CUDA_RUNTIME_LIBRARY.rst
index 11b344c..e937fc6 100644
--- a/Help/prop_tgt/CUDA_RUNTIME_LIBRARY.rst
+++ b/Help/prop_tgt/CUDA_RUNTIME_LIBRARY.rst
@@ -1,6 +1,8 @@
 CUDA_RUNTIME_LIBRARY
 --------------------
 
+.. versionadded:: 3.17
+
 Select the CUDA runtime library for use by compilers targeting the CUDA language.
 
 The allowed case insensitive values are:
diff --git a/Help/prop_tgt/CUDA_SEPARABLE_COMPILATION.rst b/Help/prop_tgt/CUDA_SEPARABLE_COMPILATION.rst
index d306d7f..32222f9 100644
--- a/Help/prop_tgt/CUDA_SEPARABLE_COMPILATION.rst
+++ b/Help/prop_tgt/CUDA_SEPARABLE_COMPILATION.rst
@@ -1,6 +1,8 @@
 CUDA_SEPARABLE_COMPILATION
 --------------------------
 
+.. versionadded:: 3.8
+
 CUDA only: Enables separate compilation of device code
 
 If set this will enable separable compilation for all CUDA files for
diff --git a/Help/prop_tgt/CUDA_STANDARD.rst b/Help/prop_tgt/CUDA_STANDARD.rst
index 6d6774e..fcc4725 100644
--- a/Help/prop_tgt/CUDA_STANDARD.rst
+++ b/Help/prop_tgt/CUDA_STANDARD.rst
@@ -1,6 +1,8 @@
 CUDA_STANDARD
 -------------
 
+.. versionadded:: 3.8
+
 The CUDA/C++ standard whose features are requested to build this target.
 
 This property specifies the CUDA/C++ standard whose features are requested
diff --git a/Help/prop_tgt/CUDA_STANDARD_REQUIRED.rst b/Help/prop_tgt/CUDA_STANDARD_REQUIRED.rst
index b2d5b28..c9301b5 100644
--- a/Help/prop_tgt/CUDA_STANDARD_REQUIRED.rst
+++ b/Help/prop_tgt/CUDA_STANDARD_REQUIRED.rst
@@ -1,6 +1,8 @@
 CUDA_STANDARD_REQUIRED
 ----------------------
 
+.. versionadded:: 3.8
+
 Boolean describing whether the value of :prop_tgt:`CUDA_STANDARD` is a requirement.
 
 If this property is set to ``ON``, then the value of the
@@ -8,7 +10,7 @@
 property is ``OFF`` or unset, the :prop_tgt:`CUDA_STANDARD` target property is
 treated as optional and may "decay" to a previous standard if the requested is
 not available.  For compilers that have no notion of a standard level, such as
-MSVC, this has no effect.
+MSVC 1800 (Visual Studio 2013) and lower, this has no effect.
 
 See the :manual:`cmake-compile-features(7)` manual for information on
 compile features and a list of supported compilers.
diff --git a/Help/prop_tgt/CXX_EXTENSIONS.rst b/Help/prop_tgt/CXX_EXTENSIONS.rst
index 280bb3a..bda531e 100644
--- a/Help/prop_tgt/CXX_EXTENSIONS.rst
+++ b/Help/prop_tgt/CXX_EXTENSIONS.rst
@@ -1,6 +1,8 @@
 CXX_EXTENSIONS
 --------------
 
+.. versionadded:: 3.1
+
 Boolean specifying whether compiler specific extensions are requested.
 
 This property specifies whether compiler specific extensions should be
diff --git a/Help/prop_tgt/CXX_STANDARD.rst b/Help/prop_tgt/CXX_STANDARD.rst
index ccc0147..f322ffe 100644
--- a/Help/prop_tgt/CXX_STANDARD.rst
+++ b/Help/prop_tgt/CXX_STANDARD.rst
@@ -1,6 +1,8 @@
 CXX_STANDARD
 ------------
 
+.. versionadded:: 3.1
+
 The C++ standard whose features are requested to build this target.
 
 This property specifies the C++ standard whose features are requested
diff --git a/Help/prop_tgt/CXX_STANDARD_REQUIRED.rst b/Help/prop_tgt/CXX_STANDARD_REQUIRED.rst
index 697d7f6..8b17490 100644
--- a/Help/prop_tgt/CXX_STANDARD_REQUIRED.rst
+++ b/Help/prop_tgt/CXX_STANDARD_REQUIRED.rst
@@ -1,6 +1,8 @@
 CXX_STANDARD_REQUIRED
 ---------------------
 
+.. versionadded:: 3.1
+
 Boolean describing whether the value of :prop_tgt:`CXX_STANDARD` is a requirement.
 
 If this property is set to ``ON``, then the value of the
@@ -8,7 +10,7 @@
 property is ``OFF`` or unset, the :prop_tgt:`CXX_STANDARD` target property is
 treated as optional and may "decay" to a previous standard if the requested is
 not available.  For compilers that have no notion of a standard level, such as
-MSVC, this has no effect.
+MSVC 1800 (Visual Studio 2013) and lower, this has no effect.
 
 See the :manual:`cmake-compile-features(7)` manual for information on
 compile features and a list of supported compilers.
diff --git a/Help/prop_tgt/C_EXTENSIONS.rst b/Help/prop_tgt/C_EXTENSIONS.rst
index 05b14ce..b2abb46 100644
--- a/Help/prop_tgt/C_EXTENSIONS.rst
+++ b/Help/prop_tgt/C_EXTENSIONS.rst
@@ -1,6 +1,8 @@
 C_EXTENSIONS
 ------------
 
+.. versionadded:: 3.1
+
 Boolean specifying whether compiler specific extensions are requested.
 
 This property specifies whether compiler specific extensions should be
diff --git a/Help/prop_tgt/C_STANDARD.rst b/Help/prop_tgt/C_STANDARD.rst
index 6a05139..999a9e7 100644
--- a/Help/prop_tgt/C_STANDARD.rst
+++ b/Help/prop_tgt/C_STANDARD.rst
@@ -1,6 +1,8 @@
 C_STANDARD
 ----------
 
+.. versionadded:: 3.1
+
 The C standard whose features are requested to build this target.
 
 This property specifies the C standard whose features are requested
diff --git a/Help/prop_tgt/C_STANDARD_REQUIRED.rst b/Help/prop_tgt/C_STANDARD_REQUIRED.rst
index acfad98..55bff04 100644
--- a/Help/prop_tgt/C_STANDARD_REQUIRED.rst
+++ b/Help/prop_tgt/C_STANDARD_REQUIRED.rst
@@ -1,6 +1,8 @@
 C_STANDARD_REQUIRED
 -------------------
 
+.. versionadded:: 3.1
+
 Boolean describing whether the value of :prop_tgt:`C_STANDARD` is a requirement.
 
 If this property is set to ``ON``, then the value of the
@@ -8,7 +10,7 @@
 property is ``OFF`` or unset, the :prop_tgt:`C_STANDARD` target property is
 treated as optional and may "decay" to a previous standard if the requested is
 not available.  For compilers that have no notion of a standard level, such as
-MSVC, this has no effect.
+MSVC 1800 (Visual Studio 2013) and lower, this has no effect.
 
 See the :manual:`cmake-compile-features(7)` manual for information on
 compile features and a list of supported compilers.
diff --git a/Help/prop_tgt/DEBUG_POSTFIX.rst b/Help/prop_tgt/DEBUG_POSTFIX.rst
index 04e312e..eca7cb0 100644
--- a/Help/prop_tgt/DEBUG_POSTFIX.rst
+++ b/Help/prop_tgt/DEBUG_POSTFIX.rst
@@ -1,7 +1,7 @@
 DEBUG_POSTFIX
 -------------
 
-See target property ``<CONFIG>_POSTFIX``.
+See target property :prop_tgt:`<CONFIG>_POSTFIX`.
 
-This property is a special case of the more-general ``<CONFIG>_POSTFIX``
+This property is a special case of the more-general :prop_tgt:`<CONFIG>_POSTFIX`
 property for the ``DEBUG`` configuration.
diff --git a/Help/prop_tgt/DEPLOYMENT_ADDITIONAL_FILES.rst b/Help/prop_tgt/DEPLOYMENT_ADDITIONAL_FILES.rst
index 5e9c191..f11fe7c 100644
--- a/Help/prop_tgt/DEPLOYMENT_ADDITIONAL_FILES.rst
+++ b/Help/prop_tgt/DEPLOYMENT_ADDITIONAL_FILES.rst
@@ -1,6 +1,8 @@
 DEPLOYMENT_ADDITIONAL_FILES
 ---------------------------
 
+.. versionadded:: 3.13
+
 Set the WinCE project ``AdditionalFiles`` in ``DeploymentTool`` in ``.vcproj``
 files generated by the :generator:`Visual Studio 9 2008` generator.
 This is useful when you want to debug on remote WinCE device.
diff --git a/Help/prop_tgt/DEPLOYMENT_REMOTE_DIRECTORY.rst b/Help/prop_tgt/DEPLOYMENT_REMOTE_DIRECTORY.rst
index 368768a..0680238 100644
--- a/Help/prop_tgt/DEPLOYMENT_REMOTE_DIRECTORY.rst
+++ b/Help/prop_tgt/DEPLOYMENT_REMOTE_DIRECTORY.rst
@@ -1,6 +1,8 @@
 DEPLOYMENT_REMOTE_DIRECTORY
 ---------------------------
 
+.. versionadded:: 3.6
+
 Set the WinCE project ``RemoteDirectory`` in ``DeploymentTool`` and
 ``RemoteExecutable`` in ``DebuggerTool`` in ``.vcproj`` files generated
 by the :generator:`Visual Studio 9 2008` generator.
diff --git a/Help/prop_tgt/DEPRECATION.rst b/Help/prop_tgt/DEPRECATION.rst
index fef2e2e..45ca848 100644
--- a/Help/prop_tgt/DEPRECATION.rst
+++ b/Help/prop_tgt/DEPRECATION.rst
@@ -1,6 +1,8 @@
 DEPRECATION
 -----------
 
+.. versionadded:: 3.17
+
 Deprecation message from imported target's developer.
 
 ``DEPRECATION`` is the message regarding a deprecation status to be displayed
diff --git a/Help/prop_tgt/DISABLE_PRECOMPILE_HEADERS.rst b/Help/prop_tgt/DISABLE_PRECOMPILE_HEADERS.rst
index 4cef023..7b3826b 100644
--- a/Help/prop_tgt/DISABLE_PRECOMPILE_HEADERS.rst
+++ b/Help/prop_tgt/DISABLE_PRECOMPILE_HEADERS.rst
@@ -1,6 +1,8 @@
 DISABLE_PRECOMPILE_HEADERS
 --------------------------
 
+.. versionadded:: 3.16
+
 Disables the precompilation of header files specified by
 :prop_tgt:`PRECOMPILE_HEADERS` property.
 
diff --git a/Help/prop_tgt/DOTNET_TARGET_FRAMEWORK.rst b/Help/prop_tgt/DOTNET_TARGET_FRAMEWORK.rst
index 8698eb6..3ba4e25 100644
--- a/Help/prop_tgt/DOTNET_TARGET_FRAMEWORK.rst
+++ b/Help/prop_tgt/DOTNET_TARGET_FRAMEWORK.rst
@@ -1,6 +1,8 @@
 DOTNET_TARGET_FRAMEWORK
 -----------------------
 
+.. versionadded:: 3.17
+
 Specify the .NET target framework.
 
 Used to specify the .NET target framework for C++/CLI and C#.  For
diff --git a/Help/prop_tgt/DOTNET_TARGET_FRAMEWORK_VERSION.rst b/Help/prop_tgt/DOTNET_TARGET_FRAMEWORK_VERSION.rst
index b33f4fb..fbd1aab 100644
--- a/Help/prop_tgt/DOTNET_TARGET_FRAMEWORK_VERSION.rst
+++ b/Help/prop_tgt/DOTNET_TARGET_FRAMEWORK_VERSION.rst
@@ -1,6 +1,8 @@
 DOTNET_TARGET_FRAMEWORK_VERSION
 -------------------------------
 
+.. versionadded:: 3.12
+
 Specify the .NET target framework version.
 
 Used to specify the .NET target framework version for C++/CLI and C#.
diff --git a/Help/prop_tgt/EXCLUDE_FROM_ALL.rst b/Help/prop_tgt/EXCLUDE_FROM_ALL.rst
index c9ece22..f0200f3 100644
--- a/Help/prop_tgt/EXCLUDE_FROM_ALL.rst
+++ b/Help/prop_tgt/EXCLUDE_FROM_ALL.rst
@@ -19,3 +19,10 @@
 in an :command:`install(TARGETS)` command, but the user is responsible for
 ensuring that the target's build artifacts are not missing or outdated when
 an install is performed.
+
+This property may use "generator expressions" with the syntax ``$<...>``. See
+the :manual:`cmake-generator-expressions(7)` manual for available expressions.
+
+Only the "Ninja Multi-Config" generator supports a property value that varies by
+configuration.  For all other generators the value of this property must be the
+same for all configurations.
diff --git a/Help/prop_tgt/EXPORT_PROPERTIES.rst b/Help/prop_tgt/EXPORT_PROPERTIES.rst
index bcf47a6..2d54f8b 100644
--- a/Help/prop_tgt/EXPORT_PROPERTIES.rst
+++ b/Help/prop_tgt/EXPORT_PROPERTIES.rst
@@ -1,6 +1,8 @@
 EXPORT_PROPERTIES
 -----------------
 
+.. versionadded:: 3.12
+
 List additional properties to export for a target.
 
 This property contains a list of property names that should be exported by
@@ -12,3 +14,11 @@
 they are reserved for internal CMake use.
 
 Properties containing generator expressions are also not allowed.
+
+.. note::
+
+  Since CMake 3.19, :ref:`Interface Libraries` may have arbitrary
+  target properties.  If a project exports an interface library
+  with custom properties, the resulting package may not work with
+  dependents configured by older versions of CMake that reject the
+  custom properties.
diff --git a/Help/prop_tgt/FRAMEWORK_MULTI_CONFIG_POSTFIX_CONFIG.rst b/Help/prop_tgt/FRAMEWORK_MULTI_CONFIG_POSTFIX_CONFIG.rst
index 243c0cd..84d0c1e 100644
--- a/Help/prop_tgt/FRAMEWORK_MULTI_CONFIG_POSTFIX_CONFIG.rst
+++ b/Help/prop_tgt/FRAMEWORK_MULTI_CONFIG_POSTFIX_CONFIG.rst
@@ -1,6 +1,8 @@
 FRAMEWORK_MULTI_CONFIG_POSTFIX_<CONFIG>
 ---------------------------------------
 
+.. versionadded:: 3.18
+
 Postfix to append to the framework file name for configuration ``<CONFIG>``,
 when using a multi-config generator (like Xcode and Ninja Multi-Config).
 
diff --git a/Help/prop_tgt/FRAMEWORK_VERSION.rst b/Help/prop_tgt/FRAMEWORK_VERSION.rst
index c2ae7b9..38b8137 100644
--- a/Help/prop_tgt/FRAMEWORK_VERSION.rst
+++ b/Help/prop_tgt/FRAMEWORK_VERSION.rst
@@ -1,6 +1,8 @@
 FRAMEWORK_VERSION
 -----------------
 
+.. versionadded:: 3.4
+
 Version of a framework created using the :prop_tgt:`FRAMEWORK` target
 property (e.g. ``A``).
 
diff --git a/Help/prop_tgt/Fortran_PREPROCESS.rst b/Help/prop_tgt/Fortran_PREPROCESS.rst
index 47a15c0..e7e2fba 100644
--- a/Help/prop_tgt/Fortran_PREPROCESS.rst
+++ b/Help/prop_tgt/Fortran_PREPROCESS.rst
@@ -1,6 +1,8 @@
 Fortran_PREPROCESS
 ------------------
 
+.. versionadded:: 3.18
+
 Control whether the Fortran source file should be unconditionally
 preprocessed.
 
diff --git a/Help/prop_tgt/GHS_INTEGRITY_APP.rst b/Help/prop_tgt/GHS_INTEGRITY_APP.rst
index b669781..cccd087 100644
--- a/Help/prop_tgt/GHS_INTEGRITY_APP.rst
+++ b/Help/prop_tgt/GHS_INTEGRITY_APP.rst
@@ -1,6 +1,8 @@
 GHS_INTEGRITY_APP
 -----------------
 
+.. versionadded:: 3.14
+
 ``ON`` / ``OFF`` boolean to determine if an executable target should
 be treated as an `Integrity Application`.
 
diff --git a/Help/prop_tgt/GHS_NO_SOURCE_GROUP_FILE.rst b/Help/prop_tgt/GHS_NO_SOURCE_GROUP_FILE.rst
index 11ce0b22..fe6b8e6 100644
--- a/Help/prop_tgt/GHS_NO_SOURCE_GROUP_FILE.rst
+++ b/Help/prop_tgt/GHS_NO_SOURCE_GROUP_FILE.rst
@@ -1,6 +1,8 @@
 GHS_NO_SOURCE_GROUP_FILE
 ------------------------
 
+.. versionadded:: 3.14
+
 ``ON`` / ``OFF`` boolean to control if the project file for a target should
 be one single file or multiple files.
 
diff --git a/Help/prop_tgt/IMPORTED_COMMON_LANGUAGE_RUNTIME.rst b/Help/prop_tgt/IMPORTED_COMMON_LANGUAGE_RUNTIME.rst
index 99e3bc4..8c20e07 100644
--- a/Help/prop_tgt/IMPORTED_COMMON_LANGUAGE_RUNTIME.rst
+++ b/Help/prop_tgt/IMPORTED_COMMON_LANGUAGE_RUNTIME.rst
@@ -1,6 +1,8 @@
 IMPORTED_COMMON_LANGUAGE_RUNTIME
 --------------------------------
 
+.. versionadded:: 3.12
+
 Property to define if the target uses ``C++/CLI``.
 
 Ignored for non-imported targets.
diff --git a/Help/prop_tgt/IMPORTED_GLOBAL.rst b/Help/prop_tgt/IMPORTED_GLOBAL.rst
index 1a9129f..176127f 100644
--- a/Help/prop_tgt/IMPORTED_GLOBAL.rst
+++ b/Help/prop_tgt/IMPORTED_GLOBAL.rst
@@ -1,6 +1,8 @@
 IMPORTED_GLOBAL
 ---------------
 
+.. versionadded:: 3.11
+
 Indication of whether an :ref:`IMPORTED target <Imported Targets>` is
 globally visible.
 
diff --git a/Help/prop_tgt/IMPORTED_LIBNAME.rst b/Help/prop_tgt/IMPORTED_LIBNAME.rst
index 1943dba..7a83906 100644
--- a/Help/prop_tgt/IMPORTED_LIBNAME.rst
+++ b/Help/prop_tgt/IMPORTED_LIBNAME.rst
@@ -1,6 +1,8 @@
 IMPORTED_LIBNAME
 ----------------
 
+.. versionadded:: 3.8
+
 Specify the link library name for an :ref:`imported <Imported Targets>`
 :ref:`Interface Library <Interface Libraries>`.
 
diff --git a/Help/prop_tgt/IMPORTED_LIBNAME_CONFIG.rst b/Help/prop_tgt/IMPORTED_LIBNAME_CONFIG.rst
index a28b838..df64769 100644
--- a/Help/prop_tgt/IMPORTED_LIBNAME_CONFIG.rst
+++ b/Help/prop_tgt/IMPORTED_LIBNAME_CONFIG.rst
@@ -1,6 +1,8 @@
 IMPORTED_LIBNAME_<CONFIG>
 -------------------------
 
+.. versionadded:: 3.8
+
 <CONFIG>-specific version of :prop_tgt:`IMPORTED_LIBNAME` property.
 
 Configuration names correspond to those provided by the project from
diff --git a/Help/prop_tgt/IMPORTED_OBJECTS.rst b/Help/prop_tgt/IMPORTED_OBJECTS.rst
index 50a329f..bbbcd86 100644
--- a/Help/prop_tgt/IMPORTED_OBJECTS.rst
+++ b/Help/prop_tgt/IMPORTED_OBJECTS.rst
@@ -1,6 +1,8 @@
 IMPORTED_OBJECTS
 ----------------
 
+.. versionadded:: 3.9
+
 A :ref:`semicolon-separated list <CMake Language Lists>` of absolute paths to the object
 files on disk for an :ref:`imported <Imported targets>`
 :ref:`object library <object libraries>`.
diff --git a/Help/prop_tgt/IMPORTED_OBJECTS_CONFIG.rst b/Help/prop_tgt/IMPORTED_OBJECTS_CONFIG.rst
index 4419ed1..b12ca38 100644
--- a/Help/prop_tgt/IMPORTED_OBJECTS_CONFIG.rst
+++ b/Help/prop_tgt/IMPORTED_OBJECTS_CONFIG.rst
@@ -1,6 +1,8 @@
 IMPORTED_OBJECTS_<CONFIG>
 -------------------------
 
+.. versionadded:: 3.9
+
 <CONFIG>-specific version of :prop_tgt:`IMPORTED_OBJECTS` property.
 
 Configuration names correspond to those provided by the project from
diff --git a/Help/prop_tgt/INSTALL_REMOVE_ENVIRONMENT_RPATH.rst b/Help/prop_tgt/INSTALL_REMOVE_ENVIRONMENT_RPATH.rst
index 72dcaa0..f41e41c 100644
--- a/Help/prop_tgt/INSTALL_REMOVE_ENVIRONMENT_RPATH.rst
+++ b/Help/prop_tgt/INSTALL_REMOVE_ENVIRONMENT_RPATH.rst
@@ -1,6 +1,8 @@
 INSTALL_REMOVE_ENVIRONMENT_RPATH
 --------------------------------
 
+.. versionadded:: 3.16
+
 Controls whether toolchain-defined rpaths should be removed during installation.
 
 When a target is being installed, CMake may need to rewrite its rpath
diff --git a/Help/prop_tgt/INTERFACE_COMPILE_FEATURES.rst b/Help/prop_tgt/INTERFACE_COMPILE_FEATURES.rst
index 31b594f..0db3b0c 100644
--- a/Help/prop_tgt/INTERFACE_COMPILE_FEATURES.rst
+++ b/Help/prop_tgt/INTERFACE_COMPILE_FEATURES.rst
@@ -1,6 +1,8 @@
 INTERFACE_COMPILE_FEATURES
 --------------------------
 
+.. versionadded:: 3.1
+
 .. |property_name| replace:: compile features
 .. |command_name| replace:: :command:`target_compile_features`
 .. |PROPERTY_INTERFACE_NAME| replace:: ``INTERFACE_COMPILE_FEATURES``
diff --git a/Help/prop_tgt/INTERFACE_LINK_DEPENDS.rst b/Help/prop_tgt/INTERFACE_LINK_DEPENDS.rst
index 790554d..9c8275d 100644
--- a/Help/prop_tgt/INTERFACE_LINK_DEPENDS.rst
+++ b/Help/prop_tgt/INTERFACE_LINK_DEPENDS.rst
@@ -1,6 +1,8 @@
 INTERFACE_LINK_DEPENDS
 ----------------------
 
+.. versionadded:: 3.13
+
 Additional public interface files on which a target binary depends for linking.
 
 This property is supported only by :generator:`Ninja` and
diff --git a/Help/prop_tgt/INTERFACE_LINK_DIRECTORIES.rst b/Help/prop_tgt/INTERFACE_LINK_DIRECTORIES.rst
index 56a4ec0..de1dabb 100644
--- a/Help/prop_tgt/INTERFACE_LINK_DIRECTORIES.rst
+++ b/Help/prop_tgt/INTERFACE_LINK_DIRECTORIES.rst
@@ -1,6 +1,8 @@
 INTERFACE_LINK_DIRECTORIES
 --------------------------
 
+.. versionadded:: 3.13
+
 .. |property_name| replace:: link directories
 .. |command_name| replace:: :command:`target_link_directories`
 .. |PROPERTY_INTERFACE_NAME| replace:: ``INTERFACE_LINK_DIRECTORIES``
diff --git a/Help/prop_tgt/INTERFACE_LINK_OPTIONS.rst b/Help/prop_tgt/INTERFACE_LINK_OPTIONS.rst
index c293b98..4245fe9 100644
--- a/Help/prop_tgt/INTERFACE_LINK_OPTIONS.rst
+++ b/Help/prop_tgt/INTERFACE_LINK_OPTIONS.rst
@@ -1,6 +1,8 @@
 INTERFACE_LINK_OPTIONS
 ----------------------
 
+.. versionadded:: 3.13
+
 .. |property_name| replace:: link options
 .. |command_name| replace:: :command:`target_link_options`
 .. |PROPERTY_INTERFACE_NAME| replace:: ``INTERFACE_LINK_OPTIONS``
diff --git a/Help/prop_tgt/INTERFACE_PRECOMPILE_HEADERS.rst b/Help/prop_tgt/INTERFACE_PRECOMPILE_HEADERS.rst
index e285407..2299264 100644
--- a/Help/prop_tgt/INTERFACE_PRECOMPILE_HEADERS.rst
+++ b/Help/prop_tgt/INTERFACE_PRECOMPILE_HEADERS.rst
@@ -1,6 +1,8 @@
 INTERFACE_PRECOMPILE_HEADERS
 ----------------------------
 
+.. versionadded:: 3.16
+
 List of interface header files to precompile into consuming targets.
 
 Targets may populate this property to publish the header files
diff --git a/Help/prop_tgt/INTERFACE_SOURCES.rst b/Help/prop_tgt/INTERFACE_SOURCES.rst
index a224b68..759c482 100644
--- a/Help/prop_tgt/INTERFACE_SOURCES.rst
+++ b/Help/prop_tgt/INTERFACE_SOURCES.rst
@@ -1,6 +1,8 @@
 INTERFACE_SOURCES
 -----------------
 
+.. versionadded:: 3.1
+
 List of interface sources to compile into consuming targets.
 
 Targets may populate this property to publish the sources
diff --git a/Help/prop_tgt/IOS_INSTALL_COMBINED.rst b/Help/prop_tgt/IOS_INSTALL_COMBINED.rst
index 59f67a7..23a86e6 100644
--- a/Help/prop_tgt/IOS_INSTALL_COMBINED.rst
+++ b/Help/prop_tgt/IOS_INSTALL_COMBINED.rst
@@ -1,6 +1,8 @@
 IOS_INSTALL_COMBINED
 --------------------
 
+.. versionadded:: 3.5
+
 Build a combined (device and simulator) target when installing.
 
 When this property is set to set to false (which is the default) then it will
diff --git a/Help/prop_tgt/JOB_POOL_PRECOMPILE_HEADER.rst b/Help/prop_tgt/JOB_POOL_PRECOMPILE_HEADER.rst
index ece28a4..42cace0 100644
--- a/Help/prop_tgt/JOB_POOL_PRECOMPILE_HEADER.rst
+++ b/Help/prop_tgt/JOB_POOL_PRECOMPILE_HEADER.rst
@@ -1,6 +1,8 @@
 JOB_POOL_PRECOMPILE_HEADER
 --------------------------
 
+.. versionadded:: 3.17
+
 Ninja only: Pool used for generating pre-compiled headers.
 
 The number of parallel compile processes could be limited by defining
diff --git a/Help/prop_tgt/LANG_CLANG_TIDY.rst b/Help/prop_tgt/LANG_CLANG_TIDY.rst
index 2bfef66..7fc2372 100644
--- a/Help/prop_tgt/LANG_CLANG_TIDY.rst
+++ b/Help/prop_tgt/LANG_CLANG_TIDY.rst
@@ -1,6 +1,8 @@
 <LANG>_CLANG_TIDY
 -----------------
 
+.. versionadded:: 3.6
+
 This property is implemented only when ``<LANG>`` is ``C`` or ``CXX``.
 
 Specify a :ref:`semicolon-separated list <CMake Language Lists>` containing a command
diff --git a/Help/prop_tgt/LANG_COMPILER_LAUNCHER.rst b/Help/prop_tgt/LANG_COMPILER_LAUNCHER.rst
index a6f2b24..77ae1f6 100644
--- a/Help/prop_tgt/LANG_COMPILER_LAUNCHER.rst
+++ b/Help/prop_tgt/LANG_COMPILER_LAUNCHER.rst
@@ -1,6 +1,8 @@
 <LANG>_COMPILER_LAUNCHER
 ------------------------
 
+.. versionadded:: 3.4
+
 This property is implemented only when ``<LANG>`` is ``C``, ``CXX``,
 ``Fortran``, ``OBJC``, ``OBJCXX``, or ``CUDA``.
 
diff --git a/Help/prop_tgt/LANG_CPPCHECK.rst b/Help/prop_tgt/LANG_CPPCHECK.rst
index 60785d0..80acbc0 100644
--- a/Help/prop_tgt/LANG_CPPCHECK.rst
+++ b/Help/prop_tgt/LANG_CPPCHECK.rst
@@ -1,6 +1,8 @@
 <LANG>_CPPCHECK
 ---------------
 
+.. versionadded:: 3.10
+
 This property is supported only when ``<LANG>`` is ``C`` or ``CXX``.
 
 Specify a :ref:`semicolon-separated list <CMake Language Lists>` containing a command line
diff --git a/Help/prop_tgt/LANG_CPPLINT.rst b/Help/prop_tgt/LANG_CPPLINT.rst
index 9944c88..be6db46 100644
--- a/Help/prop_tgt/LANG_CPPLINT.rst
+++ b/Help/prop_tgt/LANG_CPPLINT.rst
@@ -1,6 +1,8 @@
 <LANG>_CPPLINT
 --------------
 
+.. versionadded:: 3.8
+
 This property is supported only when ``<LANG>`` is ``C`` or ``CXX``.
 
 Specify a :ref:`semicolon-separated list <CMake Language Lists>` containing a command line
diff --git a/Help/prop_tgt/LANG_INCLUDE_WHAT_YOU_USE.rst b/Help/prop_tgt/LANG_INCLUDE_WHAT_YOU_USE.rst
index 35220e4..eebef56 100644
--- a/Help/prop_tgt/LANG_INCLUDE_WHAT_YOU_USE.rst
+++ b/Help/prop_tgt/LANG_INCLUDE_WHAT_YOU_USE.rst
@@ -1,6 +1,8 @@
 <LANG>_INCLUDE_WHAT_YOU_USE
 ---------------------------
 
+.. versionadded:: 3.3
+
 This property is implemented only when ``<LANG>`` is ``C`` or ``CXX``.
 
 Specify a :ref:`semicolon-separated list <CMake Language Lists>` containing a command
diff --git a/Help/prop_tgt/LINK_DIRECTORIES.rst b/Help/prop_tgt/LINK_DIRECTORIES.rst
index c2905b3..67be494 100644
--- a/Help/prop_tgt/LINK_DIRECTORIES.rst
+++ b/Help/prop_tgt/LINK_DIRECTORIES.rst
@@ -1,6 +1,8 @@
 LINK_DIRECTORIES
 ----------------
 
+.. versionadded:: 3.13
+
 List of directories to use for the link step of shared library, module
 and executable targets.
 
diff --git a/Help/prop_tgt/LINK_OPTIONS.rst b/Help/prop_tgt/LINK_OPTIONS.rst
index ff3ee87..8c0dfc4 100644
--- a/Help/prop_tgt/LINK_OPTIONS.rst
+++ b/Help/prop_tgt/LINK_OPTIONS.rst
@@ -1,6 +1,8 @@
 LINK_OPTIONS
 ------------
 
+.. versionadded:: 3.13
+
 List of options to use for the link step of shared library, module
 and executable targets as well as the device link step. Targets that are static
 libraries need to use the :prop_tgt:`STATIC_LIBRARY_OPTIONS` target property.
diff --git a/Help/prop_tgt/LINK_WHAT_YOU_USE.rst b/Help/prop_tgt/LINK_WHAT_YOU_USE.rst
index 32d6edb..2ed93ad 100644
--- a/Help/prop_tgt/LINK_WHAT_YOU_USE.rst
+++ b/Help/prop_tgt/LINK_WHAT_YOU_USE.rst
@@ -1,6 +1,8 @@
 LINK_WHAT_YOU_USE
 ---------------------------
 
+.. versionadded:: 3.7
+
 This is a boolean option that when set to ``TRUE`` will automatically run
 ``ldd -r -u`` on the target after it is linked. In addition, the linker flag
 ``-Wl,--no-as-needed`` will be passed to the target with the link command so
diff --git a/Help/prop_tgt/MACHO_COMPATIBILITY_VERSION.rst b/Help/prop_tgt/MACHO_COMPATIBILITY_VERSION.rst
index 26d5cc8..a24b255 100644
--- a/Help/prop_tgt/MACHO_COMPATIBILITY_VERSION.rst
+++ b/Help/prop_tgt/MACHO_COMPATIBILITY_VERSION.rst
@@ -1,6 +1,8 @@
 MACHO_COMPATIBILITY_VERSION
 ---------------------------
 
+.. versionadded:: 3.17
+
 What compatibility version number is this target for Mach-O binaries.
 
 For shared libraries on Mach-O systems (e.g. macOS, iOS)
diff --git a/Help/prop_tgt/MACHO_CURRENT_VERSION.rst b/Help/prop_tgt/MACHO_CURRENT_VERSION.rst
index 9afb356..530f79b 100644
--- a/Help/prop_tgt/MACHO_CURRENT_VERSION.rst
+++ b/Help/prop_tgt/MACHO_CURRENT_VERSION.rst
@@ -1,6 +1,8 @@
 MACHO_CURRENT_VERSION
 ---------------------
 
+.. versionadded:: 3.17
+
 What current version number is this target for Mach-O binaries.
 
 For shared libraries on Mach-O systems (e.g. macOS, iOS)
diff --git a/Help/prop_tgt/MANUALLY_ADDED_DEPENDENCIES.rst b/Help/prop_tgt/MANUALLY_ADDED_DEPENDENCIES.rst
index c12ea14..72871b3 100644
--- a/Help/prop_tgt/MANUALLY_ADDED_DEPENDENCIES.rst
+++ b/Help/prop_tgt/MANUALLY_ADDED_DEPENDENCIES.rst
@@ -1,6 +1,8 @@
 MANUALLY_ADDED_DEPENDENCIES
 ---------------------------
 
+.. versionadded:: 3.8
+
 Get manually added dependencies to other top-level targets.
 
 This read-only property can be used to query all dependencies that
diff --git a/Help/prop_tgt/MSVC_RUNTIME_LIBRARY.rst b/Help/prop_tgt/MSVC_RUNTIME_LIBRARY.rst
index 73792de..9b978b2 100644
--- a/Help/prop_tgt/MSVC_RUNTIME_LIBRARY.rst
+++ b/Help/prop_tgt/MSVC_RUNTIME_LIBRARY.rst
@@ -1,6 +1,8 @@
 MSVC_RUNTIME_LIBRARY
 --------------------
 
+.. versionadded:: 3.15
+
 Select the MSVC runtime library for use by compilers targeting the MSVC ABI.
 
 The allowed values are:
diff --git a/Help/prop_tgt/OBJCXX_EXTENSIONS.rst b/Help/prop_tgt/OBJCXX_EXTENSIONS.rst
index 9f9d804..8a254f2 100644
--- a/Help/prop_tgt/OBJCXX_EXTENSIONS.rst
+++ b/Help/prop_tgt/OBJCXX_EXTENSIONS.rst
@@ -1,6 +1,8 @@
 OBJCXX_EXTENSIONS
 -----------------
 
+.. versionadded:: 3.16
+
 Boolean specifying whether compiler specific extensions are requested.
 
 This property specifies whether compiler specific extensions should be
diff --git a/Help/prop_tgt/OBJCXX_STANDARD.rst b/Help/prop_tgt/OBJCXX_STANDARD.rst
index 3c925dc..1067153 100644
--- a/Help/prop_tgt/OBJCXX_STANDARD.rst
+++ b/Help/prop_tgt/OBJCXX_STANDARD.rst
@@ -1,6 +1,8 @@
 OBJCXX_STANDARD
 ---------------
 
+.. versionadded:: 3.16
+
 The ObjC++ standard whose features are requested to build this target.
 
 This property specifies the ObjC++ standard whose features are requested
diff --git a/Help/prop_tgt/OBJCXX_STANDARD_REQUIRED.rst b/Help/prop_tgt/OBJCXX_STANDARD_REQUIRED.rst
index c330abf..3cee740 100644
--- a/Help/prop_tgt/OBJCXX_STANDARD_REQUIRED.rst
+++ b/Help/prop_tgt/OBJCXX_STANDARD_REQUIRED.rst
@@ -1,6 +1,8 @@
 OBJCXX_STANDARD_REQUIRED
 ------------------------
 
+.. versionadded:: 3.16
+
 Boolean describing whether the value of :prop_tgt:`OBJCXX_STANDARD` is a requirement.
 
 If this property is set to ``ON``, then the value of the
diff --git a/Help/prop_tgt/OBJC_EXTENSIONS.rst b/Help/prop_tgt/OBJC_EXTENSIONS.rst
index 2de9e48..ef1c754 100644
--- a/Help/prop_tgt/OBJC_EXTENSIONS.rst
+++ b/Help/prop_tgt/OBJC_EXTENSIONS.rst
@@ -1,6 +1,8 @@
 OBJC_EXTENSIONS
 ---------------
 
+.. versionadded:: 3.16
+
 Boolean specifying whether compiler specific extensions are requested.
 
 This property specifies whether compiler specific extensions should be
diff --git a/Help/prop_tgt/OBJC_STANDARD.rst b/Help/prop_tgt/OBJC_STANDARD.rst
index d1e1b24..2143ff9 100644
--- a/Help/prop_tgt/OBJC_STANDARD.rst
+++ b/Help/prop_tgt/OBJC_STANDARD.rst
@@ -1,6 +1,8 @@
 OBJC_STANDARD
 -------------
 
+.. versionadded:: 3.16
+
 The OBJC standard whose features are requested to build this target.
 
 This property specifies the OBJC standard whose features are requested
diff --git a/Help/prop_tgt/OBJC_STANDARD_REQUIRED.rst b/Help/prop_tgt/OBJC_STANDARD_REQUIRED.rst
index 8cf377c..11547c8 100644
--- a/Help/prop_tgt/OBJC_STANDARD_REQUIRED.rst
+++ b/Help/prop_tgt/OBJC_STANDARD_REQUIRED.rst
@@ -1,6 +1,8 @@
 OBJC_STANDARD_REQUIRED
 ----------------------
 
+.. versionadded:: 3.16
+
 Boolean describing whether the value of :prop_tgt:`OBJC_STANDARD` is a requirement.
 
 If this property is set to ``ON``, then the value of the
diff --git a/Help/prop_tgt/PCH_WARN_INVALID.rst b/Help/prop_tgt/PCH_WARN_INVALID.rst
index 96e1abd..2d5ec55 100644
--- a/Help/prop_tgt/PCH_WARN_INVALID.rst
+++ b/Help/prop_tgt/PCH_WARN_INVALID.rst
@@ -1,6 +1,8 @@
 PCH_WARN_INVALID
 ----------------
 
+.. versionadded:: 3.18
+
 When this property is set to true, the precompile header compiler options
 will contain a compiler flag which should warn about invalid precompiled
 headers e.g. ``-Winvalid-pch`` for GNU compiler.
diff --git a/Help/prop_tgt/PRECOMPILE_HEADERS.rst b/Help/prop_tgt/PRECOMPILE_HEADERS.rst
index 9e70b65..af27947 100644
--- a/Help/prop_tgt/PRECOMPILE_HEADERS.rst
+++ b/Help/prop_tgt/PRECOMPILE_HEADERS.rst
@@ -1,6 +1,8 @@
 PRECOMPILE_HEADERS
 ------------------
 
+.. versionadded:: 3.16
+
 List of header files to precompile.
 
 This property holds a :ref:`semicolon-separated list <CMake Language Lists>`
diff --git a/Help/prop_tgt/PRECOMPILE_HEADERS_REUSE_FROM.rst b/Help/prop_tgt/PRECOMPILE_HEADERS_REUSE_FROM.rst
index 9c3e7ea..6f5635b 100644
--- a/Help/prop_tgt/PRECOMPILE_HEADERS_REUSE_FROM.rst
+++ b/Help/prop_tgt/PRECOMPILE_HEADERS_REUSE_FROM.rst
@@ -1,6 +1,8 @@
 PRECOMPILE_HEADERS_REUSE_FROM
 -----------------------------
 
+.. versionadded:: 3.16
+
 Target from which to reuse the precompiled headers build artifact.
 
 See the second signature of :command:`target_precompile_headers` command
diff --git a/Help/prop_tgt/SOURCE_DIR.rst b/Help/prop_tgt/SOURCE_DIR.rst
index b25813b..78ce220 100644
--- a/Help/prop_tgt/SOURCE_DIR.rst
+++ b/Help/prop_tgt/SOURCE_DIR.rst
@@ -1,6 +1,8 @@
 SOURCE_DIR
 ----------
 
+.. versionadded:: 3.4
+
 This read-only property reports the value of the
 :variable:`CMAKE_CURRENT_SOURCE_DIR` variable in the directory in which
 the target was defined.
diff --git a/Help/prop_tgt/STATIC_LIBRARY_OPTIONS.rst b/Help/prop_tgt/STATIC_LIBRARY_OPTIONS.rst
index d05fda4..2f4a3ba 100644
--- a/Help/prop_tgt/STATIC_LIBRARY_OPTIONS.rst
+++ b/Help/prop_tgt/STATIC_LIBRARY_OPTIONS.rst
@@ -1,6 +1,8 @@
 STATIC_LIBRARY_OPTIONS
 ----------------------
 
+.. versionadded:: 3.13
+
 Archiver (or MSVC librarian) flags for a static library target.
 Targets that are shared libraries, modules, or executables need to use
 the :prop_tgt:`LINK_OPTIONS` target property.
diff --git a/Help/prop_tgt/Swift_DEPENDENCIES_FILE.rst b/Help/prop_tgt/Swift_DEPENDENCIES_FILE.rst
index 46c9a1d..0f944b6 100644
--- a/Help/prop_tgt/Swift_DEPENDENCIES_FILE.rst
+++ b/Help/prop_tgt/Swift_DEPENDENCIES_FILE.rst
@@ -1,5 +1,7 @@
 Swift_DEPENDENCIES_FILE
 -----------------------
 
+.. versionadded:: 3.15
+
 This property sets the path for the Swift dependency file (swiftdep) for the
 target.  If one is not specified, it will default to ``<TARGET>.swiftdeps``.
diff --git a/Help/prop_tgt/Swift_LANGUAGE_VERSION.rst b/Help/prop_tgt/Swift_LANGUAGE_VERSION.rst
index 7579447..afc6b31 100644
--- a/Help/prop_tgt/Swift_LANGUAGE_VERSION.rst
+++ b/Help/prop_tgt/Swift_LANGUAGE_VERSION.rst
@@ -1,6 +1,8 @@
 Swift_LANGUAGE_VERSION
 ----------------------
 
+.. versionadded:: 3.16
+
 This property sets the language version for the Swift sources in the target.  If
 one is not specified, it will default to ``<CMAKE_Swift_LANGUAGE_VERSION>`` if
 specified, otherwise it is the latest version supported by the compiler.
diff --git a/Help/prop_tgt/Swift_MODULE_DIRECTORY.rst b/Help/prop_tgt/Swift_MODULE_DIRECTORY.rst
index d404251..a6484f2 100644
--- a/Help/prop_tgt/Swift_MODULE_DIRECTORY.rst
+++ b/Help/prop_tgt/Swift_MODULE_DIRECTORY.rst
@@ -1,6 +1,8 @@
 Swift_MODULE_DIRECTORY
 ----------------------
 
+.. versionadded:: 3.15
+
 Specify output directory for Swift modules provided by the target.
 
 If the target contains Swift source files, this specifies the directory in which
diff --git a/Help/prop_tgt/Swift_MODULE_NAME.rst b/Help/prop_tgt/Swift_MODULE_NAME.rst
index 2866020..d941b54 100644
--- a/Help/prop_tgt/Swift_MODULE_NAME.rst
+++ b/Help/prop_tgt/Swift_MODULE_NAME.rst
@@ -1,5 +1,7 @@
 Swift_MODULE_NAME
 -----------------
 
+.. versionadded:: 3.15
+
 This property specifies the name of the Swift module.  It is defaulted to the
 name of the target.
diff --git a/Help/prop_tgt/UNITY_BUILD.rst b/Help/prop_tgt/UNITY_BUILD.rst
index e140952..04cede6 100644
--- a/Help/prop_tgt/UNITY_BUILD.rst
+++ b/Help/prop_tgt/UNITY_BUILD.rst
@@ -1,6 +1,8 @@
 UNITY_BUILD
 -----------
 
+.. versionadded:: 3.16
+
 When this property is set to true, the target source files will be combined
 into batches for faster compilation.  This is done by creating a (set of)
 unity sources which ``#include`` the original sources, then compiling these
diff --git a/Help/prop_tgt/UNITY_BUILD_BATCH_SIZE.rst b/Help/prop_tgt/UNITY_BUILD_BATCH_SIZE.rst
index 44ffe27..3886ec9 100644
--- a/Help/prop_tgt/UNITY_BUILD_BATCH_SIZE.rst
+++ b/Help/prop_tgt/UNITY_BUILD_BATCH_SIZE.rst
@@ -1,6 +1,8 @@
 UNITY_BUILD_BATCH_SIZE
 ----------------------
 
+.. versionadded:: 3.16
+
 Specifies the maximum number of source files that can be combined into any one
 unity source file when unity builds are enabled by the :prop_tgt:`UNITY_BUILD`
 target property.  The original source files will be distributed across as many
diff --git a/Help/prop_tgt/UNITY_BUILD_CODE_AFTER_INCLUDE.rst b/Help/prop_tgt/UNITY_BUILD_CODE_AFTER_INCLUDE.rst
index 7231b61..ac2b19c 100644
--- a/Help/prop_tgt/UNITY_BUILD_CODE_AFTER_INCLUDE.rst
+++ b/Help/prop_tgt/UNITY_BUILD_CODE_AFTER_INCLUDE.rst
@@ -1,6 +1,8 @@
 UNITY_BUILD_CODE_AFTER_INCLUDE
 ------------------------------
 
+.. versionadded:: 3.16
+
 Code snippet which is included verbatim by the :prop_tgt:`UNITY_BUILD`
 feature just after every ``#include`` statement in the generated unity
 source files.  For example:
diff --git a/Help/prop_tgt/UNITY_BUILD_CODE_BEFORE_INCLUDE.rst b/Help/prop_tgt/UNITY_BUILD_CODE_BEFORE_INCLUDE.rst
index 7ed6fa1..6f0d56b 100644
--- a/Help/prop_tgt/UNITY_BUILD_CODE_BEFORE_INCLUDE.rst
+++ b/Help/prop_tgt/UNITY_BUILD_CODE_BEFORE_INCLUDE.rst
@@ -1,6 +1,8 @@
 UNITY_BUILD_CODE_BEFORE_INCLUDE
 -------------------------------
 
+.. versionadded:: 3.16
+
 Code snippet which is included verbatim by the :prop_tgt:`UNITY_BUILD`
 feature just before every ``#include`` statement in the generated unity
 source files.  For example:
diff --git a/Help/prop_tgt/UNITY_BUILD_MODE.rst b/Help/prop_tgt/UNITY_BUILD_MODE.rst
index 1ebab23..003451e 100644
--- a/Help/prop_tgt/UNITY_BUILD_MODE.rst
+++ b/Help/prop_tgt/UNITY_BUILD_MODE.rst
@@ -1,6 +1,8 @@
 UNITY_BUILD_MODE
 ----------------
 
+.. versionadded:: 3.18
+
 CMake provides different algorithms for selecting which sources are grouped
 together into a *bucket*. Selection is decided by this property,
 which has the following acceptable values:
diff --git a/Help/prop_tgt/VS_CONFIGURATION_TYPE.rst b/Help/prop_tgt/VS_CONFIGURATION_TYPE.rst
index 640bed5..4adffd4 100644
--- a/Help/prop_tgt/VS_CONFIGURATION_TYPE.rst
+++ b/Help/prop_tgt/VS_CONFIGURATION_TYPE.rst
@@ -1,6 +1,8 @@
 VS_CONFIGURATION_TYPE
 ---------------------
 
+.. versionadded:: 3.6
+
 Visual Studio project configuration type.
 
 Sets the ``ConfigurationType`` attribute for a generated Visual Studio project.
diff --git a/Help/prop_tgt/VS_DEBUGGER_COMMAND.rst b/Help/prop_tgt/VS_DEBUGGER_COMMAND.rst
index ba5fd0a..58476d6 100644
--- a/Help/prop_tgt/VS_DEBUGGER_COMMAND.rst
+++ b/Help/prop_tgt/VS_DEBUGGER_COMMAND.rst
@@ -1,6 +1,8 @@
 VS_DEBUGGER_COMMAND
 -------------------
 
+.. versionadded:: 3.12
+
 Sets the local debugger command for Visual Studio C++ targets.
 The property value may use
 :manual:`generator expressions <cmake-generator-expressions(7)>`.
diff --git a/Help/prop_tgt/VS_DEBUGGER_COMMAND_ARGUMENTS.rst b/Help/prop_tgt/VS_DEBUGGER_COMMAND_ARGUMENTS.rst
index 06ef5d5..6c26601 100644
--- a/Help/prop_tgt/VS_DEBUGGER_COMMAND_ARGUMENTS.rst
+++ b/Help/prop_tgt/VS_DEBUGGER_COMMAND_ARGUMENTS.rst
@@ -1,6 +1,8 @@
 VS_DEBUGGER_COMMAND_ARGUMENTS
 -----------------------------
 
+.. versionadded:: 3.13
+
 Sets the local debugger command line arguments for Visual Studio C++ targets.
 The property value may use
 :manual:`generator expressions <cmake-generator-expressions(7)>`.
diff --git a/Help/prop_tgt/VS_DEBUGGER_ENVIRONMENT.rst b/Help/prop_tgt/VS_DEBUGGER_ENVIRONMENT.rst
index f55ac7b..2f59a82 100644
--- a/Help/prop_tgt/VS_DEBUGGER_ENVIRONMENT.rst
+++ b/Help/prop_tgt/VS_DEBUGGER_ENVIRONMENT.rst
@@ -1,6 +1,8 @@
 VS_DEBUGGER_ENVIRONMENT
 -----------------------
 
+.. versionadded:: 3.13
+
 Sets the local debugger environment for Visual Studio C++ targets.
 The property value may use
 :manual:`generator expressions <cmake-generator-expressions(7)>`.
diff --git a/Help/prop_tgt/VS_DEBUGGER_WORKING_DIRECTORY.rst b/Help/prop_tgt/VS_DEBUGGER_WORKING_DIRECTORY.rst
index 008bbf6..c163abf 100644
--- a/Help/prop_tgt/VS_DEBUGGER_WORKING_DIRECTORY.rst
+++ b/Help/prop_tgt/VS_DEBUGGER_WORKING_DIRECTORY.rst
@@ -1,6 +1,8 @@
 VS_DEBUGGER_WORKING_DIRECTORY
 -----------------------------
 
+.. versionadded:: 3.8
+
 Sets the local debugger working directory for Visual Studio C++ targets.
 The property value may use
 :manual:`generator expressions <cmake-generator-expressions(7)>`.
diff --git a/Help/prop_tgt/VS_DESKTOP_EXTENSIONS_VERSION.rst b/Help/prop_tgt/VS_DESKTOP_EXTENSIONS_VERSION.rst
index 19d1620..5fd23e1 100644
--- a/Help/prop_tgt/VS_DESKTOP_EXTENSIONS_VERSION.rst
+++ b/Help/prop_tgt/VS_DESKTOP_EXTENSIONS_VERSION.rst
@@ -1,6 +1,8 @@
 VS_DESKTOP_EXTENSIONS_VERSION
 -----------------------------
 
+.. versionadded:: 3.4
+
 Visual Studio Windows 10 Desktop Extensions Version
 
 Specifies the version of the Desktop Extensions that should be included in the
diff --git a/Help/prop_tgt/VS_DOTNET_DOCUMENTATION_FILE.rst b/Help/prop_tgt/VS_DOTNET_DOCUMENTATION_FILE.rst
index 1bc361c..a388256 100644
--- a/Help/prop_tgt/VS_DOTNET_DOCUMENTATION_FILE.rst
+++ b/Help/prop_tgt/VS_DOTNET_DOCUMENTATION_FILE.rst
@@ -1,6 +1,8 @@
 VS_DOTNET_DOCUMENTATION_FILE
 ----------------------------
 
+.. versionadded:: 3.17
+
 Visual Studio managed project .NET documentation output
 
 Sets the target XML documentation file output.
diff --git a/Help/prop_tgt/VS_DOTNET_REFERENCEPROP_refname_TAG_tagname.rst b/Help/prop_tgt/VS_DOTNET_REFERENCEPROP_refname_TAG_tagname.rst
index ab311ea..5b9caee 100644
--- a/Help/prop_tgt/VS_DOTNET_REFERENCEPROP_refname_TAG_tagname.rst
+++ b/Help/prop_tgt/VS_DOTNET_REFERENCEPROP_refname_TAG_tagname.rst
@@ -1,6 +1,8 @@
 VS_DOTNET_REFERENCEPROP_<refname>_TAG_<tagname>
 -----------------------------------------------
 
+.. versionadded:: 3.10
+
 Defines an XML property ``<tagname>`` for a .NET reference
 ``<refname>``.
 
diff --git a/Help/prop_tgt/VS_DOTNET_REFERENCES_COPY_LOCAL.rst b/Help/prop_tgt/VS_DOTNET_REFERENCES_COPY_LOCAL.rst
index 7641ba5..556fa8a 100644
--- a/Help/prop_tgt/VS_DOTNET_REFERENCES_COPY_LOCAL.rst
+++ b/Help/prop_tgt/VS_DOTNET_REFERENCES_COPY_LOCAL.rst
@@ -1,6 +1,8 @@
 VS_DOTNET_REFERENCES_COPY_LOCAL
 -------------------------------
 
+.. versionadded:: 3.8
+
 Sets the **Copy Local** property for all .NET hint references in the target
 
 Boolean property to enable/disable copying of .NET hint references to
diff --git a/Help/prop_tgt/VS_DOTNET_REFERENCE_refname.rst b/Help/prop_tgt/VS_DOTNET_REFERENCE_refname.rst
index 5814005..9c4d34a 100644
--- a/Help/prop_tgt/VS_DOTNET_REFERENCE_refname.rst
+++ b/Help/prop_tgt/VS_DOTNET_REFERENCE_refname.rst
@@ -1,6 +1,8 @@
 VS_DOTNET_REFERENCE_<refname>
 -----------------------------
 
+.. versionadded:: 3.8
+
 Visual Studio managed project .NET reference with name ``<refname>``
 and hint path.
 
diff --git a/Help/prop_tgt/VS_DPI_AWARE.rst b/Help/prop_tgt/VS_DPI_AWARE.rst
index 82640cc..47ce1ce 100644
--- a/Help/prop_tgt/VS_DPI_AWARE.rst
+++ b/Help/prop_tgt/VS_DPI_AWARE.rst
@@ -1,6 +1,8 @@
 VS_DPI_AWARE
 ------------
 
+.. versionadded:: 3.16
+
 Set the Manifest Tool -> Input and Output -> DPI Awareness in the Visual Studio
 target project properties.
 
diff --git a/Help/prop_tgt/VS_IOT_EXTENSIONS_VERSION.rst b/Help/prop_tgt/VS_IOT_EXTENSIONS_VERSION.rst
index 27c8a3d..ca6a3ca 100644
--- a/Help/prop_tgt/VS_IOT_EXTENSIONS_VERSION.rst
+++ b/Help/prop_tgt/VS_IOT_EXTENSIONS_VERSION.rst
@@ -1,6 +1,8 @@
 VS_IOT_EXTENSIONS_VERSION
 -------------------------
 
+.. versionadded:: 3.4
+
 Visual Studio Windows 10 IoT Extensions Version
 
 Specifies the version of the IoT Extensions that should be included in the
diff --git a/Help/prop_tgt/VS_IOT_STARTUP_TASK.rst b/Help/prop_tgt/VS_IOT_STARTUP_TASK.rst
index add50cb..259055d 100644
--- a/Help/prop_tgt/VS_IOT_STARTUP_TASK.rst
+++ b/Help/prop_tgt/VS_IOT_STARTUP_TASK.rst
@@ -1,6 +1,8 @@
 VS_IOT_STARTUP_TASK
 -------------------
 
+.. versionadded:: 3.4
+
 Visual Studio Windows 10 IoT Continuous Background Task
 
 Specifies that the target should be compiled as a Continuous Background Task library.
diff --git a/Help/prop_tgt/VS_JUST_MY_CODE_DEBUGGING.rst b/Help/prop_tgt/VS_JUST_MY_CODE_DEBUGGING.rst
index 42fb8ad..724bd2f 100644
--- a/Help/prop_tgt/VS_JUST_MY_CODE_DEBUGGING.rst
+++ b/Help/prop_tgt/VS_JUST_MY_CODE_DEBUGGING.rst
@@ -1,6 +1,8 @@
 VS_JUST_MY_CODE_DEBUGGING
 -------------------------
 
+.. versionadded:: 3.15
+
 Enable Just My Code with Visual Studio debugger.
 
 Supported on :ref:`Visual Studio Generators` for VS 2010 and higher,
diff --git a/Help/prop_tgt/VS_MOBILE_EXTENSIONS_VERSION.rst b/Help/prop_tgt/VS_MOBILE_EXTENSIONS_VERSION.rst
index be3c9a0..b307e84 100644
--- a/Help/prop_tgt/VS_MOBILE_EXTENSIONS_VERSION.rst
+++ b/Help/prop_tgt/VS_MOBILE_EXTENSIONS_VERSION.rst
@@ -1,6 +1,8 @@
 VS_MOBILE_EXTENSIONS_VERSION
 ----------------------------
 
+.. versionadded:: 3.4
+
 Visual Studio Windows 10 Mobile Extensions Version
 
 Specifies the version of the Mobile Extensions that should be included in the
diff --git a/Help/prop_tgt/VS_NO_SOLUTION_DEPLOY.rst b/Help/prop_tgt/VS_NO_SOLUTION_DEPLOY.rst
index ffcbde5..bf6ac10 100644
--- a/Help/prop_tgt/VS_NO_SOLUTION_DEPLOY.rst
+++ b/Help/prop_tgt/VS_NO_SOLUTION_DEPLOY.rst
@@ -1,6 +1,8 @@
 VS_NO_SOLUTION_DEPLOY
 ---------------------
 
+.. versionadded:: 3.15
+
 Specify that the target should not be marked for deployment to a Windows CE
 or Windows Phone device in the generated Visual Studio solution.
 
diff --git a/Help/prop_tgt/VS_PACKAGE_REFERENCES.rst b/Help/prop_tgt/VS_PACKAGE_REFERENCES.rst
index 5a0465b..ec17567 100644
--- a/Help/prop_tgt/VS_PACKAGE_REFERENCES.rst
+++ b/Help/prop_tgt/VS_PACKAGE_REFERENCES.rst
@@ -1,6 +1,8 @@
 VS_PACKAGE_REFERENCES
 ---------------------
 
+.. versionadded:: 3.15
+
 Visual Studio package references for nuget.
 
 Adds one or more semicolon-delimited package references to a generated
diff --git a/Help/prop_tgt/VS_PLATFORM_TOOLSET.rst b/Help/prop_tgt/VS_PLATFORM_TOOLSET.rst
index f8f2e8e..27a92d6 100644
--- a/Help/prop_tgt/VS_PLATFORM_TOOLSET.rst
+++ b/Help/prop_tgt/VS_PLATFORM_TOOLSET.rst
@@ -1,6 +1,8 @@
 VS_PLATFORM_TOOLSET
 -------------------
 
+.. versionadded:: 3.18
+
 Overrides the platform toolset used to build a target.
 
 Only supported when the compiler used by the given toolset is the
diff --git a/Help/prop_tgt/VS_PROJECT_IMPORT.rst b/Help/prop_tgt/VS_PROJECT_IMPORT.rst
index 569c8ea..f5e9698 100644
--- a/Help/prop_tgt/VS_PROJECT_IMPORT.rst
+++ b/Help/prop_tgt/VS_PROJECT_IMPORT.rst
@@ -1,6 +1,8 @@
 VS_PROJECT_IMPORT
 -----------------
 
+.. versionadded:: 3.15
+
 Visual Studio managed project imports
 
 Adds to a generated Visual Studio project one or more semicolon-delimited paths
diff --git a/Help/prop_tgt/VS_SDK_REFERENCES.rst b/Help/prop_tgt/VS_SDK_REFERENCES.rst
index 99987f5..9a082e7 100644
--- a/Help/prop_tgt/VS_SDK_REFERENCES.rst
+++ b/Help/prop_tgt/VS_SDK_REFERENCES.rst
@@ -1,6 +1,8 @@
 VS_SDK_REFERENCES
 -----------------
 
+.. versionadded:: 3.7
+
 Visual Studio project SDK references.
 Specify a :ref:`semicolon-separated list <CMake Language Lists>` of SDK references
 to be added to a generated Visual Studio project, e.g.
diff --git a/Help/prop_tgt/VS_SOLUTION_DEPLOY.rst b/Help/prop_tgt/VS_SOLUTION_DEPLOY.rst
index eef848f..e56f411 100644
--- a/Help/prop_tgt/VS_SOLUTION_DEPLOY.rst
+++ b/Help/prop_tgt/VS_SOLUTION_DEPLOY.rst
@@ -1,6 +1,8 @@
 VS_SOLUTION_DEPLOY
 ------------------
 
+.. versionadded:: 3.18
+
 Specify that the target should be marked for deployment when not targeting
 Windows CE, Windows Phone or a Windows Store application.
 
diff --git a/Help/prop_tgt/VS_SOURCE_SETTINGS_tool.rst b/Help/prop_tgt/VS_SOURCE_SETTINGS_tool.rst
index 738a912..b5a76fc 100644
--- a/Help/prop_tgt/VS_SOURCE_SETTINGS_tool.rst
+++ b/Help/prop_tgt/VS_SOURCE_SETTINGS_tool.rst
@@ -1,6 +1,8 @@
 VS_SOURCE_SETTINGS_<tool>
 -------------------------
 
+.. versionadded:: 3.18
+
 Set any item metadata on all non-built files that use <tool>.
 
 Takes a list of ``Key=Value`` pairs. Tells the Visual Studio generator
diff --git a/Help/prop_tgt/VS_USER_PROPS.rst b/Help/prop_tgt/VS_USER_PROPS.rst
index 1be222b..8f2a105 100644
--- a/Help/prop_tgt/VS_USER_PROPS.rst
+++ b/Help/prop_tgt/VS_USER_PROPS.rst
@@ -1,6 +1,8 @@
 VS_USER_PROPS
 -------------
 
+.. versionadded:: 3.8
+
 Sets the user props file to be included in the visual studio
 C++ project file. The standard path is
 ``$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props``, which is
diff --git a/Help/prop_tgt/VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION.rst b/Help/prop_tgt/VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION.rst
index 1ad7a71..50cf203 100644
--- a/Help/prop_tgt/VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION.rst
+++ b/Help/prop_tgt/VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION.rst
@@ -1,6 +1,8 @@
 VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION
 --------------------------------------
 
+.. versionadded:: 3.4
+
 Visual Studio Windows Target Platform Minimum Version
 
 For Windows 10. Specifies the minimum version of the OS that is being
diff --git a/Help/prop_tgt/VS_WINRT_COMPONENT.rst b/Help/prop_tgt/VS_WINRT_COMPONENT.rst
index e160bd6..8b4aaf7 100644
--- a/Help/prop_tgt/VS_WINRT_COMPONENT.rst
+++ b/Help/prop_tgt/VS_WINRT_COMPONENT.rst
@@ -1,6 +1,8 @@
 VS_WINRT_COMPONENT
 ------------------
 
+.. versionadded:: 3.1
+
 Mark a target as a Windows Runtime component for the Visual Studio generator.
 Compile the target with ``C++/CX`` language extensions for Windows Runtime.
 For ``SHARED`` and ``MODULE`` libraries, this also defines the
diff --git a/Help/prop_tgt/WINDOWS_EXPORT_ALL_SYMBOLS.rst b/Help/prop_tgt/WINDOWS_EXPORT_ALL_SYMBOLS.rst
index 86711bf..00f32f6 100644
--- a/Help/prop_tgt/WINDOWS_EXPORT_ALL_SYMBOLS.rst
+++ b/Help/prop_tgt/WINDOWS_EXPORT_ALL_SYMBOLS.rst
@@ -1,6 +1,8 @@
 WINDOWS_EXPORT_ALL_SYMBOLS
 --------------------------
 
+.. versionadded:: 3.4
+
 This property is implemented only for MS-compatible tools on Windows.
 
 Enable this boolean property to automatically create a module definition
diff --git a/Help/prop_tgt/XCODE_EXPLICIT_FILE_TYPE.rst b/Help/prop_tgt/XCODE_EXPLICIT_FILE_TYPE.rst
index dc92902..e01a034 100644
--- a/Help/prop_tgt/XCODE_EXPLICIT_FILE_TYPE.rst
+++ b/Help/prop_tgt/XCODE_EXPLICIT_FILE_TYPE.rst
@@ -1,6 +1,8 @@
 XCODE_EXPLICIT_FILE_TYPE
 ------------------------
 
+.. versionadded:: 3.8
+
 Set the Xcode ``explicitFileType`` attribute on its reference to a
 target.  CMake computes a default based on target type but
 can be told explicitly with this property.
diff --git a/Help/prop_tgt/XCODE_GENERATE_SCHEME.rst b/Help/prop_tgt/XCODE_GENERATE_SCHEME.rst
index c32b4de..06a3cf9 100644
--- a/Help/prop_tgt/XCODE_GENERATE_SCHEME.rst
+++ b/Help/prop_tgt/XCODE_GENERATE_SCHEME.rst
@@ -1,6 +1,8 @@
 XCODE_GENERATE_SCHEME
 ---------------------
 
+.. versionadded:: 3.15
+
 If enabled, the :generator:`Xcode` generator will generate schema files.  These
 are useful to invoke analyze, archive, build-for-testing and test
 actions from the command line.
diff --git a/Help/prop_tgt/XCODE_PRODUCT_TYPE.rst b/Help/prop_tgt/XCODE_PRODUCT_TYPE.rst
index f4ef5c0..17a9c3f 100644
--- a/Help/prop_tgt/XCODE_PRODUCT_TYPE.rst
+++ b/Help/prop_tgt/XCODE_PRODUCT_TYPE.rst
@@ -1,6 +1,8 @@
 XCODE_PRODUCT_TYPE
 ------------------
 
+.. versionadded:: 3.8
+
 Set the Xcode ``productType`` attribute on its reference to a
 target.  CMake computes a default based on target type but
 can be told explicitly with this property.
diff --git a/Help/prop_tgt/XCODE_SCHEME_ADDRESS_SANITIZER.rst b/Help/prop_tgt/XCODE_SCHEME_ADDRESS_SANITIZER.rst
index cc9bac2..c72ec06 100644
--- a/Help/prop_tgt/XCODE_SCHEME_ADDRESS_SANITIZER.rst
+++ b/Help/prop_tgt/XCODE_SCHEME_ADDRESS_SANITIZER.rst
@@ -1,6 +1,8 @@
 XCODE_SCHEME_ADDRESS_SANITIZER
 ------------------------------
 
+.. versionadded:: 3.13
+
 Whether to enable ``Address Sanitizer`` in the Diagnostics
 section of the generated Xcode scheme.
 
diff --git a/Help/prop_tgt/XCODE_SCHEME_ADDRESS_SANITIZER_USE_AFTER_RETURN.rst b/Help/prop_tgt/XCODE_SCHEME_ADDRESS_SANITIZER_USE_AFTER_RETURN.rst
index 37a043a..293b5d4 100644
--- a/Help/prop_tgt/XCODE_SCHEME_ADDRESS_SANITIZER_USE_AFTER_RETURN.rst
+++ b/Help/prop_tgt/XCODE_SCHEME_ADDRESS_SANITIZER_USE_AFTER_RETURN.rst
@@ -1,6 +1,8 @@
 XCODE_SCHEME_ADDRESS_SANITIZER_USE_AFTER_RETURN
 -----------------------------------------------
 
+.. versionadded:: 3.13
+
 Whether to enable ``Detect use of stack after return``
 in the Diagnostics section of the generated Xcode scheme.
 
diff --git a/Help/prop_tgt/XCODE_SCHEME_ARGUMENTS.rst b/Help/prop_tgt/XCODE_SCHEME_ARGUMENTS.rst
index 1f228e3..2bfcb41 100644
--- a/Help/prop_tgt/XCODE_SCHEME_ARGUMENTS.rst
+++ b/Help/prop_tgt/XCODE_SCHEME_ARGUMENTS.rst
@@ -1,6 +1,8 @@
 XCODE_SCHEME_ARGUMENTS
 ----------------------
 
+.. versionadded:: 3.13
+
 Specify command line arguments that should be added to the Arguments
 section of the generated Xcode scheme.
 
diff --git a/Help/prop_tgt/XCODE_SCHEME_DEBUG_AS_ROOT.rst b/Help/prop_tgt/XCODE_SCHEME_DEBUG_AS_ROOT.rst
index 5407e80..2523deb 100644
--- a/Help/prop_tgt/XCODE_SCHEME_DEBUG_AS_ROOT.rst
+++ b/Help/prop_tgt/XCODE_SCHEME_DEBUG_AS_ROOT.rst
@@ -1,6 +1,8 @@
 XCODE_SCHEME_DEBUG_AS_ROOT
 --------------------------
 
+.. versionadded:: 3.15
+
 Whether to debug the target as 'root'.
 
 Please refer to the :prop_tgt:`XCODE_GENERATE_SCHEME` target property
diff --git a/Help/prop_tgt/XCODE_SCHEME_DEBUG_DOCUMENT_VERSIONING.rst b/Help/prop_tgt/XCODE_SCHEME_DEBUG_DOCUMENT_VERSIONING.rst
index 9afeedd..bbcae35 100644
--- a/Help/prop_tgt/XCODE_SCHEME_DEBUG_DOCUMENT_VERSIONING.rst
+++ b/Help/prop_tgt/XCODE_SCHEME_DEBUG_DOCUMENT_VERSIONING.rst
@@ -1,6 +1,8 @@
 XCODE_SCHEME_DEBUG_DOCUMENT_VERSIONING
 --------------------------------------
 
+.. versionadded:: 3.16
+
 Whether to enable
 ``Allow debugging when using document Versions Browser``
 in the Options section of the generated Xcode scheme.
diff --git a/Help/prop_tgt/XCODE_SCHEME_DISABLE_MAIN_THREAD_CHECKER.rst b/Help/prop_tgt/XCODE_SCHEME_DISABLE_MAIN_THREAD_CHECKER.rst
index 1a6fcfd..3d315a2 100644
--- a/Help/prop_tgt/XCODE_SCHEME_DISABLE_MAIN_THREAD_CHECKER.rst
+++ b/Help/prop_tgt/XCODE_SCHEME_DISABLE_MAIN_THREAD_CHECKER.rst
@@ -1,6 +1,8 @@
 XCODE_SCHEME_DISABLE_MAIN_THREAD_CHECKER
 ----------------------------------------
 
+.. versionadded:: 3.13
+
 Whether to disable the ``Main Thread Checker``
 in the Diagnostics section of the generated Xcode scheme.
 
diff --git a/Help/prop_tgt/XCODE_SCHEME_DYNAMIC_LIBRARY_LOADS.rst b/Help/prop_tgt/XCODE_SCHEME_DYNAMIC_LIBRARY_LOADS.rst
index 9224022..2ca20f7 100644
--- a/Help/prop_tgt/XCODE_SCHEME_DYNAMIC_LIBRARY_LOADS.rst
+++ b/Help/prop_tgt/XCODE_SCHEME_DYNAMIC_LIBRARY_LOADS.rst
@@ -1,6 +1,8 @@
 XCODE_SCHEME_DYNAMIC_LIBRARY_LOADS
 ----------------------------------
 
+.. versionadded:: 3.13
+
 Whether to enable ``Dynamic Library Loads``
 in the Diagnostics section of the generated Xcode scheme.
 
diff --git a/Help/prop_tgt/XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE.rst b/Help/prop_tgt/XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE.rst
index 203c803..278c9ef 100644
--- a/Help/prop_tgt/XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE.rst
+++ b/Help/prop_tgt/XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE.rst
@@ -1,6 +1,8 @@
 XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE
 -------------------------------------
 
+.. versionadded:: 3.13
+
 Whether to enable ``Dynamic Linker API usage``
 in the Diagnostics section of the generated Xcode scheme.
 
diff --git a/Help/prop_tgt/XCODE_SCHEME_ENVIRONMENT.rst b/Help/prop_tgt/XCODE_SCHEME_ENVIRONMENT.rst
index c6d875e..16542f8 100644
--- a/Help/prop_tgt/XCODE_SCHEME_ENVIRONMENT.rst
+++ b/Help/prop_tgt/XCODE_SCHEME_ENVIRONMENT.rst
@@ -1,6 +1,8 @@
 XCODE_SCHEME_ENVIRONMENT
 ------------------------
 
+.. versionadded:: 3.13
+
 Specify environment variables that should be added to the Arguments
 section of the generated Xcode scheme.
 
diff --git a/Help/prop_tgt/XCODE_SCHEME_EXECUTABLE.rst b/Help/prop_tgt/XCODE_SCHEME_EXECUTABLE.rst
index 104841b..b453f10 100644
--- a/Help/prop_tgt/XCODE_SCHEME_EXECUTABLE.rst
+++ b/Help/prop_tgt/XCODE_SCHEME_EXECUTABLE.rst
@@ -1,6 +1,8 @@
 XCODE_SCHEME_EXECUTABLE
 -----------------------
 
+.. versionadded:: 3.13
+
 Specify path to executable in the Info section of the generated
 Xcode scheme. If not set the schema generator will select the
 current target if it is actually executable.
diff --git a/Help/prop_tgt/XCODE_SCHEME_GUARD_MALLOC.rst b/Help/prop_tgt/XCODE_SCHEME_GUARD_MALLOC.rst
index c4e83da..4b242a2 100644
--- a/Help/prop_tgt/XCODE_SCHEME_GUARD_MALLOC.rst
+++ b/Help/prop_tgt/XCODE_SCHEME_GUARD_MALLOC.rst
@@ -1,6 +1,8 @@
 XCODE_SCHEME_GUARD_MALLOC
 ------------------------------
 
+.. versionadded:: 3.13
+
 Whether to enable ``Guard Malloc``
 in the Diagnostics section of the generated Xcode scheme.
 
diff --git a/Help/prop_tgt/XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP.rst b/Help/prop_tgt/XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP.rst
index 73992c3..2a813aa 100644
--- a/Help/prop_tgt/XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP.rst
+++ b/Help/prop_tgt/XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP.rst
@@ -1,6 +1,8 @@
 XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP
 -------------------------------------
 
+.. versionadded:: 3.13
+
 Whether to enable the ``Main Thread Checker`` option
 ``Pause on issues``
 in the Diagnostics section of the generated Xcode scheme.
diff --git a/Help/prop_tgt/XCODE_SCHEME_MALLOC_GUARD_EDGES.rst b/Help/prop_tgt/XCODE_SCHEME_MALLOC_GUARD_EDGES.rst
index ca761c0..750da74 100644
--- a/Help/prop_tgt/XCODE_SCHEME_MALLOC_GUARD_EDGES.rst
+++ b/Help/prop_tgt/XCODE_SCHEME_MALLOC_GUARD_EDGES.rst
@@ -1,6 +1,8 @@
 XCODE_SCHEME_MALLOC_GUARD_EDGES
 -------------------------------
 
+.. versionadded:: 3.13
+
 Whether to enable ``Malloc Guard Edges``
 in the Diagnostics section of the generated Xcode scheme.
 
diff --git a/Help/prop_tgt/XCODE_SCHEME_MALLOC_SCRIBBLE.rst b/Help/prop_tgt/XCODE_SCHEME_MALLOC_SCRIBBLE.rst
index c5ddb95..4ebd21b 100644
--- a/Help/prop_tgt/XCODE_SCHEME_MALLOC_SCRIBBLE.rst
+++ b/Help/prop_tgt/XCODE_SCHEME_MALLOC_SCRIBBLE.rst
@@ -1,6 +1,8 @@
 XCODE_SCHEME_MALLOC_SCRIBBLE
 ------------------------------
 
+.. versionadded:: 3.13
+
 Whether to enable ``Malloc Scribble``
 in the Diagnostics section of the generated Xcode scheme.
 
diff --git a/Help/prop_tgt/XCODE_SCHEME_MALLOC_STACK.rst b/Help/prop_tgt/XCODE_SCHEME_MALLOC_STACK.rst
index 170f33d..5afe34e 100644
--- a/Help/prop_tgt/XCODE_SCHEME_MALLOC_STACK.rst
+++ b/Help/prop_tgt/XCODE_SCHEME_MALLOC_STACK.rst
@@ -1,6 +1,8 @@
 XCODE_SCHEME_MALLOC_STACK
 -------------------------
 
+.. versionadded:: 3.13
+
 Whether to enable ``Malloc Stack`` in the Diagnostics
 section of the generated Xcode scheme.
 
diff --git a/Help/prop_tgt/XCODE_SCHEME_THREAD_SANITIZER.rst b/Help/prop_tgt/XCODE_SCHEME_THREAD_SANITIZER.rst
index bb70141..cc774c4 100644
--- a/Help/prop_tgt/XCODE_SCHEME_THREAD_SANITIZER.rst
+++ b/Help/prop_tgt/XCODE_SCHEME_THREAD_SANITIZER.rst
@@ -1,6 +1,8 @@
 XCODE_SCHEME_THREAD_SANITIZER
 -----------------------------
 
+.. versionadded:: 3.13
+
 Whether to enable ``Thread Sanitizer`` in the Diagnostics
 section of the generated Xcode scheme.
 
diff --git a/Help/prop_tgt/XCODE_SCHEME_THREAD_SANITIZER_STOP.rst b/Help/prop_tgt/XCODE_SCHEME_THREAD_SANITIZER_STOP.rst
index 5deadb1..3bb2596 100644
--- a/Help/prop_tgt/XCODE_SCHEME_THREAD_SANITIZER_STOP.rst
+++ b/Help/prop_tgt/XCODE_SCHEME_THREAD_SANITIZER_STOP.rst
@@ -1,6 +1,8 @@
 XCODE_SCHEME_THREAD_SANITIZER_STOP
 ----------------------------------
 
+.. versionadded:: 3.13
+
 Whether to enable ``Thread Sanitizer - Pause on issues``
 in the Diagnostics section of the generated Xcode scheme.
 
diff --git a/Help/prop_tgt/XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER.rst b/Help/prop_tgt/XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER.rst
index 0cd823d..1146130 100644
--- a/Help/prop_tgt/XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER.rst
+++ b/Help/prop_tgt/XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER.rst
@@ -1,6 +1,8 @@
 XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER
 ------------------------------------------
 
+.. versionadded:: 3.13
+
 Whether to enable ``Undefined Behavior Sanitizer``
 in the Diagnostics section of the generated Xcode scheme.
 
diff --git a/Help/prop_tgt/XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP.rst b/Help/prop_tgt/XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP.rst
index d1a9bca..358f298 100644
--- a/Help/prop_tgt/XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP.rst
+++ b/Help/prop_tgt/XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP.rst
@@ -1,6 +1,8 @@
 XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP
 -----------------------------------------------
 
+.. versionadded:: 3.13
+
 Whether to enable ``Undefined Behavior Sanitizer`` option
 ``Pause on issues``
 in the Diagnostics section of the generated Xcode scheme.
diff --git a/Help/prop_tgt/XCODE_SCHEME_WORKING_DIRECTORY.rst b/Help/prop_tgt/XCODE_SCHEME_WORKING_DIRECTORY.rst
index f538f1d..d8d56fc 100644
--- a/Help/prop_tgt/XCODE_SCHEME_WORKING_DIRECTORY.rst
+++ b/Help/prop_tgt/XCODE_SCHEME_WORKING_DIRECTORY.rst
@@ -1,6 +1,8 @@
 XCODE_SCHEME_WORKING_DIRECTORY
 ------------------------------
 
+.. versionadded:: 3.17
+
 Specify the ``Working Directory`` of the *Run* and *Profile*
 actions in the generated Xcode scheme. In case the value contains
 generator expressions those are evaluated.
diff --git a/Help/prop_tgt/XCODE_SCHEME_ZOMBIE_OBJECTS.rst b/Help/prop_tgt/XCODE_SCHEME_ZOMBIE_OBJECTS.rst
index 6e70e8b..6030109 100644
--- a/Help/prop_tgt/XCODE_SCHEME_ZOMBIE_OBJECTS.rst
+++ b/Help/prop_tgt/XCODE_SCHEME_ZOMBIE_OBJECTS.rst
@@ -1,6 +1,8 @@
 XCODE_SCHEME_ZOMBIE_OBJECTS
 ------------------------------
 
+.. versionadded:: 3.13
+
 Whether to enable ``Zombie Objects``
 in the Diagnostics section of the generated Xcode scheme.
 
diff --git a/Help/prop_tgt/XCTEST.rst b/Help/prop_tgt/XCTEST.rst
index eb47e60..67e9a70 100644
--- a/Help/prop_tgt/XCTEST.rst
+++ b/Help/prop_tgt/XCTEST.rst
@@ -1,6 +1,8 @@
 XCTEST
 ------
 
+.. versionadded:: 3.3
+
 This target is a XCTest CFBundle on the Mac.
 
 This property will usually get set via the :command:`xctest_add_bundle`
diff --git a/Help/release/3.1.rst b/Help/release/3.1.rst
index 8bea28f..3f4712b 100644
--- a/Help/release/3.1.rst
+++ b/Help/release/3.1.rst
@@ -83,7 +83,7 @@
   :manual:`generator expression <cmake-generator-expressions(7)>`.
 
 * The :command:`string` command learned a new ``UUID`` subcommand
-  to generate a univerally unique identifier.
+  to generate a universally unique identifier.
 
 * New :command:`target_compile_features` command allows populating the
   :prop_tgt:`COMPILE_FEATURES` target property, just like any other
diff --git a/Help/release/3.3.rst b/Help/release/3.3.rst
index 6657e8d..44f4e19 100644
--- a/Help/release/3.3.rst
+++ b/Help/release/3.3.rst
@@ -196,7 +196,7 @@
   :prop_inst:`CPACK_START_MENU_SHORTCUTS`,
   :prop_inst:`CPACK_DESKTOP_SHORTCUTS` and
   :prop_inst:`CPACK_STARTUP_SHORTCUTS` installed file properties which can
-  be used to install shorcuts in the Start Menu, on the Desktop and
+  be used to install shortcuts in the Start Menu, on the Desktop and
   in the Startup Folder respectively.
 
 Other
diff --git a/Help/release/dev/0-sample-topic.rst b/Help/release/dev/0-sample-topic.rst
new file mode 100644
index 0000000..e4cc01e
--- /dev/null
+++ b/Help/release/dev/0-sample-topic.rst
@@ -0,0 +1,7 @@
+0-sample-topic
+--------------
+
+* This is a sample release note for the change in a topic.
+  Developers should add similar notes for each topic branch
+  making a noteworthy change.  Each document should be named
+  and titled to match the topic name to avoid merge conflicts.
diff --git a/Help/release/dev/CPACK_EXTERNAL_BUILT_PACKAGES.rst b/Help/release/dev/CPACK_EXTERNAL_BUILT_PACKAGES.rst
new file mode 100644
index 0000000..af446d2
--- /dev/null
+++ b/Help/release/dev/CPACK_EXTERNAL_BUILT_PACKAGES.rst
@@ -0,0 +1,4 @@
+CPACK_EXTERNAL_BUILT_PACKAGES
+-----------------------------
+
+* :cpack_gen:`CPack External Generator` learned the :variable:`CPACK_EXTERNAL_BUILT_PACKAGES` variable.
diff --git a/Help/release/dev/EXCLUDE_FROM_ALL-genex.rst b/Help/release/dev/EXCLUDE_FROM_ALL-genex.rst
new file mode 100644
index 0000000..4d5a83c
--- /dev/null
+++ b/Help/release/dev/EXCLUDE_FROM_ALL-genex.rst
@@ -0,0 +1,5 @@
+EXCLUDE_FROM_ALL-genex
+----------------------
+
+* The :prop_tgt:`EXCLUDE_FROM_ALL` target property gained support for
+  :manual:`generator expressions <cmake-generator-expressions(7)>`.
diff --git a/Help/release/dev/FindCUDAToolkit-no-nvcc.rst b/Help/release/dev/FindCUDAToolkit-no-nvcc.rst
new file mode 100644
index 0000000..e815876
--- /dev/null
+++ b/Help/release/dev/FindCUDAToolkit-no-nvcc.rst
@@ -0,0 +1,5 @@
+FindCUDAToolkit-no-nvcc
+-----------------------
+
+* The :module:`FindCUDAToolkit` module gained support for finding CUDA toolkits
+  that do not contain ``nvcc``.
diff --git a/Help/release/dev/FindSDL-update.rst b/Help/release/dev/FindSDL-update.rst
new file mode 100644
index 0000000..a85d2b9
--- /dev/null
+++ b/Help/release/dev/FindSDL-update.rst
@@ -0,0 +1,11 @@
+FindSDL-update
+--------------
+
+* The :module:`FindSDL` module now provides:
+
+  * imported target ``SDL::SDL``,
+
+  * result variables ``SDL_LIBRARIES`` and ``SDL_INCLUDE_DIRS``,
+
+  * version variables ``SDL_VERSION``, ``SDL_VERSION_MAJOR``
+    ``SDL_VERSION_MINOR``, and ``SDL_VERSION_PATCH``.
diff --git a/Help/release/dev/FindTIFF-tiffxx.rst b/Help/release/dev/FindTIFF-tiffxx.rst
new file mode 100644
index 0000000..656d38f
--- /dev/null
+++ b/Help/release/dev/FindTIFF-tiffxx.rst
@@ -0,0 +1,5 @@
+FindTIFF-tiffxx
+---------------
+
+* The :module:`FindTIFF` module gained a ``CXX`` component to
+  find the ``tiffxx`` library containing C++ bindings.
diff --git a/Help/release/dev/FindVulkan-glslc.rst b/Help/release/dev/FindVulkan-glslc.rst
new file mode 100644
index 0000000..246bc8f
--- /dev/null
+++ b/Help/release/dev/FindVulkan-glslc.rst
@@ -0,0 +1,10 @@
+FindVulkan-glslc
+----------------
+
+* The :module:`FindVulkan` module gained a new output variable
+  ``Vulkan_GLSLC_EXECUTABLE`` which contains the path to the
+  GLSL SPIR-V compiler.
+
+* The :module:`FindVulkan` module gained a new target
+  ``Vulkan::glslc`` which contains the path to the
+  GLSL SPIR-V compiler.
diff --git a/Help/release/dev/build-interface-targets.rst b/Help/release/dev/build-interface-targets.rst
new file mode 100644
index 0000000..37bded4
--- /dev/null
+++ b/Help/release/dev/build-interface-targets.rst
@@ -0,0 +1,6 @@
+build-interface-targets
+-----------------------
+
+* :ref:`Interface Libraries` may now have source files added via
+  :command:`add_library` or :command:`target_sources`.  Those
+  with sources will be generated as part of the build system.
diff --git a/Help/release/dev/clang-cl-vfs.rst b/Help/release/dev/clang-cl-vfs.rst
new file mode 100644
index 0000000..40b19ef
--- /dev/null
+++ b/Help/release/dev/clang-cl-vfs.rst
@@ -0,0 +1,6 @@
+clang-cl-vfs
+------------
+
+* A :variable:`CMAKE_CLANG_VFS_OVERLAY` variable was added to tell
+  Clang to use a VFS overlay to support the Windows SDK when
+  cross-compiling from hosts with case-sensitive filesystems.
diff --git a/Help/release/dev/cmake-E-create_hardlink.rst b/Help/release/dev/cmake-E-create_hardlink.rst
new file mode 100644
index 0000000..66cdc87
--- /dev/null
+++ b/Help/release/dev/cmake-E-create_hardlink.rst
@@ -0,0 +1,5 @@
+cmake-E-create_hardlink
+-----------------------
+
+* The :manual:`cmake(1)` gained a ``-E create_hardlink`` command-line tool
+  that can be used to create hardlinks between files.
diff --git a/Help/release/dev/compiler_flags.rst b/Help/release/dev/compiler_flags.rst
new file mode 100644
index 0000000..7138e80
--- /dev/null
+++ b/Help/release/dev/compiler_flags.rst
@@ -0,0 +1,9 @@
+compiler_flags
+-----------------
+
+* The :variable:`CMAKE_<LANG>_COMPILER` variable may now be used to
+  store "mandatory" compiler flags like the :envvar:`CC` and other environment variables.
+
+* The :variable:`CMAKE_<LANG>_FLAGS_INIT` variable will now be considered during
+  the compiler indentification check if other sources like :variable:`CMAKE_<LANG>_FLAGS`
+  or :envvar:`CFLAGS` are not set.
diff --git a/Help/release/dev/configure_file-permission-control.rst b/Help/release/dev/configure_file-permission-control.rst
new file mode 100644
index 0000000..54b52b7
--- /dev/null
+++ b/Help/release/dev/configure_file-permission-control.rst
@@ -0,0 +1,5 @@
+configure_file-permission-control
+---------------------------------
+
+* The :command:`configure_file` command gained a ``NO_SOURCE_PERMISSIONS``
+  option to suppress copying the input file's permissions to the output file.
diff --git a/Help/release/dev/cpack-pre-and-post-build-scripts.rst b/Help/release/dev/cpack-pre-and-post-build-scripts.rst
new file mode 100644
index 0000000..bf7958b
--- /dev/null
+++ b/Help/release/dev/cpack-pre-and-post-build-scripts.rst
@@ -0,0 +1,5 @@
+cpack-pre-and-post-build-scripts
+--------------------------------
+
+* CPack learned the :variable:`CPACK_PRE_BUILD_SCRIPTS`, :variable:`CPACK_POST_BUILD_SCRIPTS`,
+  and :variable:`CPACK_PACKAGE_FILES` variables.
diff --git a/Help/release/dev/ctest-cuda-memcheck.rst b/Help/release/dev/ctest-cuda-memcheck.rst
new file mode 100644
index 0000000..f8f861a
--- /dev/null
+++ b/Help/release/dev/ctest-cuda-memcheck.rst
@@ -0,0 +1,8 @@
+CTest
+-----
+
+* :manual:`ctest(1)` gained support for cuda-memcheck as ``CTEST_MEMORYCHECK_COMMAND``.
+  The different tools (memcheck, racecheck, synccheck, initcheck) supplied by
+  cuda-memcheck can be selected by setting the appropriate flags using the
+  ``CTEST_MEMORYCHECK_COMMAND_OPTIONS`` variable.
+  The default flags are `--tool memcheck --leak-check full`.
diff --git a/Help/release/dev/deprecate-policy-old.rst b/Help/release/dev/deprecate-policy-old.rst
new file mode 100644
index 0000000..1dc01cc
--- /dev/null
+++ b/Help/release/dev/deprecate-policy-old.rst
@@ -0,0 +1,13 @@
+deprecate-policy-old
+--------------------
+
+* An explicit deprecation diagnostic was added for policy ``CMP0071``
+  (``CMP0071`` and below were already deprecated).
+  The :manual:`cmake-policies(7)` manual explains that the OLD behaviors
+  of all policies are deprecated and that projects should port to the
+  NEW behaviors.
+
+* Compatibility with versions of CMake older than 2.8.12 is now deprecated
+  and will be removed from a future version.  Calls to
+  :command:`cmake_minimum_required` or :command:`cmake_policy` that set
+  the policy version to an older value now issue a deprecation diagnostic.
diff --git a/Help/release/dev/file-download-optional-file.rst b/Help/release/dev/file-download-optional-file.rst
new file mode 100644
index 0000000..f3dc24c
--- /dev/null
+++ b/Help/release/dev/file-download-optional-file.rst
@@ -0,0 +1,5 @@
+file-download-optional-file
+---------------------------
+
+* The ``<file>`` argument is now optional for :command:`file(DOWNLOAD)`. If it
+  is not specified, the file is not saved.
diff --git a/Help/release/dev/fileapi-codemodel-2.2.rst b/Help/release/dev/fileapi-codemodel-2.2.rst
new file mode 100644
index 0000000..5954df6
--- /dev/null
+++ b/Help/release/dev/fileapi-codemodel-2.2.rst
@@ -0,0 +1,7 @@
+fileapi-codemodel-2.2
+---------------------
+
+* The :manual:`cmake-file-api(7)` "codemodel" version 2 ``version`` field has
+  been updated to 2.2.
+* The :manual:`cmake-file-api(7)` "codemodel" version 2 "target" object gained
+  a new ``languageStandard`` field in the ``compileGroups`` objects.
diff --git a/Help/release/dev/find_program-exe-no-read.rst b/Help/release/dev/find_program-exe-no-read.rst
new file mode 100644
index 0000000..161b5db
--- /dev/null
+++ b/Help/release/dev/find_program-exe-no-read.rst
@@ -0,0 +1,5 @@
+find_program-exe-no-read
+------------------------
+
+* The :command:`find_program` command now requires permission to execute
+  but not to read the file found.  See policy :policy:`CMP0109`.
diff --git a/Help/release/dev/install-default-directory-permissions.rst b/Help/release/dev/install-default-directory-permissions.rst
new file mode 100644
index 0000000..27cffee
--- /dev/null
+++ b/Help/release/dev/install-default-directory-permissions.rst
@@ -0,0 +1,5 @@
+install-default-directory-permissions
+-------------------------------------
+
+* The ``--install`` argument of the :manual:`cmake(1)` command line tool gained a
+  ``--default-directory-permissions`` argument.
diff --git a/Help/release/dev/macOS-sdk-latest.rst b/Help/release/dev/macOS-sdk-latest.rst
new file mode 100644
index 0000000..c5ac3a6
--- /dev/null
+++ b/Help/release/dev/macOS-sdk-latest.rst
@@ -0,0 +1,10 @@
+macOS-sdk-latest
+----------------
+
+* Building for macOS will now use the latest SDK available on the system,
+  unless the user has explicitly chosen a SDK using :variable:`CMAKE_OSX_SYSROOT`.
+
+  The deployment target or system macOS version will not affect
+  the choice of SDK.
+
+* macOS SDKs older than 10.5 are no longer supported.
diff --git a/Help/release/dev/remove-cmake-gui-qt4.rst b/Help/release/dev/remove-cmake-gui-qt4.rst
new file mode 100644
index 0000000..2b29b75
--- /dev/null
+++ b/Help/release/dev/remove-cmake-gui-qt4.rst
@@ -0,0 +1,5 @@
+remove-cmake-gui-qt4
+--------------------
+
+* :manual:`cmake-gui(1)` now requires Qt5. Support for compiling with Qt4 has
+  been removed.
diff --git a/Help/release/dev/remove-warn-unused-vars.rst b/Help/release/dev/remove-warn-unused-vars.rst
new file mode 100644
index 0000000..7a06e91
--- /dev/null
+++ b/Help/release/dev/remove-warn-unused-vars.rst
@@ -0,0 +1,6 @@
+remove-warn-unused-vars
+-----------------------
+
+* The :manual:`cmake(1)` command-line option ``--warn-unused-vars`` has
+  been removed and is now silently ignored.  The option has not worked
+  correctly since CMake 3.3.
diff --git a/Help/release/dev/visual-studio-android.rst b/Help/release/dev/visual-studio-android.rst
new file mode 100644
index 0000000..4e1a110
--- /dev/null
+++ b/Help/release/dev/visual-studio-android.rst
@@ -0,0 +1,7 @@
+visual-studio-android
+---------------------
+
+* The :ref:`Visual Studio Generators` for Visual Studio 2015 and above gained
+  support for the Visual Studio Tools for Android. This allows you to set
+  :variable:`CMAKE_SYSTEM_NAME` to `Android` to generate `.vcxproj` files for
+  the Android tools.
diff --git a/Help/release/index.rst b/Help/release/index.rst
index 4578b3a..cdc3e8b 100644
--- a/Help/release/index.rst
+++ b/Help/release/index.rst
@@ -7,6 +7,8 @@
   This file should include the adjacent "dev.txt" file
   in development versions but not in release versions.
 
+.. include:: dev.txt
+
 Releases
 ========
 
diff --git a/Help/variable/ANDROID.rst b/Help/variable/ANDROID.rst
index fede4ca..68dccf2 100644
--- a/Help/variable/ANDROID.rst
+++ b/Help/variable/ANDROID.rst
@@ -1,5 +1,7 @@
 ANDROID
 -------
 
+.. versionadded:: 3.7
+
 Set to ``1`` when the target system (:variable:`CMAKE_SYSTEM_NAME`) is
 ``Android``.
diff --git a/Help/variable/CACHE.rst b/Help/variable/CACHE.rst
index 2cef27e..d5489c8 100644
--- a/Help/variable/CACHE.rst
+++ b/Help/variable/CACHE.rst
@@ -1,6 +1,8 @@
 CACHE
 -----
 
+.. versionadded:: 3.13
+
 Operator to read cache variables.
 
 Use the syntax ``$CACHE{VAR}`` to read cache entry ``VAR``.
diff --git a/Help/variable/CMAKE_AIX_EXPORT_ALL_SYMBOLS.rst b/Help/variable/CMAKE_AIX_EXPORT_ALL_SYMBOLS.rst
index c64dd48..699fe0f 100644
--- a/Help/variable/CMAKE_AIX_EXPORT_ALL_SYMBOLS.rst
+++ b/Help/variable/CMAKE_AIX_EXPORT_ALL_SYMBOLS.rst
@@ -1,6 +1,8 @@
 CMAKE_AIX_EXPORT_ALL_SYMBOLS
 ----------------------------
 
+.. versionadded:: 3.17
+
 Default value for :prop_tgt:`AIX_EXPORT_ALL_SYMBOLS` target property.
 This variable is used to initialize the property on each target as it is
 created.
diff --git a/Help/variable/CMAKE_ANDROID_ANT_ADDITIONAL_OPTIONS.rst b/Help/variable/CMAKE_ANDROID_ANT_ADDITIONAL_OPTIONS.rst
index 8862ba9..2d6b4b9 100644
--- a/Help/variable/CMAKE_ANDROID_ANT_ADDITIONAL_OPTIONS.rst
+++ b/Help/variable/CMAKE_ANDROID_ANT_ADDITIONAL_OPTIONS.rst
@@ -1,5 +1,7 @@
 CMAKE_ANDROID_ANT_ADDITIONAL_OPTIONS
 ------------------------------------
 
+.. versionadded:: 3.4
+
 Default value for the :prop_tgt:`ANDROID_ANT_ADDITIONAL_OPTIONS` target property.
 See that target property for additional information.
diff --git a/Help/variable/CMAKE_ANDROID_API.rst b/Help/variable/CMAKE_ANDROID_API.rst
index c07a05a..4388bf2 100644
--- a/Help/variable/CMAKE_ANDROID_API.rst
+++ b/Help/variable/CMAKE_ANDROID_API.rst
@@ -1,6 +1,8 @@
 CMAKE_ANDROID_API
 -----------------
 
+.. versionadded:: 3.1
+
 When :ref:`Cross Compiling for Android with NVIDIA Nsight Tegra Visual Studio
 Edition`, this variable may be set to specify the default value for the
 :prop_tgt:`ANDROID_API` target property.  See that target property for
diff --git a/Help/variable/CMAKE_ANDROID_API_MIN.rst b/Help/variable/CMAKE_ANDROID_API_MIN.rst
index 0246c75..a0d2ab4 100644
--- a/Help/variable/CMAKE_ANDROID_API_MIN.rst
+++ b/Help/variable/CMAKE_ANDROID_API_MIN.rst
@@ -1,5 +1,7 @@
 CMAKE_ANDROID_API_MIN
 ---------------------
 
+.. versionadded:: 3.2
+
 Default value for the :prop_tgt:`ANDROID_API_MIN` target property.
 See that target property for additional information.
diff --git a/Help/variable/CMAKE_ANDROID_ARCH.rst b/Help/variable/CMAKE_ANDROID_ARCH.rst
index b91ca57..9f12742 100644
--- a/Help/variable/CMAKE_ANDROID_ARCH.rst
+++ b/Help/variable/CMAKE_ANDROID_ARCH.rst
@@ -1,6 +1,8 @@
 CMAKE_ANDROID_ARCH
 ------------------
 
+.. versionadded:: 3.4
+
 When :ref:`Cross Compiling for Android with NVIDIA Nsight Tegra Visual Studio
 Edition`, this variable may be set to specify the default value for the
 :prop_tgt:`ANDROID_ARCH` target property.  See that target property for
diff --git a/Help/variable/CMAKE_ANDROID_ARCH_ABI.rst b/Help/variable/CMAKE_ANDROID_ARCH_ABI.rst
index 0a3ed3c..5a2e3ec 100644
--- a/Help/variable/CMAKE_ANDROID_ARCH_ABI.rst
+++ b/Help/variable/CMAKE_ANDROID_ARCH_ABI.rst
@@ -1,6 +1,8 @@
 CMAKE_ANDROID_ARCH_ABI
 ----------------------
 
+.. versionadded:: 3.7
+
 When :ref:`Cross Compiling for Android`, this variable specifies the
 target architecture and ABI to be used.  Valid values are:
 
diff --git a/Help/variable/CMAKE_ANDROID_ARM_MODE.rst b/Help/variable/CMAKE_ANDROID_ARM_MODE.rst
index ad3c37c..973ff7e 100644
--- a/Help/variable/CMAKE_ANDROID_ARM_MODE.rst
+++ b/Help/variable/CMAKE_ANDROID_ARM_MODE.rst
@@ -1,6 +1,8 @@
 CMAKE_ANDROID_ARM_MODE
 ----------------------
 
+.. versionadded:: 3.7
+
 When :ref:`Cross Compiling for Android` and :variable:`CMAKE_ANDROID_ARCH_ABI`
 is set to one of the ``armeabi`` architectures, set ``CMAKE_ANDROID_ARM_MODE``
 to ``ON`` to target 32-bit ARM processors (``-marm``).  Otherwise, the
diff --git a/Help/variable/CMAKE_ANDROID_ARM_NEON.rst b/Help/variable/CMAKE_ANDROID_ARM_NEON.rst
index 4b7ae03..6b9cf08 100644
--- a/Help/variable/CMAKE_ANDROID_ARM_NEON.rst
+++ b/Help/variable/CMAKE_ANDROID_ARM_NEON.rst
@@ -1,6 +1,8 @@
 CMAKE_ANDROID_ARM_NEON
 ----------------------
 
+.. versionadded:: 3.7
+
 When :ref:`Cross Compiling for Android` and :variable:`CMAKE_ANDROID_ARCH_ABI`
 is set to ``armeabi-v7a`` set ``CMAKE_ANDROID_ARM_NEON`` to ``ON`` to target
 ARM NEON devices.
diff --git a/Help/variable/CMAKE_ANDROID_ASSETS_DIRECTORIES.rst b/Help/variable/CMAKE_ANDROID_ASSETS_DIRECTORIES.rst
index c372fe4..3de2be4 100644
--- a/Help/variable/CMAKE_ANDROID_ASSETS_DIRECTORIES.rst
+++ b/Help/variable/CMAKE_ANDROID_ASSETS_DIRECTORIES.rst
@@ -1,5 +1,7 @@
 CMAKE_ANDROID_ASSETS_DIRECTORIES
 --------------------------------
 
+.. versionadded:: 3.4
+
 Default value for the :prop_tgt:`ANDROID_ASSETS_DIRECTORIES` target property.
 See that target property for additional information.
diff --git a/Help/variable/CMAKE_ANDROID_GUI.rst b/Help/variable/CMAKE_ANDROID_GUI.rst
index 1755375..821bbee 100644
--- a/Help/variable/CMAKE_ANDROID_GUI.rst
+++ b/Help/variable/CMAKE_ANDROID_GUI.rst
@@ -1,5 +1,7 @@
 CMAKE_ANDROID_GUI
 -----------------
 
+.. versionadded:: 3.1
+
 Default value for the :prop_tgt:`ANDROID_GUI` target property of
 executables.  See that target property for additional information.
diff --git a/Help/variable/CMAKE_ANDROID_JAR_DEPENDENCIES.rst b/Help/variable/CMAKE_ANDROID_JAR_DEPENDENCIES.rst
index 451a929..80ab842 100644
--- a/Help/variable/CMAKE_ANDROID_JAR_DEPENDENCIES.rst
+++ b/Help/variable/CMAKE_ANDROID_JAR_DEPENDENCIES.rst
@@ -1,5 +1,7 @@
 CMAKE_ANDROID_JAR_DEPENDENCIES
 ------------------------------
 
+.. versionadded:: 3.4
+
 Default value for the :prop_tgt:`ANDROID_JAR_DEPENDENCIES` target property.
 See that target property for additional information.
diff --git a/Help/variable/CMAKE_ANDROID_JAR_DIRECTORIES.rst b/Help/variable/CMAKE_ANDROID_JAR_DIRECTORIES.rst
index af83e34..4d148d8 100644
--- a/Help/variable/CMAKE_ANDROID_JAR_DIRECTORIES.rst
+++ b/Help/variable/CMAKE_ANDROID_JAR_DIRECTORIES.rst
@@ -1,5 +1,7 @@
 CMAKE_ANDROID_JAR_DIRECTORIES
 -----------------------------
 
+.. versionadded:: 3.4
+
 Default value for the :prop_tgt:`ANDROID_JAR_DIRECTORIES` target property.
 See that target property for additional information.
diff --git a/Help/variable/CMAKE_ANDROID_JAVA_SOURCE_DIR.rst b/Help/variable/CMAKE_ANDROID_JAVA_SOURCE_DIR.rst
index 3dc05e0..021baa0 100644
--- a/Help/variable/CMAKE_ANDROID_JAVA_SOURCE_DIR.rst
+++ b/Help/variable/CMAKE_ANDROID_JAVA_SOURCE_DIR.rst
@@ -1,5 +1,7 @@
 CMAKE_ANDROID_JAVA_SOURCE_DIR
 -----------------------------
 
+.. versionadded:: 3.4
+
 Default value for the :prop_tgt:`ANDROID_JAVA_SOURCE_DIR` target property.
 See that target property for additional information.
diff --git a/Help/variable/CMAKE_ANDROID_NATIVE_LIB_DEPENDENCIES.rst b/Help/variable/CMAKE_ANDROID_NATIVE_LIB_DEPENDENCIES.rst
index 4191907..41d4cc3 100644
--- a/Help/variable/CMAKE_ANDROID_NATIVE_LIB_DEPENDENCIES.rst
+++ b/Help/variable/CMAKE_ANDROID_NATIVE_LIB_DEPENDENCIES.rst
@@ -1,5 +1,7 @@
 CMAKE_ANDROID_NATIVE_LIB_DEPENDENCIES
 -------------------------------------
 
+.. versionadded:: 3.4
+
 Default value for the :prop_tgt:`ANDROID_NATIVE_LIB_DEPENDENCIES` target
 property.  See that target property for additional information.
diff --git a/Help/variable/CMAKE_ANDROID_NATIVE_LIB_DIRECTORIES.rst b/Help/variable/CMAKE_ANDROID_NATIVE_LIB_DIRECTORIES.rst
index 7cb9527..e87547d 100644
--- a/Help/variable/CMAKE_ANDROID_NATIVE_LIB_DIRECTORIES.rst
+++ b/Help/variable/CMAKE_ANDROID_NATIVE_LIB_DIRECTORIES.rst
@@ -1,5 +1,7 @@
 CMAKE_ANDROID_NATIVE_LIB_DIRECTORIES
 ------------------------------------
 
+.. versionadded:: 3.4
+
 Default value for the :prop_tgt:`ANDROID_NATIVE_LIB_DIRECTORIES` target
 property.  See that target property for additional information.
diff --git a/Help/variable/CMAKE_ANDROID_NDK.rst b/Help/variable/CMAKE_ANDROID_NDK.rst
index d241dd0..72ac99e 100644
--- a/Help/variable/CMAKE_ANDROID_NDK.rst
+++ b/Help/variable/CMAKE_ANDROID_NDK.rst
@@ -1,6 +1,8 @@
 CMAKE_ANDROID_NDK
 -----------------
 
+.. versionadded:: 3.7
+
 When :ref:`Cross Compiling for Android with the NDK`, this variable holds
 the absolute path to the root directory of the NDK.  The directory must
 contain a ``platforms`` subdirectory holding the ``android-<api>``
diff --git a/Help/variable/CMAKE_ANDROID_NDK_DEPRECATED_HEADERS.rst b/Help/variable/CMAKE_ANDROID_NDK_DEPRECATED_HEADERS.rst
index 8ea1257..40a5c1a 100644
--- a/Help/variable/CMAKE_ANDROID_NDK_DEPRECATED_HEADERS.rst
+++ b/Help/variable/CMAKE_ANDROID_NDK_DEPRECATED_HEADERS.rst
@@ -1,6 +1,8 @@
 CMAKE_ANDROID_NDK_DEPRECATED_HEADERS
 ------------------------------------
 
+.. versionadded:: 3.9
+
 When :ref:`Cross Compiling for Android with the NDK`, this variable
 may be set to specify whether to use the deprecated per-api-level
 headers instead of the unified headers.
diff --git a/Help/variable/CMAKE_ANDROID_NDK_TOOLCHAIN_HOST_TAG.rst b/Help/variable/CMAKE_ANDROID_NDK_TOOLCHAIN_HOST_TAG.rst
index 207019a..9d61fa4 100644
--- a/Help/variable/CMAKE_ANDROID_NDK_TOOLCHAIN_HOST_TAG.rst
+++ b/Help/variable/CMAKE_ANDROID_NDK_TOOLCHAIN_HOST_TAG.rst
@@ -1,6 +1,8 @@
 CMAKE_ANDROID_NDK_TOOLCHAIN_HOST_TAG
 ------------------------------------
 
+.. versionadded:: 3.7.1
+
 When :ref:`Cross Compiling for Android with the NDK`, this variable
 provides the NDK's "host tag" used to construct the path to prebuilt
 toolchains that run on the host.
diff --git a/Help/variable/CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION.rst b/Help/variable/CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION.rst
index 22808e3..15fe18f 100644
--- a/Help/variable/CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION.rst
+++ b/Help/variable/CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION.rst
@@ -1,6 +1,8 @@
 CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION
 -----------------------------------
 
+.. versionadded:: 3.7
+
 When :ref:`Cross Compiling for Android with the NDK`, this variable
 may be set to specify the version of the toolchain to be used
 as the compiler.
diff --git a/Help/variable/CMAKE_ANDROID_PROCESS_MAX.rst b/Help/variable/CMAKE_ANDROID_PROCESS_MAX.rst
index 19fb527..be241c2 100644
--- a/Help/variable/CMAKE_ANDROID_PROCESS_MAX.rst
+++ b/Help/variable/CMAKE_ANDROID_PROCESS_MAX.rst
@@ -1,5 +1,7 @@
 CMAKE_ANDROID_PROCESS_MAX
 -------------------------
 
+.. versionadded:: 3.4
+
 Default value for the :prop_tgt:`ANDROID_PROCESS_MAX` target property.
 See that target property for additional information.
diff --git a/Help/variable/CMAKE_ANDROID_PROGUARD.rst b/Help/variable/CMAKE_ANDROID_PROGUARD.rst
index b8fdd46..bb001d3 100644
--- a/Help/variable/CMAKE_ANDROID_PROGUARD.rst
+++ b/Help/variable/CMAKE_ANDROID_PROGUARD.rst
@@ -1,5 +1,7 @@
 CMAKE_ANDROID_PROGUARD
 ----------------------
 
+.. versionadded:: 3.4
+
 Default value for the :prop_tgt:`ANDROID_PROGUARD` target property.
 See that target property for additional information.
diff --git a/Help/variable/CMAKE_ANDROID_PROGUARD_CONFIG_PATH.rst b/Help/variable/CMAKE_ANDROID_PROGUARD_CONFIG_PATH.rst
index 8dea009..6fd4067 100644
--- a/Help/variable/CMAKE_ANDROID_PROGUARD_CONFIG_PATH.rst
+++ b/Help/variable/CMAKE_ANDROID_PROGUARD_CONFIG_PATH.rst
@@ -1,5 +1,7 @@
 CMAKE_ANDROID_PROGUARD_CONFIG_PATH
 ----------------------------------
 
+.. versionadded:: 3.4
+
 Default value for the :prop_tgt:`ANDROID_PROGUARD_CONFIG_PATH` target property.
 See that target property for additional information.
diff --git a/Help/variable/CMAKE_ANDROID_SECURE_PROPS_PATH.rst b/Help/variable/CMAKE_ANDROID_SECURE_PROPS_PATH.rst
index 69a4d0b..9f5743e 100644
--- a/Help/variable/CMAKE_ANDROID_SECURE_PROPS_PATH.rst
+++ b/Help/variable/CMAKE_ANDROID_SECURE_PROPS_PATH.rst
@@ -1,5 +1,7 @@
 CMAKE_ANDROID_SECURE_PROPS_PATH
 -------------------------------
 
+.. versionadded:: 3.4
+
 Default value for the :prop_tgt:`ANDROID_SECURE_PROPS_PATH` target property.
 See that target property for additional information.
diff --git a/Help/variable/CMAKE_ANDROID_SKIP_ANT_STEP.rst b/Help/variable/CMAKE_ANDROID_SKIP_ANT_STEP.rst
index 0a96df9..588769b 100644
--- a/Help/variable/CMAKE_ANDROID_SKIP_ANT_STEP.rst
+++ b/Help/variable/CMAKE_ANDROID_SKIP_ANT_STEP.rst
@@ -1,5 +1,7 @@
 CMAKE_ANDROID_SKIP_ANT_STEP
 ---------------------------
 
+.. versionadded:: 3.4
+
 Default value for the :prop_tgt:`ANDROID_SKIP_ANT_STEP` target property.
 See that target property for additional information.
diff --git a/Help/variable/CMAKE_ANDROID_STANDALONE_TOOLCHAIN.rst b/Help/variable/CMAKE_ANDROID_STANDALONE_TOOLCHAIN.rst
index ea62cab..3ca89f5 100644
--- a/Help/variable/CMAKE_ANDROID_STANDALONE_TOOLCHAIN.rst
+++ b/Help/variable/CMAKE_ANDROID_STANDALONE_TOOLCHAIN.rst
@@ -1,6 +1,8 @@
 CMAKE_ANDROID_STANDALONE_TOOLCHAIN
 ----------------------------------
 
+.. versionadded:: 3.7
+
 When :ref:`Cross Compiling for Android with a Standalone Toolchain`, this
 variable holds the absolute path to the root directory of the toolchain.
 The specified directory must contain a ``sysroot`` subdirectory.
diff --git a/Help/variable/CMAKE_ANDROID_STL_TYPE.rst b/Help/variable/CMAKE_ANDROID_STL_TYPE.rst
index d174575..3778181 100644
--- a/Help/variable/CMAKE_ANDROID_STL_TYPE.rst
+++ b/Help/variable/CMAKE_ANDROID_STL_TYPE.rst
@@ -1,6 +1,8 @@
 CMAKE_ANDROID_STL_TYPE
 ----------------------
 
+.. versionadded:: 3.4
+
 When :ref:`Cross Compiling for Android with NVIDIA Nsight Tegra Visual Studio
 Edition`, this variable may be set to specify the default value for the
 :prop_tgt:`ANDROID_STL_TYPE` target property.  See that target property
diff --git a/Help/variable/CMAKE_ARCHIVE_OUTPUT_DIRECTORY_CONFIG.rst b/Help/variable/CMAKE_ARCHIVE_OUTPUT_DIRECTORY_CONFIG.rst
index 94c2b6e..d8bd82c 100644
--- a/Help/variable/CMAKE_ARCHIVE_OUTPUT_DIRECTORY_CONFIG.rst
+++ b/Help/variable/CMAKE_ARCHIVE_OUTPUT_DIRECTORY_CONFIG.rst
@@ -1,6 +1,8 @@
 CMAKE_ARCHIVE_OUTPUT_DIRECTORY_<CONFIG>
 ---------------------------------------
 
+.. versionadded:: 3.3
+
 Where to put all the :ref:`ARCHIVE <Archive Output Artifacts>`
 target files when built for a specific configuration.
 
diff --git a/Help/variable/CMAKE_AUTOGEN_ORIGIN_DEPENDS.rst b/Help/variable/CMAKE_AUTOGEN_ORIGIN_DEPENDS.rst
index 1398e78..c24e462 100644
--- a/Help/variable/CMAKE_AUTOGEN_ORIGIN_DEPENDS.rst
+++ b/Help/variable/CMAKE_AUTOGEN_ORIGIN_DEPENDS.rst
@@ -1,6 +1,8 @@
 CMAKE_AUTOGEN_ORIGIN_DEPENDS
 ----------------------------
 
+.. versionadded:: 3.14
+
 Switch for forwarding origin target dependencies to the corresponding
 ``_autogen`` targets.
 
diff --git a/Help/variable/CMAKE_AUTOGEN_PARALLEL.rst b/Help/variable/CMAKE_AUTOGEN_PARALLEL.rst
index dd9499a..2ada012 100644
--- a/Help/variable/CMAKE_AUTOGEN_PARALLEL.rst
+++ b/Help/variable/CMAKE_AUTOGEN_PARALLEL.rst
@@ -1,6 +1,8 @@
 CMAKE_AUTOGEN_PARALLEL
 ----------------------
 
+.. versionadded:: 3.11
+
 Number of parallel ``moc`` or ``uic`` processes to start when using
 :prop_tgt:`AUTOMOC` and :prop_tgt:`AUTOUIC`.
 
diff --git a/Help/variable/CMAKE_AUTOGEN_VERBOSE.rst b/Help/variable/CMAKE_AUTOGEN_VERBOSE.rst
index bad9cf2..f77ed6a 100644
--- a/Help/variable/CMAKE_AUTOGEN_VERBOSE.rst
+++ b/Help/variable/CMAKE_AUTOGEN_VERBOSE.rst
@@ -1,6 +1,8 @@
 CMAKE_AUTOGEN_VERBOSE
 ---------------------
 
+.. versionadded:: 3.13
+
 Sets the verbosity of :prop_tgt:`AUTOMOC`, :prop_tgt:`AUTOUIC` and
 :prop_tgt:`AUTORCC`.  A positive integer value or a true boolean value
 lets the ``AUTO*`` generators output additional processing information.
diff --git a/Help/variable/CMAKE_AUTOMOC_COMPILER_PREDEFINES.rst b/Help/variable/CMAKE_AUTOMOC_COMPILER_PREDEFINES.rst
index 7e1c53d..f1b03a0 100644
--- a/Help/variable/CMAKE_AUTOMOC_COMPILER_PREDEFINES.rst
+++ b/Help/variable/CMAKE_AUTOMOC_COMPILER_PREDEFINES.rst
@@ -1,6 +1,8 @@
 CMAKE_AUTOMOC_COMPILER_PREDEFINES
 ---------------------------------
 
+.. versionadded:: 3.10
+
 This variable is used to initialize the :prop_tgt:`AUTOMOC_COMPILER_PREDEFINES`
 property on all the targets. See that target property for additional
 information.
diff --git a/Help/variable/CMAKE_AUTOMOC_DEPEND_FILTERS.rst b/Help/variable/CMAKE_AUTOMOC_DEPEND_FILTERS.rst
index 5c3662d..2c1551a 100644
--- a/Help/variable/CMAKE_AUTOMOC_DEPEND_FILTERS.rst
+++ b/Help/variable/CMAKE_AUTOMOC_DEPEND_FILTERS.rst
@@ -1,6 +1,8 @@
 CMAKE_AUTOMOC_DEPEND_FILTERS
 ----------------------------
 
+.. versionadded:: 3.9
+
 Filter definitions used by :variable:`CMAKE_AUTOMOC`
 to extract file names from source code as additional dependencies
 for the ``moc`` file.
diff --git a/Help/variable/CMAKE_AUTOMOC_MACRO_NAMES.rst b/Help/variable/CMAKE_AUTOMOC_MACRO_NAMES.rst
index ba1b9d2..8e34df2 100644
--- a/Help/variable/CMAKE_AUTOMOC_MACRO_NAMES.rst
+++ b/Help/variable/CMAKE_AUTOMOC_MACRO_NAMES.rst
@@ -1,6 +1,8 @@
 CMAKE_AUTOMOC_MACRO_NAMES
 ----------------------------
 
+.. versionadded:: 3.10
+
 :ref:`Semicolon-separated list <CMake Language Lists>` list of macro names used by
 :variable:`CMAKE_AUTOMOC` to determine if a C++ file needs to be
 processed by ``moc``.
diff --git a/Help/variable/CMAKE_AUTOMOC_PATH_PREFIX.rst b/Help/variable/CMAKE_AUTOMOC_PATH_PREFIX.rst
index 1e9790f..42f48b4 100644
--- a/Help/variable/CMAKE_AUTOMOC_PATH_PREFIX.rst
+++ b/Help/variable/CMAKE_AUTOMOC_PATH_PREFIX.rst
@@ -1,6 +1,8 @@
 CMAKE_AUTOMOC_PATH_PREFIX
 -------------------------
 
+.. versionadded:: 3.16
+
 Whether to generate the ``-p`` path prefix option for ``moc`` on
 :prop_tgt:`AUTOMOC` enabled Qt targets.
 
diff --git a/Help/variable/CMAKE_AUTOUIC_SEARCH_PATHS.rst b/Help/variable/CMAKE_AUTOUIC_SEARCH_PATHS.rst
index aa132bf..0262368 100644
--- a/Help/variable/CMAKE_AUTOUIC_SEARCH_PATHS.rst
+++ b/Help/variable/CMAKE_AUTOUIC_SEARCH_PATHS.rst
@@ -1,6 +1,8 @@
 CMAKE_AUTOUIC_SEARCH_PATHS
 --------------------------
 
+.. versionadded:: 3.9
+
 Search path list used by :variable:`CMAKE_AUTOUIC` to find included
 ``.ui`` files.
 
diff --git a/Help/variable/CMAKE_BUILD_RPATH.rst b/Help/variable/CMAKE_BUILD_RPATH.rst
index f5d53b8..7a8ace7 100644
--- a/Help/variable/CMAKE_BUILD_RPATH.rst
+++ b/Help/variable/CMAKE_BUILD_RPATH.rst
@@ -1,6 +1,8 @@
 CMAKE_BUILD_RPATH
 -----------------
 
+.. versionadded:: 3.8
+
 :ref:`Semicolon-separated list <CMake Language Lists>` specifying runtime path (``RPATH``)
 entries to add to binaries linked in the build tree (for platforms that
 support it).  The entries will *not* be used for binaries in the install
diff --git a/Help/variable/CMAKE_BUILD_RPATH_USE_ORIGIN.rst b/Help/variable/CMAKE_BUILD_RPATH_USE_ORIGIN.rst
index e34ede6..ecd9278 100644
--- a/Help/variable/CMAKE_BUILD_RPATH_USE_ORIGIN.rst
+++ b/Help/variable/CMAKE_BUILD_RPATH_USE_ORIGIN.rst
@@ -1,6 +1,8 @@
 CMAKE_BUILD_RPATH_USE_ORIGIN
 ----------------------------
 
+.. versionadded:: 3.14
+
 Whether to use relative paths for the build ``RPATH``.
 
 This is used to initialize the :prop_tgt:`BUILD_RPATH_USE_ORIGIN` target
diff --git a/Help/variable/CMAKE_BUILD_WITH_INSTALL_NAME_DIR.rst b/Help/variable/CMAKE_BUILD_WITH_INSTALL_NAME_DIR.rst
index 30d5d3b..5ba775c 100644
--- a/Help/variable/CMAKE_BUILD_WITH_INSTALL_NAME_DIR.rst
+++ b/Help/variable/CMAKE_BUILD_WITH_INSTALL_NAME_DIR.rst
@@ -1,6 +1,8 @@
 CMAKE_BUILD_WITH_INSTALL_NAME_DIR
 ---------------------------------
 
+.. versionadded:: 3.9
+
 Whether to use :prop_tgt:`INSTALL_NAME_DIR` on targets in the build tree.
 
 This variable is used to initialize the :prop_tgt:`BUILD_WITH_INSTALL_NAME_DIR`
diff --git a/Help/variable/CMAKE_CLANG_VFS_OVERLAY.rst b/Help/variable/CMAKE_CLANG_VFS_OVERLAY.rst
new file mode 100644
index 0000000..56ac328
--- /dev/null
+++ b/Help/variable/CMAKE_CLANG_VFS_OVERLAY.rst
@@ -0,0 +1,9 @@
+CMAKE_CLANG_VFS_OVERLAY
+-----------------------
+
+.. versionadded:: 3.19
+
+When cross compiling for windows with clang-cl, this variable can be an
+absolute path pointing to a clang virtual file system yaml file, which
+will enable clang-cl to resolve windows header names on a case sensitive
+file system.
diff --git a/Help/variable/CMAKE_CODEBLOCKS_COMPILER_ID.rst b/Help/variable/CMAKE_CODEBLOCKS_COMPILER_ID.rst
index ad2709d..0b2b0a0 100644
--- a/Help/variable/CMAKE_CODEBLOCKS_COMPILER_ID.rst
+++ b/Help/variable/CMAKE_CODEBLOCKS_COMPILER_ID.rst
@@ -1,6 +1,8 @@
 CMAKE_CODEBLOCKS_COMPILER_ID
 ----------------------------
 
+.. versionadded:: 3.11
+
 Change the compiler id in the generated CodeBlocks project files.
 
 CodeBlocks uses its own compiler id string which differs from
diff --git a/Help/variable/CMAKE_CODEBLOCKS_EXCLUDE_EXTERNAL_FILES.rst b/Help/variable/CMAKE_CODEBLOCKS_EXCLUDE_EXTERNAL_FILES.rst
index 80ffce3..dbb8606 100644
--- a/Help/variable/CMAKE_CODEBLOCKS_EXCLUDE_EXTERNAL_FILES.rst
+++ b/Help/variable/CMAKE_CODEBLOCKS_EXCLUDE_EXTERNAL_FILES.rst
@@ -1,6 +1,8 @@
 CMAKE_CODEBLOCKS_EXCLUDE_EXTERNAL_FILES
 ---------------------------------------
 
+.. versionadded:: 3.10
+
 Change the way the CodeBlocks generator creates project files.
 
 If this variable evaluates to ``ON`` the generator excludes from
diff --git a/Help/variable/CMAKE_CODELITE_USE_TARGETS.rst b/Help/variable/CMAKE_CODELITE_USE_TARGETS.rst
index 33cdf6c..21af5f7 100644
--- a/Help/variable/CMAKE_CODELITE_USE_TARGETS.rst
+++ b/Help/variable/CMAKE_CODELITE_USE_TARGETS.rst
@@ -1,6 +1,8 @@
 CMAKE_CODELITE_USE_TARGETS
 --------------------------
 
+.. versionadded:: 3.7
+
 Change the way the CodeLite generator creates projectfiles.
 
 If this variable evaluates to ``ON`` at the end of the top-level
diff --git a/Help/variable/CMAKE_COMPILER_IS_GNUCC.rst b/Help/variable/CMAKE_COMPILER_IS_GNUCC.rst
index a40667e..91cf848 100644
--- a/Help/variable/CMAKE_COMPILER_IS_GNUCC.rst
+++ b/Help/variable/CMAKE_COMPILER_IS_GNUCC.rst
@@ -1,5 +1,7 @@
 CMAKE_COMPILER_IS_GNUCC
 -----------------------
 
+.. versionadded:: 3.7
+
 True if the ``C`` compiler is GNU.
 Use :variable:`CMAKE_C_COMPILER_ID <CMAKE_<LANG>_COMPILER_ID>` instead.
diff --git a/Help/variable/CMAKE_COMPILER_IS_GNUCXX.rst b/Help/variable/CMAKE_COMPILER_IS_GNUCXX.rst
index f1f5cf7..e67718a 100644
--- a/Help/variable/CMAKE_COMPILER_IS_GNUCXX.rst
+++ b/Help/variable/CMAKE_COMPILER_IS_GNUCXX.rst
@@ -1,5 +1,7 @@
 CMAKE_COMPILER_IS_GNUCXX
 ------------------------
 
+.. versionadded:: 3.7
+
 True if the C++ (``CXX``) compiler is GNU.
 Use :variable:`CMAKE_CXX_COMPILER_ID <CMAKE_<LANG>_COMPILER_ID>` instead.
diff --git a/Help/variable/CMAKE_COMPILER_IS_GNUG77.rst b/Help/variable/CMAKE_COMPILER_IS_GNUG77.rst
index 3d6dab4..f69c01a 100644
--- a/Help/variable/CMAKE_COMPILER_IS_GNUG77.rst
+++ b/Help/variable/CMAKE_COMPILER_IS_GNUG77.rst
@@ -1,5 +1,7 @@
 CMAKE_COMPILER_IS_GNUG77
 ------------------------
 
+.. versionadded:: 3.7
+
 True if the ``Fortran`` compiler is GNU.
 Use :variable:`CMAKE_Fortran_COMPILER_ID <CMAKE_<LANG>_COMPILER_ID>` instead.
diff --git a/Help/variable/CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY.rst b/Help/variable/CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY.rst
index ea33c7d..11f52c7 100644
--- a/Help/variable/CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY.rst
+++ b/Help/variable/CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY.rst
@@ -1,6 +1,8 @@
 CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY
 ----------------------------------
 
+.. versionadded:: 3.1
+
 Output directory for MS debug symbol ``.pdb`` files
 generated by the compiler while building source files.
 
diff --git a/Help/variable/CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY_CONFIG.rst b/Help/variable/CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY_CONFIG.rst
index fdeb9ab..99d0bdc 100644
--- a/Help/variable/CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY_CONFIG.rst
+++ b/Help/variable/CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY_CONFIG.rst
@@ -1,6 +1,8 @@
 CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY_<CONFIG>
 -------------------------------------------
 
+.. versionadded:: 3.1
+
 Per-configuration output directory for MS debug symbol ``.pdb`` files
 generated by the compiler while building source files.
 
diff --git a/Help/variable/CMAKE_CPACK_COMMAND.rst b/Help/variable/CMAKE_CPACK_COMMAND.rst
index 559108a..3a81d68 100644
--- a/Help/variable/CMAKE_CPACK_COMMAND.rst
+++ b/Help/variable/CMAKE_CPACK_COMMAND.rst
@@ -1,6 +1,8 @@
 CMAKE_CPACK_COMMAND
 -------------------
 
+.. versionadded:: 3.13
+
 Full path to :manual:`cpack(1)` command installed with CMake.
 
 This is the full path to the CPack executable :manual:`cpack(1)` which is
diff --git a/Help/variable/CMAKE_CROSSCOMPILING_EMULATOR.rst b/Help/variable/CMAKE_CROSSCOMPILING_EMULATOR.rst
index 1d013b7..815da00 100644
--- a/Help/variable/CMAKE_CROSSCOMPILING_EMULATOR.rst
+++ b/Help/variable/CMAKE_CROSSCOMPILING_EMULATOR.rst
@@ -1,6 +1,8 @@
 CMAKE_CROSSCOMPILING_EMULATOR
 -----------------------------
 
+.. versionadded:: 3.3
+
 This variable is only used when :variable:`CMAKE_CROSSCOMPILING` is on. It
 should point to a command on the host system that can run executable built
 for the target system.
diff --git a/Help/variable/CMAKE_CROSS_CONFIGS.rst b/Help/variable/CMAKE_CROSS_CONFIGS.rst
index 94157f3..be921d6 100644
--- a/Help/variable/CMAKE_CROSS_CONFIGS.rst
+++ b/Help/variable/CMAKE_CROSS_CONFIGS.rst
@@ -1,6 +1,8 @@
 CMAKE_CROSS_CONFIGS
 -------------------
 
+.. versionadded:: 3.17
+
 Specifies a :ref:`semicolon-separated list <CMake Language Lists>` of
 configurations available from all ``build-<Config>.ninja`` files in the
 :generator:`Ninja Multi-Config` generator.  This variable activates
diff --git a/Help/variable/CMAKE_CTEST_ARGUMENTS.rst b/Help/variable/CMAKE_CTEST_ARGUMENTS.rst
index 0940b46..4dfc8fe 100644
--- a/Help/variable/CMAKE_CTEST_ARGUMENTS.rst
+++ b/Help/variable/CMAKE_CTEST_ARGUMENTS.rst
@@ -1,6 +1,8 @@
 CMAKE_CTEST_ARGUMENTS
 ---------------------
 
+.. versionadded:: 3.17
+
 Set this to a :ref:`semicolon-separated list <CMake Language Lists>` of
 command-line arguments to pass to :manual:`ctest(1)` when running tests
 through the ``test`` (or ``RUN_TESTS``) target of the generated build system.
diff --git a/Help/variable/CMAKE_CUDA_ARCHITECTURES.rst b/Help/variable/CMAKE_CUDA_ARCHITECTURES.rst
index 149bffa..985040d 100644
--- a/Help/variable/CMAKE_CUDA_ARCHITECTURES.rst
+++ b/Help/variable/CMAKE_CUDA_ARCHITECTURES.rst
@@ -1,6 +1,8 @@
 CMAKE_CUDA_ARCHITECTURES
 ------------------------
 
+.. versionadded:: 3.18
+
 Default value for :prop_tgt:`CUDA_ARCHITECTURES` property of targets.
 
 This is initialized as follows depending on :variable:`CMAKE_CUDA_COMPILER_ID <CMAKE_<LANG>_COMPILER_ID>`:
diff --git a/Help/variable/CMAKE_CUDA_COMPILE_FEATURES.rst b/Help/variable/CMAKE_CUDA_COMPILE_FEATURES.rst
index 2cd2650..c1c270c 100644
--- a/Help/variable/CMAKE_CUDA_COMPILE_FEATURES.rst
+++ b/Help/variable/CMAKE_CUDA_COMPILE_FEATURES.rst
@@ -1,6 +1,8 @@
 CMAKE_CUDA_COMPILE_FEATURES
 ---------------------------
 
+.. versionadded:: 3.17
+
 List of features known to the CUDA compiler
 
 These features are known to be available for use with the CUDA compiler. This
diff --git a/Help/variable/CMAKE_CUDA_EXTENSIONS.rst b/Help/variable/CMAKE_CUDA_EXTENSIONS.rst
index 4fe758e..b86c0ea 100644
--- a/Help/variable/CMAKE_CUDA_EXTENSIONS.rst
+++ b/Help/variable/CMAKE_CUDA_EXTENSIONS.rst
@@ -1,6 +1,8 @@
 CMAKE_CUDA_EXTENSIONS
 ---------------------
 
+.. versionadded:: 3.8
+
 Default value for :prop_tgt:`CUDA_EXTENSIONS` property of targets.
 
 This variable is used to initialize the :prop_tgt:`CUDA_EXTENSIONS`
diff --git a/Help/variable/CMAKE_CUDA_HOST_COMPILER.rst b/Help/variable/CMAKE_CUDA_HOST_COMPILER.rst
index 6d34c5c..07342b5 100644
--- a/Help/variable/CMAKE_CUDA_HOST_COMPILER.rst
+++ b/Help/variable/CMAKE_CUDA_HOST_COMPILER.rst
@@ -1,8 +1,25 @@
 CMAKE_CUDA_HOST_COMPILER
 ------------------------
 
-Executable to use when compiling host code when compiling ``CUDA`` language
-files. Maps to the ``nvcc -ccbin`` option.  Will only be used by CMake on the first
-configuration to determine a valid host compiler for ``CUDA``. After a valid
-host compiler has been found, this value is read-only.  This variable takes
-priority over the :envvar:`CUDAHOSTCXX` environment variable.
+.. versionadded:: 3.10
+
+When :variable:`CMAKE_CUDA_COMPILER <CMAKE_<LANG>_COMPILER>` is set to
+NVIDIA ``nvcc``, ``CMAKE_CUDA_HOST_COMPILER`` selects the compiler
+executable to use when compiling host code for ``CUDA`` language files.
+This maps to the ``nvcc -ccbin`` option.
+
+The ``CMAKE_CUDA_HOST_COMPILER`` variable may be set explicitly before CUDA is
+first enabled by a :command:`project` or :command:`enable_language` command.
+This can be done via ``-DCMAKE_CUDA_HOST_COMPILER=...`` on the command line
+or in a :ref:`toolchain file <Cross Compiling Toolchain>`.  Or, one may set
+the :envvar:`CUDAHOSTCXX` environment variable to provide a default value.
+
+Once the CUDA language is enabled, the ``CMAKE_CUDA_HOST_COMPILER`` variable
+is read-only and changes to it are undefined behavior.
+
+.. note::
+
+  Since ``CMAKE_CUDA_HOST_COMPILER`` is meaningful only when the
+  ``CMAKE_CUDA_COMPILER`` is ``nvcc``, it does not make sense to
+  set ``CMAKE_CUDA_HOST_COMPILER`` explicitly without also setting
+  ``CMAKE_CUDA_COMPILER`` explicitly to be sure it is ``nvcc``.
diff --git a/Help/variable/CMAKE_CUDA_RESOLVE_DEVICE_SYMBOLS.rst b/Help/variable/CMAKE_CUDA_RESOLVE_DEVICE_SYMBOLS.rst
index fc835cd..474baee 100644
--- a/Help/variable/CMAKE_CUDA_RESOLVE_DEVICE_SYMBOLS.rst
+++ b/Help/variable/CMAKE_CUDA_RESOLVE_DEVICE_SYMBOLS.rst
@@ -1,6 +1,8 @@
 CMAKE_CUDA_RESOLVE_DEVICE_SYMBOLS
 ---------------------------------
 
+.. versionadded:: 3.16
+
 Default value for :prop_tgt:`CUDA_RESOLVE_DEVICE_SYMBOLS` target
 property. This variable is used to initialize the property on each target as
 it is created.
diff --git a/Help/variable/CMAKE_CUDA_RUNTIME_LIBRARY.rst b/Help/variable/CMAKE_CUDA_RUNTIME_LIBRARY.rst
index e3205d3..69b9d93 100644
--- a/Help/variable/CMAKE_CUDA_RUNTIME_LIBRARY.rst
+++ b/Help/variable/CMAKE_CUDA_RUNTIME_LIBRARY.rst
@@ -1,6 +1,8 @@
 CMAKE_CUDA_RUNTIME_LIBRARY
 --------------------------
 
+.. versionadded:: 3.17
+
 Select the CUDA runtime library for use when compiling and linking CUDA.
 This variable is used to initialize the :prop_tgt:`CUDA_RUNTIME_LIBRARY`
 property on all targets as they are created.
diff --git a/Help/variable/CMAKE_CUDA_SEPARABLE_COMPILATION.rst b/Help/variable/CMAKE_CUDA_SEPARABLE_COMPILATION.rst
index eef92fb..3dbaef9 100644
--- a/Help/variable/CMAKE_CUDA_SEPARABLE_COMPILATION.rst
+++ b/Help/variable/CMAKE_CUDA_SEPARABLE_COMPILATION.rst
@@ -1,6 +1,8 @@
 CMAKE_CUDA_SEPARABLE_COMPILATION
 --------------------------------
 
+.. versionadded:: 3.11
+
 Default value for :prop_tgt:`CUDA_SEPARABLE_COMPILATION` target property.
 This variable is used to initialize the property on each target as it is
 created.
diff --git a/Help/variable/CMAKE_CUDA_STANDARD.rst b/Help/variable/CMAKE_CUDA_STANDARD.rst
index 6c23031..798ab1e 100644
--- a/Help/variable/CMAKE_CUDA_STANDARD.rst
+++ b/Help/variable/CMAKE_CUDA_STANDARD.rst
@@ -1,6 +1,8 @@
 CMAKE_CUDA_STANDARD
 -------------------
 
+.. versionadded:: 3.8
+
 Default value for :prop_tgt:`CUDA_STANDARD` property of targets.
 
 This variable is used to initialize the :prop_tgt:`CUDA_STANDARD`
diff --git a/Help/variable/CMAKE_CUDA_STANDARD_REQUIRED.rst b/Help/variable/CMAKE_CUDA_STANDARD_REQUIRED.rst
index 935d605..ae2f52f 100644
--- a/Help/variable/CMAKE_CUDA_STANDARD_REQUIRED.rst
+++ b/Help/variable/CMAKE_CUDA_STANDARD_REQUIRED.rst
@@ -1,6 +1,8 @@
 CMAKE_CUDA_STANDARD_REQUIRED
 ----------------------------
 
+.. versionadded:: 3.8
+
 Default value for :prop_tgt:`CUDA_STANDARD_REQUIRED` property of targets.
 
 This variable is used to initialize the :prop_tgt:`CUDA_STANDARD_REQUIRED`
diff --git a/Help/variable/CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES.rst b/Help/variable/CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES.rst
index 7de50a5..e586dab 100644
--- a/Help/variable/CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES.rst
+++ b/Help/variable/CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES.rst
@@ -1,6 +1,8 @@
 CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES
 --------------------------------------
 
+.. versionadded:: 3.8
+
 When the ``CUDA`` language has been enabled, this provides a
 :ref:`semicolon-separated list <CMake Language Lists>` of include directories provided
 by the CUDA Toolkit.  The value may be useful for C++ source files
diff --git a/Help/variable/CMAKE_CURRENT_FUNCTION.rst b/Help/variable/CMAKE_CURRENT_FUNCTION.rst
index fb7f610..5d1a4e9 100644
--- a/Help/variable/CMAKE_CURRENT_FUNCTION.rst
+++ b/Help/variable/CMAKE_CURRENT_FUNCTION.rst
@@ -1,6 +1,8 @@
 CMAKE_CURRENT_FUNCTION
 ----------------------
 
+.. versionadded:: 3.17
+
 When executing code inside a :command:`function`, this variable
 contains the name of the current function.  It can be useful for
 diagnostic or debug messages.
diff --git a/Help/variable/CMAKE_CURRENT_FUNCTION_LIST_DIR.rst b/Help/variable/CMAKE_CURRENT_FUNCTION_LIST_DIR.rst
index 44ae1e5..f8f553d 100644
--- a/Help/variable/CMAKE_CURRENT_FUNCTION_LIST_DIR.rst
+++ b/Help/variable/CMAKE_CURRENT_FUNCTION_LIST_DIR.rst
@@ -1,6 +1,8 @@
 CMAKE_CURRENT_FUNCTION_LIST_DIR
 -------------------------------
 
+.. versionadded:: 3.17
+
 When executing code inside a :command:`function`, this variable
 contains the full directory of the listfile that defined the current function.
 
diff --git a/Help/variable/CMAKE_CURRENT_FUNCTION_LIST_FILE.rst b/Help/variable/CMAKE_CURRENT_FUNCTION_LIST_FILE.rst
index c737af9..437dfec 100644
--- a/Help/variable/CMAKE_CURRENT_FUNCTION_LIST_FILE.rst
+++ b/Help/variable/CMAKE_CURRENT_FUNCTION_LIST_FILE.rst
@@ -1,6 +1,8 @@
 CMAKE_CURRENT_FUNCTION_LIST_FILE
 --------------------------------
 
+.. versionadded:: 3.17
+
 When executing code inside a :command:`function`, this variable
 contains the full path to the listfile that defined the current function.
 
diff --git a/Help/variable/CMAKE_CURRENT_FUNCTION_LIST_LINE.rst b/Help/variable/CMAKE_CURRENT_FUNCTION_LIST_LINE.rst
index ad6282e..2fc7012 100644
--- a/Help/variable/CMAKE_CURRENT_FUNCTION_LIST_LINE.rst
+++ b/Help/variable/CMAKE_CURRENT_FUNCTION_LIST_LINE.rst
@@ -1,6 +1,8 @@
 CMAKE_CURRENT_FUNCTION_LIST_LINE
 --------------------------------
 
+.. versionadded:: 3.17
+
 When executing code inside a :command:`function`, this variable
 contains the line number in the listfile where the current function
 was defined.
diff --git a/Help/variable/CMAKE_CXX_COMPILE_FEATURES.rst b/Help/variable/CMAKE_CXX_COMPILE_FEATURES.rst
index 5c59f95..8fcfbae 100644
--- a/Help/variable/CMAKE_CXX_COMPILE_FEATURES.rst
+++ b/Help/variable/CMAKE_CXX_COMPILE_FEATURES.rst
@@ -1,6 +1,8 @@
 CMAKE_CXX_COMPILE_FEATURES
 --------------------------
 
+.. versionadded:: 3.1
+
 List of features known to the C++ compiler
 
 These features are known to be available for use with the C++ compiler. This
diff --git a/Help/variable/CMAKE_CXX_EXTENSIONS.rst b/Help/variable/CMAKE_CXX_EXTENSIONS.rst
index 4a92425..ea8c4be 100644
--- a/Help/variable/CMAKE_CXX_EXTENSIONS.rst
+++ b/Help/variable/CMAKE_CXX_EXTENSIONS.rst
@@ -1,6 +1,8 @@
 CMAKE_CXX_EXTENSIONS
 --------------------
 
+.. versionadded:: 3.1
+
 Default value for :prop_tgt:`CXX_EXTENSIONS` property of targets.
 
 This variable is used to initialize the :prop_tgt:`CXX_EXTENSIONS`
diff --git a/Help/variable/CMAKE_CXX_STANDARD.rst b/Help/variable/CMAKE_CXX_STANDARD.rst
index 8a8bdff..8ef8c80 100644
--- a/Help/variable/CMAKE_CXX_STANDARD.rst
+++ b/Help/variable/CMAKE_CXX_STANDARD.rst
@@ -1,6 +1,8 @@
 CMAKE_CXX_STANDARD
 ------------------
 
+.. versionadded:: 3.1
+
 Default value for :prop_tgt:`CXX_STANDARD` property of targets.
 
 This variable is used to initialize the :prop_tgt:`CXX_STANDARD`
diff --git a/Help/variable/CMAKE_CXX_STANDARD_REQUIRED.rst b/Help/variable/CMAKE_CXX_STANDARD_REQUIRED.rst
index 4c71058..f7b2ae9 100644
--- a/Help/variable/CMAKE_CXX_STANDARD_REQUIRED.rst
+++ b/Help/variable/CMAKE_CXX_STANDARD_REQUIRED.rst
@@ -1,6 +1,8 @@
 CMAKE_CXX_STANDARD_REQUIRED
 ---------------------------
 
+.. versionadded:: 3.1
+
 Default value for :prop_tgt:`CXX_STANDARD_REQUIRED` property of targets.
 
 This variable is used to initialize the :prop_tgt:`CXX_STANDARD_REQUIRED`
diff --git a/Help/variable/CMAKE_C_COMPILE_FEATURES.rst b/Help/variable/CMAKE_C_COMPILE_FEATURES.rst
index 8d1eca0..2b306a3 100644
--- a/Help/variable/CMAKE_C_COMPILE_FEATURES.rst
+++ b/Help/variable/CMAKE_C_COMPILE_FEATURES.rst
@@ -1,6 +1,8 @@
 CMAKE_C_COMPILE_FEATURES
 ------------------------
 
+.. versionadded:: 3.1
+
 List of features known to the C compiler
 
 These features are known to be available for use with the C compiler. This
diff --git a/Help/variable/CMAKE_C_EXTENSIONS.rst b/Help/variable/CMAKE_C_EXTENSIONS.rst
index fa510d4..fce8fc7 100644
--- a/Help/variable/CMAKE_C_EXTENSIONS.rst
+++ b/Help/variable/CMAKE_C_EXTENSIONS.rst
@@ -1,6 +1,8 @@
 CMAKE_C_EXTENSIONS
 ------------------
 
+.. versionadded:: 3.1
+
 Default value for :prop_tgt:`C_EXTENSIONS` property of targets.
 
 This variable is used to initialize the :prop_tgt:`C_EXTENSIONS`
diff --git a/Help/variable/CMAKE_C_STANDARD.rst b/Help/variable/CMAKE_C_STANDARD.rst
index b55e00c..64ef8ce 100644
--- a/Help/variable/CMAKE_C_STANDARD.rst
+++ b/Help/variable/CMAKE_C_STANDARD.rst
@@ -1,6 +1,8 @@
 CMAKE_C_STANDARD
 ----------------
 
+.. versionadded:: 3.1
+
 Default value for :prop_tgt:`C_STANDARD` property of targets.
 
 This variable is used to initialize the :prop_tgt:`C_STANDARD`
diff --git a/Help/variable/CMAKE_C_STANDARD_REQUIRED.rst b/Help/variable/CMAKE_C_STANDARD_REQUIRED.rst
index 7f70f6e..e70b6bd 100644
--- a/Help/variable/CMAKE_C_STANDARD_REQUIRED.rst
+++ b/Help/variable/CMAKE_C_STANDARD_REQUIRED.rst
@@ -1,6 +1,8 @@
 CMAKE_C_STANDARD_REQUIRED
 -------------------------
 
+.. versionadded:: 3.1
+
 Default value for :prop_tgt:`C_STANDARD_REQUIRED` property of targets.
 
 This variable is used to initialize the :prop_tgt:`C_STANDARD_REQUIRED`
diff --git a/Help/variable/CMAKE_DEFAULT_BUILD_TYPE.rst b/Help/variable/CMAKE_DEFAULT_BUILD_TYPE.rst
index aa4f82d..cadbf3a 100644
--- a/Help/variable/CMAKE_DEFAULT_BUILD_TYPE.rst
+++ b/Help/variable/CMAKE_DEFAULT_BUILD_TYPE.rst
@@ -1,6 +1,8 @@
 CMAKE_DEFAULT_BUILD_TYPE
 ------------------------
 
+.. versionadded:: 3.17
+
 Specifies the configuration to use by default in a ``build.ninja`` file in the
 :generator:`Ninja Multi-Config` generator. If this variable is specified,
 ``build.ninja`` uses build rules from ``build-<Config>.ninja`` by default. All
diff --git a/Help/variable/CMAKE_DEFAULT_CONFIGS.rst b/Help/variable/CMAKE_DEFAULT_CONFIGS.rst
index 84c642a..65a5f0d 100644
--- a/Help/variable/CMAKE_DEFAULT_CONFIGS.rst
+++ b/Help/variable/CMAKE_DEFAULT_CONFIGS.rst
@@ -1,6 +1,8 @@
 CMAKE_DEFAULT_CONFIGS
 ---------------------
 
+.. versionadded:: 3.17
+
 Specifies a :ref:`semicolon-separated list <CMake Language Lists>` of configurations
 to build for a target in ``build.ninja`` if no ``:<Config>`` suffix is specified in
 the :generator:`Ninja Multi-Config` generator. If it is set to ``all``, all
diff --git a/Help/variable/CMAKE_DEPENDS_IN_PROJECT_ONLY.rst b/Help/variable/CMAKE_DEPENDS_IN_PROJECT_ONLY.rst
index 7179071..bfe9402 100644
--- a/Help/variable/CMAKE_DEPENDS_IN_PROJECT_ONLY.rst
+++ b/Help/variable/CMAKE_DEPENDS_IN_PROJECT_ONLY.rst
@@ -1,6 +1,8 @@
 CMAKE_DEPENDS_IN_PROJECT_ONLY
 -----------------------------
 
+.. versionadded:: 3.6
+
 When set to ``TRUE`` in a directory, the build system produced by the
 :ref:`Makefile Generators` is set up to only consider dependencies on source
 files that appear either in the source or in the binary directories.  Changes
diff --git a/Help/variable/CMAKE_DIRECTORY_LABELS.rst b/Help/variable/CMAKE_DIRECTORY_LABELS.rst
index 2a6c410..81d6dd1 100644
--- a/Help/variable/CMAKE_DIRECTORY_LABELS.rst
+++ b/Help/variable/CMAKE_DIRECTORY_LABELS.rst
@@ -1,6 +1,8 @@
 CMAKE_DIRECTORY_LABELS
 -----------------------
 
+.. versionadded:: 3.10
+
 Specify labels for the current directory.
 
 This is used to initialize the :prop_dir:`LABELS` directory property.
diff --git a/Help/variable/CMAKE_DISABLE_PRECOMPILE_HEADERS.rst b/Help/variable/CMAKE_DISABLE_PRECOMPILE_HEADERS.rst
index 7c30ede..cf52776 100644
--- a/Help/variable/CMAKE_DISABLE_PRECOMPILE_HEADERS.rst
+++ b/Help/variable/CMAKE_DISABLE_PRECOMPILE_HEADERS.rst
@@ -1,6 +1,8 @@
 CMAKE_DISABLE_PRECOMPILE_HEADERS
 --------------------------------
 
+.. versionadded:: 3.16
+
 Default value for :prop_tgt:`DISABLE_PRECOMPILE_HEADERS` of targets.
 
 By default ``CMAKE_DISABLE_PRECOMPILE_HEADERS`` is ``OFF``.
diff --git a/Help/variable/CMAKE_DOTNET_TARGET_FRAMEWORK.rst b/Help/variable/CMAKE_DOTNET_TARGET_FRAMEWORK.rst
index 8edcd1e..29249d6 100644
--- a/Help/variable/CMAKE_DOTNET_TARGET_FRAMEWORK.rst
+++ b/Help/variable/CMAKE_DOTNET_TARGET_FRAMEWORK.rst
@@ -1,6 +1,8 @@
 CMAKE_DOTNET_TARGET_FRAMEWORK
 -----------------------------
 
+.. versionadded:: 3.17
+
 Default value for :prop_tgt:`DOTNET_TARGET_FRAMEWORK` property	of
 targets.
 
diff --git a/Help/variable/CMAKE_DOTNET_TARGET_FRAMEWORK_VERSION.rst b/Help/variable/CMAKE_DOTNET_TARGET_FRAMEWORK_VERSION.rst
index c2eef9e..fc3c360 100644
--- a/Help/variable/CMAKE_DOTNET_TARGET_FRAMEWORK_VERSION.rst
+++ b/Help/variable/CMAKE_DOTNET_TARGET_FRAMEWORK_VERSION.rst
@@ -1,6 +1,8 @@
 CMAKE_DOTNET_TARGET_FRAMEWORK_VERSION
 -------------------------------------
 
+.. versionadded:: 3.12
+
 Default value for :prop_tgt:`DOTNET_TARGET_FRAMEWORK_VERSION`
 property of targets.
 
diff --git a/Help/variable/CMAKE_ECLIPSE_GENERATE_LINKED_RESOURCES.rst b/Help/variable/CMAKE_ECLIPSE_GENERATE_LINKED_RESOURCES.rst
index 331aae8..548c563 100644
--- a/Help/variable/CMAKE_ECLIPSE_GENERATE_LINKED_RESOURCES.rst
+++ b/Help/variable/CMAKE_ECLIPSE_GENERATE_LINKED_RESOURCES.rst
@@ -1,6 +1,8 @@
 CMAKE_ECLIPSE_GENERATE_LINKED_RESOURCES
 ---------------------------------------
 
+.. versionadded:: 3.6
+
 This cache variable is used by the Eclipse project generator.  See
 :manual:`cmake-generators(7)`.
 
diff --git a/Help/variable/CMAKE_ECLIPSE_GENERATE_SOURCE_PROJECT.rst b/Help/variable/CMAKE_ECLIPSE_GENERATE_SOURCE_PROJECT.rst
index 7b4367d..fc28ebb 100644
--- a/Help/variable/CMAKE_ECLIPSE_GENERATE_SOURCE_PROJECT.rst
+++ b/Help/variable/CMAKE_ECLIPSE_GENERATE_SOURCE_PROJECT.rst
@@ -1,6 +1,8 @@
 CMAKE_ECLIPSE_GENERATE_SOURCE_PROJECT
 -------------------------------------
 
+.. versionadded:: 3.6
+
 This cache variable is used by the Eclipse project generator.  See
 :manual:`cmake-generators(7)`.
 
diff --git a/Help/variable/CMAKE_ECLIPSE_MAKE_ARGUMENTS.rst b/Help/variable/CMAKE_ECLIPSE_MAKE_ARGUMENTS.rst
index 6e8a408..90e36f5 100644
--- a/Help/variable/CMAKE_ECLIPSE_MAKE_ARGUMENTS.rst
+++ b/Help/variable/CMAKE_ECLIPSE_MAKE_ARGUMENTS.rst
@@ -1,6 +1,8 @@
 CMAKE_ECLIPSE_MAKE_ARGUMENTS
 ----------------------------
 
+.. versionadded:: 3.6
+
 This cache variable is used by the Eclipse project generator.  See
 :manual:`cmake-generators(7)`.
 
diff --git a/Help/variable/CMAKE_ECLIPSE_RESOURCE_ENCODING.rst b/Help/variable/CMAKE_ECLIPSE_RESOURCE_ENCODING.rst
index 314efe5..492acd8 100644
--- a/Help/variable/CMAKE_ECLIPSE_RESOURCE_ENCODING.rst
+++ b/Help/variable/CMAKE_ECLIPSE_RESOURCE_ENCODING.rst
@@ -1,6 +1,8 @@
 CMAKE_ECLIPSE_RESOURCE_ENCODING
 -------------------------------
 
+.. versionadded:: 3.16
+
 This cache variable tells the :generator:`Eclipse CDT4` project generator
 to set the resource encoding to the given value in generated project files.
 If no value is given, no encoding will be set.
diff --git a/Help/variable/CMAKE_ECLIPSE_VERSION.rst b/Help/variable/CMAKE_ECLIPSE_VERSION.rst
index 8cc7882..db65d89 100644
--- a/Help/variable/CMAKE_ECLIPSE_VERSION.rst
+++ b/Help/variable/CMAKE_ECLIPSE_VERSION.rst
@@ -1,6 +1,8 @@
 CMAKE_ECLIPSE_VERSION
 ---------------------
 
+.. versionadded:: 3.6
+
 This cache variable is used by the Eclipse project generator.  See
 :manual:`cmake-generators(7)`.
 
diff --git a/Help/variable/CMAKE_ENABLE_EXPORTS.rst b/Help/variable/CMAKE_ENABLE_EXPORTS.rst
index 8848da1..9f43de3 100644
--- a/Help/variable/CMAKE_ENABLE_EXPORTS.rst
+++ b/Help/variable/CMAKE_ENABLE_EXPORTS.rst
@@ -1,6 +1,8 @@
 CMAKE_ENABLE_EXPORTS
 --------------------
 
+.. versionadded:: 3.4
+
 Specify whether executables export symbols for loadable modules.
 
 This variable is used to initialize the :prop_tgt:`ENABLE_EXPORTS` target
diff --git a/Help/variable/CMAKE_EXECUTE_PROCESS_COMMAND_ECHO.rst b/Help/variable/CMAKE_EXECUTE_PROCESS_COMMAND_ECHO.rst
index 76561d8..90a16c3 100644
--- a/Help/variable/CMAKE_EXECUTE_PROCESS_COMMAND_ECHO.rst
+++ b/Help/variable/CMAKE_EXECUTE_PROCESS_COMMAND_ECHO.rst
@@ -1,6 +1,8 @@
 CMAKE_EXECUTE_PROCESS_COMMAND_ECHO
 ----------------------------------
 
+.. versionadded:: 3.15
+
 If this variable is set to ``STDERR``, ``STDOUT`` or ``NONE`` then commands
 in :command:`execute_process` calls will be printed to either stderr or
 stdout or not at all.
diff --git a/Help/variable/CMAKE_EXE_LINKER_FLAGS_CONFIG_INIT.rst b/Help/variable/CMAKE_EXE_LINKER_FLAGS_CONFIG_INIT.rst
index 592a369..4d2718a 100644
--- a/Help/variable/CMAKE_EXE_LINKER_FLAGS_CONFIG_INIT.rst
+++ b/Help/variable/CMAKE_EXE_LINKER_FLAGS_CONFIG_INIT.rst
@@ -1,6 +1,8 @@
 CMAKE_EXE_LINKER_FLAGS_<CONFIG>_INIT
 ------------------------------------
 
+.. versionadded:: 3.7
+
 Value used to initialize the :variable:`CMAKE_EXE_LINKER_FLAGS_<CONFIG>`
 cache entry the first time a build tree is configured.
 This variable is meant to be set by a :variable:`toolchain file
diff --git a/Help/variable/CMAKE_EXE_LINKER_FLAGS_INIT.rst b/Help/variable/CMAKE_EXE_LINKER_FLAGS_INIT.rst
index 0b8afe4..6e3927c 100644
--- a/Help/variable/CMAKE_EXE_LINKER_FLAGS_INIT.rst
+++ b/Help/variable/CMAKE_EXE_LINKER_FLAGS_INIT.rst
@@ -1,6 +1,8 @@
 CMAKE_EXE_LINKER_FLAGS_INIT
 ---------------------------
 
+.. versionadded:: 3.7
+
 Value used to initialize the :variable:`CMAKE_EXE_LINKER_FLAGS`
 cache entry the first time a build tree is configured.
 This variable is meant to be set by a :variable:`toolchain file
diff --git a/Help/variable/CMAKE_EXPORT_COMPILE_COMMANDS.rst b/Help/variable/CMAKE_EXPORT_COMPILE_COMMANDS.rst
index 6d2450b..724f309 100644
--- a/Help/variable/CMAKE_EXPORT_COMPILE_COMMANDS.rst
+++ b/Help/variable/CMAKE_EXPORT_COMPILE_COMMANDS.rst
@@ -1,6 +1,8 @@
 CMAKE_EXPORT_COMPILE_COMMANDS
 -----------------------------
 
+.. versionadded:: 3.5
+
 Enable/Disable output of compile commands during generation.
 
 If enabled, generates a ``compile_commands.json`` file containing the exact
diff --git a/Help/variable/CMAKE_EXPORT_NO_PACKAGE_REGISTRY.rst b/Help/variable/CMAKE_EXPORT_NO_PACKAGE_REGISTRY.rst
index 768ed64..5772490 100644
--- a/Help/variable/CMAKE_EXPORT_NO_PACKAGE_REGISTRY.rst
+++ b/Help/variable/CMAKE_EXPORT_NO_PACKAGE_REGISTRY.rst
@@ -1,6 +1,8 @@
 CMAKE_EXPORT_NO_PACKAGE_REGISTRY
 --------------------------------
 
+.. versionadded:: 3.1
+
 Disable the :command:`export(PACKAGE)` command when :policy:`CMP0090`
 is not set to ``NEW``.
 
diff --git a/Help/variable/CMAKE_EXPORT_PACKAGE_REGISTRY.rst b/Help/variable/CMAKE_EXPORT_PACKAGE_REGISTRY.rst
index 3476a19..663639b 100644
--- a/Help/variable/CMAKE_EXPORT_PACKAGE_REGISTRY.rst
+++ b/Help/variable/CMAKE_EXPORT_PACKAGE_REGISTRY.rst
@@ -1,6 +1,8 @@
 CMAKE_EXPORT_PACKAGE_REGISTRY
 -----------------------------
 
+.. versionadded:: 3.15
+
 Enables the :command:`export(PACKAGE)` command when :policy:`CMP0090`
 is set to ``NEW``.
 
diff --git a/Help/variable/CMAKE_FIND_APPBUNDLE.rst b/Help/variable/CMAKE_FIND_APPBUNDLE.rst
index 7a05fac..17563f3 100644
--- a/Help/variable/CMAKE_FIND_APPBUNDLE.rst
+++ b/Help/variable/CMAKE_FIND_APPBUNDLE.rst
@@ -1,6 +1,8 @@
 CMAKE_FIND_APPBUNDLE
 --------------------
 
+.. versionadded:: 3.4
+
 This variable affects how ``find_*`` commands choose between
 macOS Application Bundles and unix-style package components.
 
diff --git a/Help/variable/CMAKE_FIND_DEBUG_MODE.rst b/Help/variable/CMAKE_FIND_DEBUG_MODE.rst
index f5fd8ce..8f2a82f 100644
--- a/Help/variable/CMAKE_FIND_DEBUG_MODE.rst
+++ b/Help/variable/CMAKE_FIND_DEBUG_MODE.rst
@@ -1,6 +1,8 @@
 CMAKE_FIND_DEBUG_MODE
 ---------------------
 
+.. versionadded:: 3.17
+
 Print extra find call information for the following commands to standard
 error:
 
diff --git a/Help/variable/CMAKE_FIND_FRAMEWORK.rst b/Help/variable/CMAKE_FIND_FRAMEWORK.rst
index 4d5078f..3b62cda 100644
--- a/Help/variable/CMAKE_FIND_FRAMEWORK.rst
+++ b/Help/variable/CMAKE_FIND_FRAMEWORK.rst
@@ -1,6 +1,8 @@
 CMAKE_FIND_FRAMEWORK
 --------------------
 
+.. versionadded:: 3.4
+
 This variable affects how ``find_*`` commands choose between
 macOS Frameworks and unix-style package components.
 
diff --git a/Help/variable/CMAKE_FIND_LIBRARY_CUSTOM_LIB_SUFFIX.rst b/Help/variable/CMAKE_FIND_LIBRARY_CUSTOM_LIB_SUFFIX.rst
index ada8955..ca2ad7f 100644
--- a/Help/variable/CMAKE_FIND_LIBRARY_CUSTOM_LIB_SUFFIX.rst
+++ b/Help/variable/CMAKE_FIND_LIBRARY_CUSTOM_LIB_SUFFIX.rst
@@ -1,6 +1,8 @@
 CMAKE_FIND_LIBRARY_CUSTOM_LIB_SUFFIX
 ------------------------------------
 
+.. versionadded:: 3.9
+
 Specify a ``<suffix>`` to tell the :command:`find_library` command to
 search in a ``lib<suffix>`` directory before each ``lib`` directory that
 would normally be searched.
diff --git a/Help/variable/CMAKE_FIND_PACKAGE_NAME.rst b/Help/variable/CMAKE_FIND_PACKAGE_NAME.rst
index bd1a30f..fc1fd43 100644
--- a/Help/variable/CMAKE_FIND_PACKAGE_NAME.rst
+++ b/Help/variable/CMAKE_FIND_PACKAGE_NAME.rst
@@ -1,6 +1,8 @@
 CMAKE_FIND_PACKAGE_NAME
 -----------------------
 
+.. versionadded:: 3.1.1
+
 Defined by the :command:`find_package` command while loading
 a find module to record the caller-specified package name.
 See command documentation for details.
diff --git a/Help/variable/CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY.rst b/Help/variable/CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY.rst
index 4ee9d8b..8d86a94 100644
--- a/Help/variable/CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY.rst
+++ b/Help/variable/CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY.rst
@@ -1,6 +1,8 @@
 CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY
 --------------------------------------
 
+.. versionadded:: 3.1
+
 .. deprecated:: 3.16
 
   Use the :variable:`CMAKE_FIND_USE_PACKAGE_REGISTRY` variable instead.
diff --git a/Help/variable/CMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY.rst b/Help/variable/CMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY.rst
index 107c183..cc67f08 100644
--- a/Help/variable/CMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY.rst
+++ b/Help/variable/CMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY.rst
@@ -1,6 +1,8 @@
 CMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY
 ---------------------------------------------
 
+.. versionadded:: 3.1
+
 .. deprecated:: 3.16
 
   Use the :variable:`CMAKE_FIND_USE_SYSTEM_PACKAGE_REGISTRY` variable instead.
diff --git a/Help/variable/CMAKE_FIND_PACKAGE_PREFER_CONFIG.rst b/Help/variable/CMAKE_FIND_PACKAGE_PREFER_CONFIG.rst
index db658a1..ba81529 100644
--- a/Help/variable/CMAKE_FIND_PACKAGE_PREFER_CONFIG.rst
+++ b/Help/variable/CMAKE_FIND_PACKAGE_PREFER_CONFIG.rst
@@ -1,6 +1,8 @@
 CMAKE_FIND_PACKAGE_PREFER_CONFIG
 ---------------------------------
 
+.. versionadded:: 3.15
+
 Tell :command:`find_package` to try "Config" mode before "Module" mode if no
 mode was specified.
 
diff --git a/Help/variable/CMAKE_FIND_PACKAGE_RESOLVE_SYMLINKS.rst b/Help/variable/CMAKE_FIND_PACKAGE_RESOLVE_SYMLINKS.rst
index dfbde20..86d75e7 100644
--- a/Help/variable/CMAKE_FIND_PACKAGE_RESOLVE_SYMLINKS.rst
+++ b/Help/variable/CMAKE_FIND_PACKAGE_RESOLVE_SYMLINKS.rst
@@ -1,6 +1,8 @@
 CMAKE_FIND_PACKAGE_RESOLVE_SYMLINKS
 -----------------------------------
 
+.. versionadded:: 3.14
+
 Set to ``TRUE`` to tell :command:`find_package` calls to resolve symbolic
 links in the value of ``<PackageName>_DIR``.
 
diff --git a/Help/variable/CMAKE_FIND_PACKAGE_SORT_DIRECTION.rst b/Help/variable/CMAKE_FIND_PACKAGE_SORT_DIRECTION.rst
index 99e4ec1..98c2a8f 100644
--- a/Help/variable/CMAKE_FIND_PACKAGE_SORT_DIRECTION.rst
+++ b/Help/variable/CMAKE_FIND_PACKAGE_SORT_DIRECTION.rst
@@ -1,6 +1,8 @@
 CMAKE_FIND_PACKAGE_SORT_DIRECTION
 ---------------------------------
 
+.. versionadded:: 3.7
+
 The sorting direction used by :variable:`CMAKE_FIND_PACKAGE_SORT_ORDER`.
 It can assume one of the following values:
 
diff --git a/Help/variable/CMAKE_FIND_PACKAGE_SORT_ORDER.rst b/Help/variable/CMAKE_FIND_PACKAGE_SORT_ORDER.rst
index ba5f3a8..1725ba1 100644
--- a/Help/variable/CMAKE_FIND_PACKAGE_SORT_ORDER.rst
+++ b/Help/variable/CMAKE_FIND_PACKAGE_SORT_ORDER.rst
@@ -1,6 +1,8 @@
 CMAKE_FIND_PACKAGE_SORT_ORDER
 -----------------------------
 
+.. versionadded:: 3.7
+
 The default order for sorting packages found using :command:`find_package`.
 It can assume one of the following values:
 
diff --git a/Help/variable/CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH.rst b/Help/variable/CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH.rst
index 957e956..de1bad7 100644
--- a/Help/variable/CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH.rst
+++ b/Help/variable/CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH.rst
@@ -1,6 +1,8 @@
 CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH
 -------------------------------------
 
+.. versionadded:: 3.16
+
 Controls the default behavior of the following commands for whether or not to
 search paths provided by cmake-specific environment variables:
 
diff --git a/Help/variable/CMAKE_FIND_USE_CMAKE_PATH.rst b/Help/variable/CMAKE_FIND_USE_CMAKE_PATH.rst
index d2bdb09..47ce3a3 100644
--- a/Help/variable/CMAKE_FIND_USE_CMAKE_PATH.rst
+++ b/Help/variable/CMAKE_FIND_USE_CMAKE_PATH.rst
@@ -1,6 +1,8 @@
 CMAKE_FIND_USE_CMAKE_PATH
 -------------------------
 
+.. versionadded:: 3.16
+
 Controls the default behavior of the following commands for whether or not to
 search paths provided by cmake-specific cache variables:
 
diff --git a/Help/variable/CMAKE_FIND_USE_CMAKE_SYSTEM_PATH.rst b/Help/variable/CMAKE_FIND_USE_CMAKE_SYSTEM_PATH.rst
index b99081d..2fd00df 100644
--- a/Help/variable/CMAKE_FIND_USE_CMAKE_SYSTEM_PATH.rst
+++ b/Help/variable/CMAKE_FIND_USE_CMAKE_SYSTEM_PATH.rst
@@ -1,6 +1,8 @@
 CMAKE_FIND_USE_CMAKE_SYSTEM_PATH
 --------------------------------
 
+.. versionadded:: 3.16
+
 Controls the default behavior of the following commands for whether or not to
 search paths provided by platform-specific cmake variables:
 
diff --git a/Help/variable/CMAKE_FIND_USE_PACKAGE_REGISTRY.rst b/Help/variable/CMAKE_FIND_USE_PACKAGE_REGISTRY.rst
index 7c7ca36..3127206 100644
--- a/Help/variable/CMAKE_FIND_USE_PACKAGE_REGISTRY.rst
+++ b/Help/variable/CMAKE_FIND_USE_PACKAGE_REGISTRY.rst
@@ -1,6 +1,8 @@
 CMAKE_FIND_USE_PACKAGE_REGISTRY
 -------------------------------
 
+.. versionadded:: 3.16
+
 Controls the default behavior of the :command:`find_package` command for
 whether or not to search paths provided by the :ref:`User Package Registry`.
 
diff --git a/Help/variable/CMAKE_FIND_USE_PACKAGE_ROOT_PATH.rst b/Help/variable/CMAKE_FIND_USE_PACKAGE_ROOT_PATH.rst
index e7f5b0f..64e5c6d 100644
--- a/Help/variable/CMAKE_FIND_USE_PACKAGE_ROOT_PATH.rst
+++ b/Help/variable/CMAKE_FIND_USE_PACKAGE_ROOT_PATH.rst
@@ -1,6 +1,8 @@
 CMAKE_FIND_USE_PACKAGE_ROOT_PATH
 --------------------------------
 
+.. versionadded:: 3.16
+
 Controls the default behavior of the following commands for whether or not to
 search paths provided by :variable:`<PackageName>_ROOT` variables:
 
diff --git a/Help/variable/CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH.rst b/Help/variable/CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH.rst
index fbaba5a..a0a86e4 100644
--- a/Help/variable/CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH.rst
+++ b/Help/variable/CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH.rst
@@ -1,6 +1,8 @@
 CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH
 --------------------------------------
 
+.. versionadded:: 3.16
+
 Controls the default behavior of the following commands for whether or not to
 search paths provided by standard system environment variables:
 
diff --git a/Help/variable/CMAKE_FIND_USE_SYSTEM_PACKAGE_REGISTRY.rst b/Help/variable/CMAKE_FIND_USE_SYSTEM_PACKAGE_REGISTRY.rst
index cb4eec5..504b7e8 100644
--- a/Help/variable/CMAKE_FIND_USE_SYSTEM_PACKAGE_REGISTRY.rst
+++ b/Help/variable/CMAKE_FIND_USE_SYSTEM_PACKAGE_REGISTRY.rst
@@ -1,6 +1,8 @@
 CMAKE_FIND_USE_SYSTEM_PACKAGE_REGISTRY
 --------------------------------------
 
+.. versionadded:: 3.16
+
 Controls searching the :ref:`System Package Registry` by the
 :command:`find_package` command.
 
diff --git a/Help/variable/CMAKE_FOLDER.rst b/Help/variable/CMAKE_FOLDER.rst
index 50a2b88..37f137c 100644
--- a/Help/variable/CMAKE_FOLDER.rst
+++ b/Help/variable/CMAKE_FOLDER.rst
@@ -1,6 +1,8 @@
 CMAKE_FOLDER
 ------------
 
+.. versionadded:: 3.12
+
 Set the folder name. Use to organize targets in an IDE.
 
 This variable is used to initialize the :prop_tgt:`FOLDER` property on all the
diff --git a/Help/variable/CMAKE_FRAMEWORK.rst b/Help/variable/CMAKE_FRAMEWORK.rst
index 591041c..37385bf 100644
--- a/Help/variable/CMAKE_FRAMEWORK.rst
+++ b/Help/variable/CMAKE_FRAMEWORK.rst
@@ -1,6 +1,8 @@
 CMAKE_FRAMEWORK
 ---------------
 
+.. versionadded:: 3.15
+
 Default value for :prop_tgt:`FRAMEWORK` of targets.
 
 This variable is used to initialize the :prop_tgt:`FRAMEWORK` property on
diff --git a/Help/variable/CMAKE_FRAMEWORK_MULTI_CONFIG_POSTFIX_CONFIG.rst b/Help/variable/CMAKE_FRAMEWORK_MULTI_CONFIG_POSTFIX_CONFIG.rst
index 5c7cd23..47fb66e 100644
--- a/Help/variable/CMAKE_FRAMEWORK_MULTI_CONFIG_POSTFIX_CONFIG.rst
+++ b/Help/variable/CMAKE_FRAMEWORK_MULTI_CONFIG_POSTFIX_CONFIG.rst
@@ -1,6 +1,8 @@
 CMAKE_FRAMEWORK_MULTI_CONFIG_POSTFIX_<CONFIG>
 ---------------------------------------------
 
+.. versionadded:: 3.18
+
 Default framework filename postfix under configuration ``<CONFIG>`` when
 using a multi-config generator.
 
diff --git a/Help/variable/CMAKE_Fortran_PREPROCESS.rst b/Help/variable/CMAKE_Fortran_PREPROCESS.rst
index 74b2d8b..7d405f3 100644
--- a/Help/variable/CMAKE_Fortran_PREPROCESS.rst
+++ b/Help/variable/CMAKE_Fortran_PREPROCESS.rst
@@ -1,6 +1,8 @@
 CMAKE_Fortran_PREPROCESS
 ------------------------
 
+.. versionadded:: 3.18
+
 Default value for :prop_tgt:`Fortran_PREPROCESS` of targets.
 
 This variable is used to initialize the :prop_tgt:`Fortran_PREPROCESS`
diff --git a/Help/variable/CMAKE_GENERATOR_INSTANCE.rst b/Help/variable/CMAKE_GENERATOR_INSTANCE.rst
index 3657ed4..5858d7a 100644
--- a/Help/variable/CMAKE_GENERATOR_INSTANCE.rst
+++ b/Help/variable/CMAKE_GENERATOR_INSTANCE.rst
@@ -1,6 +1,8 @@
 CMAKE_GENERATOR_INSTANCE
 ------------------------
 
+.. versionadded:: 3.11
+
 Generator-specific instance specification provided by user.
 
 Some CMake generators support selection of an instance of the native build
diff --git a/Help/variable/CMAKE_GENERATOR_PLATFORM.rst b/Help/variable/CMAKE_GENERATOR_PLATFORM.rst
index 2c115a3..b17d83a 100644
--- a/Help/variable/CMAKE_GENERATOR_PLATFORM.rst
+++ b/Help/variable/CMAKE_GENERATOR_PLATFORM.rst
@@ -1,6 +1,8 @@
 CMAKE_GENERATOR_PLATFORM
 ------------------------
 
+.. versionadded:: 3.1
+
 Generator-specific target platform specification provided by user.
 
 Some CMake generators support a target platform name to be given
diff --git a/Help/variable/CMAKE_GHS_NO_SOURCE_GROUP_FILE.rst b/Help/variable/CMAKE_GHS_NO_SOURCE_GROUP_FILE.rst
index b6768a1..0e8ae5e 100644
--- a/Help/variable/CMAKE_GHS_NO_SOURCE_GROUP_FILE.rst
+++ b/Help/variable/CMAKE_GHS_NO_SOURCE_GROUP_FILE.rst
@@ -1,6 +1,8 @@
 CMAKE_GHS_NO_SOURCE_GROUP_FILE
 ------------------------------
 
+.. versionadded:: 3.14
+
 ``ON`` / ``OFF`` boolean to control if the project file for a target should
 be one single file or multiple files.  Refer to
 :prop_tgt:`GHS_NO_SOURCE_GROUP_FILE` for further details.
diff --git a/Help/variable/CMAKE_GLOBAL_AUTOGEN_TARGET.rst b/Help/variable/CMAKE_GLOBAL_AUTOGEN_TARGET.rst
index 8587742..96e9907 100644
--- a/Help/variable/CMAKE_GLOBAL_AUTOGEN_TARGET.rst
+++ b/Help/variable/CMAKE_GLOBAL_AUTOGEN_TARGET.rst
@@ -1,6 +1,8 @@
 CMAKE_GLOBAL_AUTOGEN_TARGET
 ---------------------------
 
+.. versionadded:: 3.14
+
 Switch to enable generation of a global ``autogen`` target.
 
 When :variable:`CMAKE_GLOBAL_AUTOGEN_TARGET` is enabled, a custom target
diff --git a/Help/variable/CMAKE_GLOBAL_AUTOGEN_TARGET_NAME.rst b/Help/variable/CMAKE_GLOBAL_AUTOGEN_TARGET_NAME.rst
index c86a5d0..4af4bc3 100644
--- a/Help/variable/CMAKE_GLOBAL_AUTOGEN_TARGET_NAME.rst
+++ b/Help/variable/CMAKE_GLOBAL_AUTOGEN_TARGET_NAME.rst
@@ -1,6 +1,8 @@
 CMAKE_GLOBAL_AUTOGEN_TARGET_NAME
 --------------------------------
 
+.. versionadded:: 3.14
+
 Change the name of the global ``autogen`` target.
 
 When :variable:`CMAKE_GLOBAL_AUTOGEN_TARGET` is enabled, a global custom target
diff --git a/Help/variable/CMAKE_GLOBAL_AUTORCC_TARGET.rst b/Help/variable/CMAKE_GLOBAL_AUTORCC_TARGET.rst
index f92128c..efea5be 100644
--- a/Help/variable/CMAKE_GLOBAL_AUTORCC_TARGET.rst
+++ b/Help/variable/CMAKE_GLOBAL_AUTORCC_TARGET.rst
@@ -1,6 +1,8 @@
 CMAKE_GLOBAL_AUTORCC_TARGET
 ---------------------------
 
+.. versionadded:: 3.14
+
 Switch to enable generation of a global ``autorcc`` target.
 
 When :variable:`CMAKE_GLOBAL_AUTORCC_TARGET` is enabled, a custom target
diff --git a/Help/variable/CMAKE_GLOBAL_AUTORCC_TARGET_NAME.rst b/Help/variable/CMAKE_GLOBAL_AUTORCC_TARGET_NAME.rst
index c6e05de..4d2e313 100644
--- a/Help/variable/CMAKE_GLOBAL_AUTORCC_TARGET_NAME.rst
+++ b/Help/variable/CMAKE_GLOBAL_AUTORCC_TARGET_NAME.rst
@@ -1,6 +1,8 @@
 CMAKE_GLOBAL_AUTORCC_TARGET_NAME
 --------------------------------
 
+.. versionadded:: 3.14
+
 Change the name of the global ``autorcc`` target.
 
 When :variable:`CMAKE_GLOBAL_AUTORCC_TARGET` is enabled, a global custom target
diff --git a/Help/variable/CMAKE_HOST_SOLARIS.rst b/Help/variable/CMAKE_HOST_SOLARIS.rst
index 82b5d69..7054acd 100644
--- a/Help/variable/CMAKE_HOST_SOLARIS.rst
+++ b/Help/variable/CMAKE_HOST_SOLARIS.rst
@@ -1,6 +1,8 @@
 CMAKE_HOST_SOLARIS
 ------------------
 
+.. versionadded:: 3.6
+
 ``True`` for Oracle Solaris operating systems.
 
 Set to ``true`` when the host system is Oracle Solaris.
diff --git a/Help/variable/CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS.rst b/Help/variable/CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS.rst
index f994fbe..aad99e4 100644
--- a/Help/variable/CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS.rst
+++ b/Help/variable/CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS.rst
@@ -1,6 +1,8 @@
 CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS
 -------------------------------------------
 
+.. versionadded:: 3.11
+
 Default permissions for directories created implicitly during installation
 of files by :command:`install` and :command:`file(INSTALL)`.
 
diff --git a/Help/variable/CMAKE_INSTALL_MESSAGE.rst b/Help/variable/CMAKE_INSTALL_MESSAGE.rst
index 304df26..4f39cfe 100644
--- a/Help/variable/CMAKE_INSTALL_MESSAGE.rst
+++ b/Help/variable/CMAKE_INSTALL_MESSAGE.rst
@@ -1,6 +1,8 @@
 CMAKE_INSTALL_MESSAGE
 ---------------------
 
+.. versionadded:: 3.1
+
 Specify verbosity of installation script code generated by the
 :command:`install` command (using the :command:`file(INSTALL)` command).
 For paths that are newly installed or updated, installation
diff --git a/Help/variable/CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT.rst b/Help/variable/CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT.rst
index 2a5842d..93cc319 100644
--- a/Help/variable/CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT.rst
+++ b/Help/variable/CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT.rst
@@ -1,6 +1,8 @@
 CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT
 -------------------------------------------
 
+.. versionadded:: 3.7.1
+
 CMake sets this variable to a ``TRUE`` value when the
 :variable:`CMAKE_INSTALL_PREFIX` has just been initialized to
 its default value, typically on the first run of CMake within
diff --git a/Help/variable/CMAKE_INSTALL_REMOVE_ENVIRONMENT_RPATH.rst b/Help/variable/CMAKE_INSTALL_REMOVE_ENVIRONMENT_RPATH.rst
index 76ca3da..c86e433 100644
--- a/Help/variable/CMAKE_INSTALL_REMOVE_ENVIRONMENT_RPATH.rst
+++ b/Help/variable/CMAKE_INSTALL_REMOVE_ENVIRONMENT_RPATH.rst
@@ -1,6 +1,8 @@
 CMAKE_INSTALL_REMOVE_ENVIRONMENT_RPATH
 --------------------------------------
 
+.. versionadded:: 3.16
+
 Sets the default for whether toolchain-defined rpaths should be removed during
 installation.
 
diff --git a/Help/variable/CMAKE_INTERPROCEDURAL_OPTIMIZATION.rst b/Help/variable/CMAKE_INTERPROCEDURAL_OPTIMIZATION.rst
index b0cbb62..cf7da76 100644
--- a/Help/variable/CMAKE_INTERPROCEDURAL_OPTIMIZATION.rst
+++ b/Help/variable/CMAKE_INTERPROCEDURAL_OPTIMIZATION.rst
@@ -1,6 +1,8 @@
 CMAKE_INTERPROCEDURAL_OPTIMIZATION
 ----------------------------------
 
+.. versionadded:: 3.9
+
 Default value for :prop_tgt:`INTERPROCEDURAL_OPTIMIZATION` of targets.
 
 This variable is used to initialize the :prop_tgt:`INTERPROCEDURAL_OPTIMIZATION`
diff --git a/Help/variable/CMAKE_INTERPROCEDURAL_OPTIMIZATION_CONFIG.rst b/Help/variable/CMAKE_INTERPROCEDURAL_OPTIMIZATION_CONFIG.rst
index b291102..5b3ee77 100644
--- a/Help/variable/CMAKE_INTERPROCEDURAL_OPTIMIZATION_CONFIG.rst
+++ b/Help/variable/CMAKE_INTERPROCEDURAL_OPTIMIZATION_CONFIG.rst
@@ -1,6 +1,8 @@
 CMAKE_INTERPROCEDURAL_OPTIMIZATION_<CONFIG>
 -------------------------------------------
 
+.. versionadded:: 3.9
+
 Default value for :prop_tgt:`INTERPROCEDURAL_OPTIMIZATION_<CONFIG>` of targets.
 
 This variable is used to initialize the :prop_tgt:`INTERPROCEDURAL_OPTIMIZATION_<CONFIG>`
diff --git a/Help/variable/CMAKE_IOS_INSTALL_COMBINED.rst b/Help/variable/CMAKE_IOS_INSTALL_COMBINED.rst
index c5cb9b6..cd7fd8d 100644
--- a/Help/variable/CMAKE_IOS_INSTALL_COMBINED.rst
+++ b/Help/variable/CMAKE_IOS_INSTALL_COMBINED.rst
@@ -1,6 +1,8 @@
 CMAKE_IOS_INSTALL_COMBINED
 --------------------------
 
+.. versionadded:: 3.5
+
 Default value for :prop_tgt:`IOS_INSTALL_COMBINED` of targets.
 
 This variable is used to initialize the :prop_tgt:`IOS_INSTALL_COMBINED`
diff --git a/Help/variable/CMAKE_JOB_POOLS.rst b/Help/variable/CMAKE_JOB_POOLS.rst
index 72b50b4..43d3c84 100644
--- a/Help/variable/CMAKE_JOB_POOLS.rst
+++ b/Help/variable/CMAKE_JOB_POOLS.rst
@@ -1,6 +1,8 @@
 CMAKE_JOB_POOLS
 ---------------
 
+.. versionadded:: 3.11
+
 If the :prop_gbl:`JOB_POOLS` global property is not set, the value
 of this variable is used in its place.  See :prop_gbl:`JOB_POOLS`
 for additional information.
diff --git a/Help/variable/CMAKE_JOB_POOL_PRECOMPILE_HEADER.rst b/Help/variable/CMAKE_JOB_POOL_PRECOMPILE_HEADER.rst
index f9467b3..1a6f66a 100644
--- a/Help/variable/CMAKE_JOB_POOL_PRECOMPILE_HEADER.rst
+++ b/Help/variable/CMAKE_JOB_POOL_PRECOMPILE_HEADER.rst
@@ -1,6 +1,8 @@
 CMAKE_JOB_POOL_PRECOMPILE_HEADER
 --------------------------------
 
+.. versionadded:: 3.17
+
 This variable is used to initialize the :prop_tgt:`JOB_POOL_PRECOMPILE_HEADER`
 property on all the targets. See :prop_tgt:`JOB_POOL_PRECOMPILE_HEADER`
 for additional information.
diff --git a/Help/variable/CMAKE_LANG_ANDROID_TOOLCHAIN_MACHINE.rst b/Help/variable/CMAKE_LANG_ANDROID_TOOLCHAIN_MACHINE.rst
index d336364..f539277 100644
--- a/Help/variable/CMAKE_LANG_ANDROID_TOOLCHAIN_MACHINE.rst
+++ b/Help/variable/CMAKE_LANG_ANDROID_TOOLCHAIN_MACHINE.rst
@@ -1,6 +1,8 @@
 CMAKE_<LANG>_ANDROID_TOOLCHAIN_MACHINE
 --------------------------------------
 
+.. versionadded:: 3.7.1
+
 When :ref:`Cross Compiling for Android` this variable contains the
 toolchain binutils machine name (e.g. ``gcc -dumpmachine``).  The
 binutils typically have a ``<machine>-`` prefix on their name.
diff --git a/Help/variable/CMAKE_LANG_ANDROID_TOOLCHAIN_PREFIX.rst b/Help/variable/CMAKE_LANG_ANDROID_TOOLCHAIN_PREFIX.rst
index db04af3..ff072ca 100644
--- a/Help/variable/CMAKE_LANG_ANDROID_TOOLCHAIN_PREFIX.rst
+++ b/Help/variable/CMAKE_LANG_ANDROID_TOOLCHAIN_PREFIX.rst
@@ -1,6 +1,8 @@
 CMAKE_<LANG>_ANDROID_TOOLCHAIN_PREFIX
 -------------------------------------
 
+.. versionadded:: 3.7
+
 When :ref:`Cross Compiling for Android` this variable contains the absolute
 path prefixing the toolchain GNU compiler and its binutils.
 
diff --git a/Help/variable/CMAKE_LANG_ANDROID_TOOLCHAIN_SUFFIX.rst b/Help/variable/CMAKE_LANG_ANDROID_TOOLCHAIN_SUFFIX.rst
index 159eb22..d595280 100644
--- a/Help/variable/CMAKE_LANG_ANDROID_TOOLCHAIN_SUFFIX.rst
+++ b/Help/variable/CMAKE_LANG_ANDROID_TOOLCHAIN_SUFFIX.rst
@@ -1,6 +1,8 @@
 CMAKE_<LANG>_ANDROID_TOOLCHAIN_SUFFIX
 -------------------------------------
 
+.. versionadded:: 3.7
+
 When :ref:`Cross Compiling for Android` this variable contains the
 host platform suffix of the toolchain GNU compiler and its binutils.
 
diff --git a/Help/variable/CMAKE_LANG_CLANG_TIDY.rst b/Help/variable/CMAKE_LANG_CLANG_TIDY.rst
index bd49de3..78f0f6a 100644
--- a/Help/variable/CMAKE_LANG_CLANG_TIDY.rst
+++ b/Help/variable/CMAKE_LANG_CLANG_TIDY.rst
@@ -1,6 +1,8 @@
 CMAKE_<LANG>_CLANG_TIDY
 -----------------------
 
+.. versionadded:: 3.6
+
 Default value for :prop_tgt:`<LANG>_CLANG_TIDY` target property
 when ``<LANG>`` is ``C`` or ``CXX``.
 
diff --git a/Help/variable/CMAKE_LANG_COMPILER.rst b/Help/variable/CMAKE_LANG_COMPILER.rst
index 89df495..e694b33 100644
--- a/Help/variable/CMAKE_LANG_COMPILER.rst
+++ b/Help/variable/CMAKE_LANG_COMPILER.rst
@@ -5,3 +5,28 @@
 
 This is the command that will be used as the ``<LANG>`` compiler.  Once
 set, you can not change this variable.
+
+Usage
+^^^^^
+
+This variable can be set by the user during the first time a build tree is configured.
+
+If a non-full path value is supplied then CMake will resolve the full path of
+the compiler.
+
+The variable could be set in a user supplied toolchain file or via `-D` on the command line.
+
+.. note::
+  Options that are required to make the compiler work correctly can be included
+  as items in a list; they can not be changed.
+
+.. code-block:: cmake
+
+  #set within user supplied toolchain file
+  set(CMAKE_C_COMPILER /full/path/to/qcc --arg1 --arg2)
+
+or
+
+.. code-block:: console
+
+  $ cmake ... -DCMAKE_C_COMPILER='qcc;--arg1;--arg2'
diff --git a/Help/variable/CMAKE_LANG_COMPILER_AR.rst b/Help/variable/CMAKE_LANG_COMPILER_AR.rst
index b83a1d4..74f2758 100644
--- a/Help/variable/CMAKE_LANG_COMPILER_AR.rst
+++ b/Help/variable/CMAKE_LANG_COMPILER_AR.rst
@@ -1,6 +1,8 @@
 CMAKE_<LANG>_COMPILER_AR
 ------------------------
 
+.. versionadded:: 3.9
+
 A wrapper around ``ar`` adding the appropriate ``--plugin`` option for the
 compiler.
 
diff --git a/Help/variable/CMAKE_LANG_COMPILER_ARCHITECTURE_ID.rst b/Help/variable/CMAKE_LANG_COMPILER_ARCHITECTURE_ID.rst
index 054c648..8057566 100644
--- a/Help/variable/CMAKE_LANG_COMPILER_ARCHITECTURE_ID.rst
+++ b/Help/variable/CMAKE_LANG_COMPILER_ARCHITECTURE_ID.rst
@@ -1,6 +1,8 @@
 CMAKE_<LANG>_COMPILER_ARCHITECTURE_ID
 -------------------------------------
 
+.. versionadded:: 3.10
+
 An internal variable subject to change.
 
 This is used to identify the variant of a compiler based on its target
diff --git a/Help/variable/CMAKE_LANG_COMPILER_LAUNCHER.rst b/Help/variable/CMAKE_LANG_COMPILER_LAUNCHER.rst
index c76e2d0..98634c2 100644
--- a/Help/variable/CMAKE_LANG_COMPILER_LAUNCHER.rst
+++ b/Help/variable/CMAKE_LANG_COMPILER_LAUNCHER.rst
@@ -1,6 +1,8 @@
 CMAKE_<LANG>_COMPILER_LAUNCHER
 ------------------------------
 
+.. versionadded:: 3.4
+
 Default value for :prop_tgt:`<LANG>_COMPILER_LAUNCHER` target property.
 This variable is used to initialize the property on each target as it is
 created.  This is done only when ``<LANG>`` is ``C``, ``CXX``, ``Fortran``,
diff --git a/Help/variable/CMAKE_LANG_COMPILER_PREDEFINES_COMMAND.rst b/Help/variable/CMAKE_LANG_COMPILER_PREDEFINES_COMMAND.rst
index e050f43..935329a 100644
--- a/Help/variable/CMAKE_LANG_COMPILER_PREDEFINES_COMMAND.rst
+++ b/Help/variable/CMAKE_LANG_COMPILER_PREDEFINES_COMMAND.rst
@@ -1,6 +1,8 @@
 CMAKE_<LANG>_COMPILER_PREDEFINES_COMMAND
 ----------------------------------------
 
+.. versionadded:: 3.10
+
 Command that outputs the compiler pre definitions.
 
 See :prop_tgt:`AUTOMOC` which uses
diff --git a/Help/variable/CMAKE_LANG_COMPILER_RANLIB.rst b/Help/variable/CMAKE_LANG_COMPILER_RANLIB.rst
index 945160b..1d10b55 100644
--- a/Help/variable/CMAKE_LANG_COMPILER_RANLIB.rst
+++ b/Help/variable/CMAKE_LANG_COMPILER_RANLIB.rst
@@ -1,6 +1,8 @@
 CMAKE_<LANG>_COMPILER_RANLIB
 ----------------------------
 
+.. versionadded:: 3.9
+
 A wrapper around ``ranlib`` adding the appropriate ``--plugin`` option for the
 compiler.
 
diff --git a/Help/variable/CMAKE_LANG_COMPILER_VERSION_INTERNAL.rst b/Help/variable/CMAKE_LANG_COMPILER_VERSION_INTERNAL.rst
index c3cd980..596a989 100644
--- a/Help/variable/CMAKE_LANG_COMPILER_VERSION_INTERNAL.rst
+++ b/Help/variable/CMAKE_LANG_COMPILER_VERSION_INTERNAL.rst
@@ -1,6 +1,8 @@
 CMAKE_<LANG>_COMPILER_VERSION_INTERNAL
 --------------------------------------
 
+.. versionadded:: 3.10
+
 An internal variable subject to change.
 
 This is used to identify the variant of a compiler based on an internal
diff --git a/Help/variable/CMAKE_LANG_CPPCHECK.rst b/Help/variable/CMAKE_LANG_CPPCHECK.rst
index 50b478f..5ae5faf 100644
--- a/Help/variable/CMAKE_LANG_CPPCHECK.rst
+++ b/Help/variable/CMAKE_LANG_CPPCHECK.rst
@@ -1,6 +1,8 @@
 CMAKE_<LANG>_CPPCHECK
 ---------------------
 
+.. versionadded:: 3.10
+
 Default value for :prop_tgt:`<LANG>_CPPCHECK` target property. This variable
 is used to initialize the property on each target as it is created.  This
 is done only when ``<LANG>`` is ``C`` or ``CXX``.
diff --git a/Help/variable/CMAKE_LANG_CPPLINT.rst b/Help/variable/CMAKE_LANG_CPPLINT.rst
index 3b6f452..ab7b0fc 100644
--- a/Help/variable/CMAKE_LANG_CPPLINT.rst
+++ b/Help/variable/CMAKE_LANG_CPPLINT.rst
@@ -1,6 +1,8 @@
 CMAKE_<LANG>_CPPLINT
 --------------------
 
+.. versionadded:: 3.8
+
 Default value for :prop_tgt:`<LANG>_CPPLINT` target property. This variable
 is used to initialize the property on each target as it is created.  This
 is done only when ``<LANG>`` is ``C`` or ``CXX``.
diff --git a/Help/variable/CMAKE_LANG_FLAGS_CONFIG.rst b/Help/variable/CMAKE_LANG_FLAGS_CONFIG.rst
index 1dbd036..628b62b 100644
--- a/Help/variable/CMAKE_LANG_FLAGS_CONFIG.rst
+++ b/Help/variable/CMAKE_LANG_FLAGS_CONFIG.rst
@@ -1,4 +1,6 @@
 CMAKE_<LANG>_FLAGS_<CONFIG>
 ---------------------------
 
+.. versionadded:: 3.11
+
 Flags for language ``<LANG>`` when building for the ``<CONFIG>`` configuration.
diff --git a/Help/variable/CMAKE_LANG_FLAGS_CONFIG_INIT.rst b/Help/variable/CMAKE_LANG_FLAGS_CONFIG_INIT.rst
index 1eb5b3f..17669a2 100644
--- a/Help/variable/CMAKE_LANG_FLAGS_CONFIG_INIT.rst
+++ b/Help/variable/CMAKE_LANG_FLAGS_CONFIG_INIT.rst
@@ -1,6 +1,8 @@
 CMAKE_<LANG>_FLAGS_<CONFIG>_INIT
 --------------------------------
 
+.. versionadded:: 3.11
+
 Value used to initialize the :variable:`CMAKE_<LANG>_FLAGS_<CONFIG>` cache
 entry the first time a build tree is configured for language ``<LANG>``.
 This variable is meant to be set by a :variable:`toolchain file
diff --git a/Help/variable/CMAKE_LANG_FLAGS_DEBUG_INIT.rst b/Help/variable/CMAKE_LANG_FLAGS_DEBUG_INIT.rst
index de7fcfc..49c9e99 100644
--- a/Help/variable/CMAKE_LANG_FLAGS_DEBUG_INIT.rst
+++ b/Help/variable/CMAKE_LANG_FLAGS_DEBUG_INIT.rst
@@ -1,5 +1,7 @@
 CMAKE_<LANG>_FLAGS_DEBUG_INIT
 -----------------------------
 
+.. versionadded:: 3.7
+
 This variable is the ``Debug`` variant of the
 :variable:`CMAKE_<LANG>_FLAGS_<CONFIG>_INIT` variable.
diff --git a/Help/variable/CMAKE_LANG_FLAGS_INIT.rst b/Help/variable/CMAKE_LANG_FLAGS_INIT.rst
index 4a034e8..67ff2cb 100644
--- a/Help/variable/CMAKE_LANG_FLAGS_INIT.rst
+++ b/Help/variable/CMAKE_LANG_FLAGS_INIT.rst
@@ -1,6 +1,8 @@
 CMAKE_<LANG>_FLAGS_INIT
 -----------------------
 
+.. versionadded:: 3.7
+
 Value used to initialize the :variable:`CMAKE_<LANG>_FLAGS` cache entry
 the first time a build tree is configured for language ``<LANG>``.
 This variable is meant to be set by a :variable:`toolchain file
diff --git a/Help/variable/CMAKE_LANG_FLAGS_MINSIZEREL_INIT.rst b/Help/variable/CMAKE_LANG_FLAGS_MINSIZEREL_INIT.rst
index 1e7003c..3600909 100644
--- a/Help/variable/CMAKE_LANG_FLAGS_MINSIZEREL_INIT.rst
+++ b/Help/variable/CMAKE_LANG_FLAGS_MINSIZEREL_INIT.rst
@@ -1,5 +1,7 @@
 CMAKE_<LANG>_FLAGS_MINSIZEREL_INIT
 ----------------------------------
 
+.. versionadded:: 3.7
+
 This variable is the ``MinSizeRel`` variant of the
 :variable:`CMAKE_<LANG>_FLAGS_<CONFIG>_INIT` variable.
diff --git a/Help/variable/CMAKE_LANG_FLAGS_RELEASE_INIT.rst b/Help/variable/CMAKE_LANG_FLAGS_RELEASE_INIT.rst
index e7c73fe..e889852 100644
--- a/Help/variable/CMAKE_LANG_FLAGS_RELEASE_INIT.rst
+++ b/Help/variable/CMAKE_LANG_FLAGS_RELEASE_INIT.rst
@@ -1,5 +1,7 @@
 CMAKE_<LANG>_FLAGS_RELEASE_INIT
 -------------------------------
 
+.. versionadded:: 3.7
+
 This variable is the ``Release`` variant of the
 :variable:`CMAKE_<LANG>_FLAGS_<CONFIG>_INIT` variable.
diff --git a/Help/variable/CMAKE_LANG_FLAGS_RELWITHDEBINFO_INIT.rst b/Help/variable/CMAKE_LANG_FLAGS_RELWITHDEBINFO_INIT.rst
index 3ab3975..b42caee 100644
--- a/Help/variable/CMAKE_LANG_FLAGS_RELWITHDEBINFO_INIT.rst
+++ b/Help/variable/CMAKE_LANG_FLAGS_RELWITHDEBINFO_INIT.rst
@@ -1,5 +1,7 @@
 CMAKE_<LANG>_FLAGS_RELWITHDEBINFO_INIT
 --------------------------------------
 
+.. versionadded:: 3.7
+
 This variable is the ``RelWithDebInfo`` variant of the
 :variable:`CMAKE_<LANG>_FLAGS_<CONFIG>_INIT` variable.
diff --git a/Help/variable/CMAKE_LANG_INCLUDE_WHAT_YOU_USE.rst b/Help/variable/CMAKE_LANG_INCLUDE_WHAT_YOU_USE.rst
index 2c8028a..be6c210 100644
--- a/Help/variable/CMAKE_LANG_INCLUDE_WHAT_YOU_USE.rst
+++ b/Help/variable/CMAKE_LANG_INCLUDE_WHAT_YOU_USE.rst
@@ -1,6 +1,8 @@
 CMAKE_<LANG>_INCLUDE_WHAT_YOU_USE
 ---------------------------------
 
+.. versionadded:: 3.3
+
 Default value for :prop_tgt:`<LANG>_INCLUDE_WHAT_YOU_USE` target property.
 This variable is used to initialize the property on each target as it is
 created.  This is done only when ``<LANG>`` is ``C`` or ``CXX``.
diff --git a/Help/variable/CMAKE_LANG_LINKER_WRAPPER_FLAG.rst b/Help/variable/CMAKE_LANG_LINKER_WRAPPER_FLAG.rst
index df51407..471c351 100644
--- a/Help/variable/CMAKE_LANG_LINKER_WRAPPER_FLAG.rst
+++ b/Help/variable/CMAKE_LANG_LINKER_WRAPPER_FLAG.rst
@@ -1,6 +1,8 @@
 CMAKE_<LANG>_LINKER_WRAPPER_FLAG
 --------------------------------
 
+.. versionadded:: 3.13
+
 Defines the syntax of compiler driver option to pass options to the linker
 tool. It will be used to translate the ``LINKER:`` prefix in the link options
 (see :command:`add_link_options` and :command:`target_link_options`).
diff --git a/Help/variable/CMAKE_LANG_LINKER_WRAPPER_FLAG_SEP.rst b/Help/variable/CMAKE_LANG_LINKER_WRAPPER_FLAG_SEP.rst
index faf1481..a3895af 100644
--- a/Help/variable/CMAKE_LANG_LINKER_WRAPPER_FLAG_SEP.rst
+++ b/Help/variable/CMAKE_LANG_LINKER_WRAPPER_FLAG_SEP.rst
@@ -1,6 +1,8 @@
 CMAKE_<LANG>_LINKER_WRAPPER_FLAG_SEP
 ------------------------------------
 
+.. versionadded:: 3.13
+
 This variable is used with :variable:`CMAKE_<LANG>_LINKER_WRAPPER_FLAG`
 variable to format ``LINKER:`` prefix in the link options
 (see :command:`add_link_options` and :command:`target_link_options`).
diff --git a/Help/variable/CMAKE_LANG_LINK_LIBRARY_FILE_FLAG.rst b/Help/variable/CMAKE_LANG_LINK_LIBRARY_FILE_FLAG.rst
index d54f080..23ece88 100644
--- a/Help/variable/CMAKE_LANG_LINK_LIBRARY_FILE_FLAG.rst
+++ b/Help/variable/CMAKE_LANG_LINK_LIBRARY_FILE_FLAG.rst
@@ -1,6 +1,8 @@
 CMAKE_<LANG>_LINK_LIBRARY_FILE_FLAG
 -----------------------------------
 
+.. versionadded:: 3.16
+
 Language-specific flag to be used to link a library specified by
 a path to its file.
 
diff --git a/Help/variable/CMAKE_LANG_LINK_LIBRARY_FLAG.rst b/Help/variable/CMAKE_LANG_LINK_LIBRARY_FLAG.rst
index d7bb0d8..0f528db 100644
--- a/Help/variable/CMAKE_LANG_LINK_LIBRARY_FLAG.rst
+++ b/Help/variable/CMAKE_LANG_LINK_LIBRARY_FLAG.rst
@@ -1,6 +1,8 @@
 CMAKE_<LANG>_LINK_LIBRARY_FLAG
 ------------------------------
 
+.. versionadded:: 3.16
+
 Flag to be used to link a library into a shared library or executable.
 
 This flag will be used to specify a library to link to a shared library or an
diff --git a/Help/variable/CMAKE_LANG_LINK_LIBRARY_SUFFIX.rst b/Help/variable/CMAKE_LANG_LINK_LIBRARY_SUFFIX.rst
index a378657..359e29f 100644
--- a/Help/variable/CMAKE_LANG_LINK_LIBRARY_SUFFIX.rst
+++ b/Help/variable/CMAKE_LANG_LINK_LIBRARY_SUFFIX.rst
@@ -1,6 +1,8 @@
 CMAKE_<LANG>_LINK_LIBRARY_SUFFIX
 --------------------------------
 
+.. versionadded:: 3.16
+
 Language-specific suffix for libraries that you link to.
 
 The suffix to use for the end of a library filename, ``.lib`` on Windows.
diff --git a/Help/variable/CMAKE_LANG_STANDARD_INCLUDE_DIRECTORIES.rst b/Help/variable/CMAKE_LANG_STANDARD_INCLUDE_DIRECTORIES.rst
index c8e3d57..24aca8b 100644
--- a/Help/variable/CMAKE_LANG_STANDARD_INCLUDE_DIRECTORIES.rst
+++ b/Help/variable/CMAKE_LANG_STANDARD_INCLUDE_DIRECTORIES.rst
@@ -1,6 +1,8 @@
 CMAKE_<LANG>_STANDARD_INCLUDE_DIRECTORIES
 -----------------------------------------
 
+.. versionadded:: 3.6
+
 Include directories to be used for every source file compiled with
 the ``<LANG>`` compiler.  This is meant for specification of system
 include directories needed by the language for the current platform.
diff --git a/Help/variable/CMAKE_LANG_STANDARD_LIBRARIES.rst b/Help/variable/CMAKE_LANG_STANDARD_LIBRARIES.rst
index ba6df93..d5f3351 100644
--- a/Help/variable/CMAKE_LANG_STANDARD_LIBRARIES.rst
+++ b/Help/variable/CMAKE_LANG_STANDARD_LIBRARIES.rst
@@ -1,6 +1,8 @@
 CMAKE_<LANG>_STANDARD_LIBRARIES
 -------------------------------
 
+.. versionadded:: 3.6
+
 Libraries linked into every executable and shared library linked
 for language ``<LANG>``.  This is meant for specification of system
 libraries needed by the language for the current platform.
diff --git a/Help/variable/CMAKE_LIBRARY_OUTPUT_DIRECTORY_CONFIG.rst b/Help/variable/CMAKE_LIBRARY_OUTPUT_DIRECTORY_CONFIG.rst
index e069cdd..08f95c4 100644
--- a/Help/variable/CMAKE_LIBRARY_OUTPUT_DIRECTORY_CONFIG.rst
+++ b/Help/variable/CMAKE_LIBRARY_OUTPUT_DIRECTORY_CONFIG.rst
@@ -1,6 +1,8 @@
 CMAKE_LIBRARY_OUTPUT_DIRECTORY_<CONFIG>
 ---------------------------------------
 
+.. versionadded:: 3.3
+
 Where to put all the :ref:`LIBRARY <Library Output Artifacts>`
 target files when built for a specific configuration.
 
diff --git a/Help/variable/CMAKE_LINK_DIRECTORIES_BEFORE.rst b/Help/variable/CMAKE_LINK_DIRECTORIES_BEFORE.rst
index 026ca35..f120866 100644
--- a/Help/variable/CMAKE_LINK_DIRECTORIES_BEFORE.rst
+++ b/Help/variable/CMAKE_LINK_DIRECTORIES_BEFORE.rst
@@ -1,6 +1,8 @@
 CMAKE_LINK_DIRECTORIES_BEFORE
 -----------------------------
 
+.. versionadded:: 3.13
+
 Whether to append or prepend directories by default in
 :command:`link_directories`.
 
diff --git a/Help/variable/CMAKE_LINK_SEARCH_END_STATIC.rst b/Help/variable/CMAKE_LINK_SEARCH_END_STATIC.rst
index 54cdaaa..f4ccc04 100644
--- a/Help/variable/CMAKE_LINK_SEARCH_END_STATIC.rst
+++ b/Help/variable/CMAKE_LINK_SEARCH_END_STATIC.rst
@@ -1,6 +1,8 @@
 CMAKE_LINK_SEARCH_END_STATIC
 ----------------------------
 
+.. versionadded:: 3.4
+
 End a link line such that static system libraries are used.
 
 Some linkers support switches such as ``-Bstatic`` and ``-Bdynamic`` to
diff --git a/Help/variable/CMAKE_LINK_SEARCH_START_STATIC.rst b/Help/variable/CMAKE_LINK_SEARCH_START_STATIC.rst
index 0d52a31..2025c72 100644
--- a/Help/variable/CMAKE_LINK_SEARCH_START_STATIC.rst
+++ b/Help/variable/CMAKE_LINK_SEARCH_START_STATIC.rst
@@ -1,6 +1,8 @@
 CMAKE_LINK_SEARCH_START_STATIC
 ------------------------------
 
+.. versionadded:: 3.4
+
 Assume the linker looks for static libraries by default.
 
 Some linkers support switches such as ``-Bstatic`` and ``-Bdynamic`` to
diff --git a/Help/variable/CMAKE_LINK_WHAT_YOU_USE.rst b/Help/variable/CMAKE_LINK_WHAT_YOU_USE.rst
index 90c4d3f..06b3aa8 100644
--- a/Help/variable/CMAKE_LINK_WHAT_YOU_USE.rst
+++ b/Help/variable/CMAKE_LINK_WHAT_YOU_USE.rst
@@ -1,6 +1,8 @@
 CMAKE_LINK_WHAT_YOU_USE
 ---------------------------------
 
+.. versionadded:: 3.7
+
 Default value for :prop_tgt:`LINK_WHAT_YOU_USE` target property.
 This variable is used to initialize the property on each target as it is
 created.
diff --git a/Help/variable/CMAKE_MATCH_COUNT.rst b/Help/variable/CMAKE_MATCH_COUNT.rst
index 355e834..deeec8b 100644
--- a/Help/variable/CMAKE_MATCH_COUNT.rst
+++ b/Help/variable/CMAKE_MATCH_COUNT.rst
@@ -1,6 +1,8 @@
 CMAKE_MATCH_COUNT
 -----------------
 
+.. versionadded:: 3.2
+
 The number of matches with the last regular expression.
 
 When a regular expression match is used, CMake fills in
diff --git a/Help/variable/CMAKE_MATCH_n.rst b/Help/variable/CMAKE_MATCH_n.rst
index c7dd623..a92788e 100644
--- a/Help/variable/CMAKE_MATCH_n.rst
+++ b/Help/variable/CMAKE_MATCH_n.rst
@@ -1,6 +1,8 @@
 CMAKE_MATCH_<n>
 ---------------
 
+.. versionadded:: 3.9
+
 Capture group ``<n>`` matched by the last regular expression, for groups
 0 through 9.  Group 0 is the entire match.  Groups 1 through 9 are the
 subexpressions captured by ``()`` syntax.
diff --git a/Help/variable/CMAKE_MAXIMUM_RECURSION_DEPTH.rst b/Help/variable/CMAKE_MAXIMUM_RECURSION_DEPTH.rst
index 7110b16..59c60d3 100644
--- a/Help/variable/CMAKE_MAXIMUM_RECURSION_DEPTH.rst
+++ b/Help/variable/CMAKE_MAXIMUM_RECURSION_DEPTH.rst
@@ -1,6 +1,8 @@
 CMAKE_MAXIMUM_RECURSION_DEPTH
 -----------------------------
 
+.. versionadded:: 3.14
+
 Maximum recursion depth for CMake scripts. It is intended to be set on the
 command line with ``-DCMAKE_MAXIMUM_RECURSION_DEPTH=<x>``, or within
 ``CMakeLists.txt`` by projects that require a large recursion depth. Projects
diff --git a/Help/variable/CMAKE_MESSAGE_CONTEXT.rst b/Help/variable/CMAKE_MESSAGE_CONTEXT.rst
index 6b4ca40..41ace43 100644
--- a/Help/variable/CMAKE_MESSAGE_CONTEXT.rst
+++ b/Help/variable/CMAKE_MESSAGE_CONTEXT.rst
@@ -1,6 +1,8 @@
 CMAKE_MESSAGE_CONTEXT
 ---------------------
 
+.. versionadded:: 3.17
+
 When enabled by the :manual:`cmake <cmake(1)>` ``--log-context`` command line
 option or the :variable:`CMAKE_MESSAGE_CONTEXT_SHOW` variable, the
 :command:`message` command converts the ``CMAKE_MESSAGE_CONTEXT`` list into a
diff --git a/Help/variable/CMAKE_MESSAGE_CONTEXT_SHOW.rst b/Help/variable/CMAKE_MESSAGE_CONTEXT_SHOW.rst
index 7ec218e..382e9ff 100644
--- a/Help/variable/CMAKE_MESSAGE_CONTEXT_SHOW.rst
+++ b/Help/variable/CMAKE_MESSAGE_CONTEXT_SHOW.rst
@@ -1,6 +1,8 @@
 CMAKE_MESSAGE_CONTEXT_SHOW
 --------------------------
 
+.. versionadded:: 3.17
+
 Setting this variable to true enables showing a context with each line
 logged by the :command:`message` command (see :variable:`CMAKE_MESSAGE_CONTEXT`
 for how the context itself is specified).
diff --git a/Help/variable/CMAKE_MESSAGE_INDENT.rst b/Help/variable/CMAKE_MESSAGE_INDENT.rst
index 7e44a4c..c6263d2 100644
--- a/Help/variable/CMAKE_MESSAGE_INDENT.rst
+++ b/Help/variable/CMAKE_MESSAGE_INDENT.rst
@@ -1,6 +1,8 @@
 CMAKE_MESSAGE_INDENT
 --------------------
 
+.. versionadded:: 3.16
+
 The :command:`message` command joins the strings from this list and for
 log levels of ``NOTICE`` and below, it prepends the resultant string to
 each line of the message.
diff --git a/Help/variable/CMAKE_MESSAGE_LOG_LEVEL.rst b/Help/variable/CMAKE_MESSAGE_LOG_LEVEL.rst
index 1d4cfe6..3b45d1d 100644
--- a/Help/variable/CMAKE_MESSAGE_LOG_LEVEL.rst
+++ b/Help/variable/CMAKE_MESSAGE_LOG_LEVEL.rst
@@ -1,6 +1,8 @@
 CMAKE_MESSAGE_LOG_LEVEL
 -----------------------
 
+.. versionadded:: 3.17
+
 When set, this variable specifies the logging level used by the
 :command:`message` command.  Valid values are the same as those for the
 ``--log-level`` command line option of the :manual:`cmake(1)` program.
diff --git a/Help/variable/CMAKE_MODULE_LINKER_FLAGS_CONFIG_INIT.rst b/Help/variable/CMAKE_MODULE_LINKER_FLAGS_CONFIG_INIT.rst
index 3279014..e8a6401 100644
--- a/Help/variable/CMAKE_MODULE_LINKER_FLAGS_CONFIG_INIT.rst
+++ b/Help/variable/CMAKE_MODULE_LINKER_FLAGS_CONFIG_INIT.rst
@@ -1,6 +1,8 @@
 CMAKE_MODULE_LINKER_FLAGS_<CONFIG>_INIT
 ---------------------------------------
 
+.. versionadded:: 3.7
+
 Value used to initialize the :variable:`CMAKE_MODULE_LINKER_FLAGS_<CONFIG>`
 cache entry the first time a build tree is configured.
 This variable is meant to be set by a :variable:`toolchain file
diff --git a/Help/variable/CMAKE_MODULE_LINKER_FLAGS_INIT.rst b/Help/variable/CMAKE_MODULE_LINKER_FLAGS_INIT.rst
index 91b39f6..d59e9bf 100644
--- a/Help/variable/CMAKE_MODULE_LINKER_FLAGS_INIT.rst
+++ b/Help/variable/CMAKE_MODULE_LINKER_FLAGS_INIT.rst
@@ -1,6 +1,8 @@
 CMAKE_MODULE_LINKER_FLAGS_INIT
 ------------------------------
 
+.. versionadded:: 3.7
+
 Value used to initialize the :variable:`CMAKE_MODULE_LINKER_FLAGS`
 cache entry the first time a build tree is configured.
 This variable is meant to be set by a :variable:`toolchain file
diff --git a/Help/variable/CMAKE_MSVCIDE_RUN_PATH.rst b/Help/variable/CMAKE_MSVCIDE_RUN_PATH.rst
index 22e727f..721ceaa 100644
--- a/Help/variable/CMAKE_MSVCIDE_RUN_PATH.rst
+++ b/Help/variable/CMAKE_MSVCIDE_RUN_PATH.rst
@@ -1,6 +1,8 @@
 CMAKE_MSVCIDE_RUN_PATH
 ----------------------
 
+.. versionadded:: 3.10
+
 Extra PATH locations that should be used when executing
 :command:`add_custom_command` or :command:`add_custom_target` when using the
 :generator:`Visual Studio 9 2008` (or above) generator. This allows
diff --git a/Help/variable/CMAKE_MSVC_RUNTIME_LIBRARY.rst b/Help/variable/CMAKE_MSVC_RUNTIME_LIBRARY.rst
index 8b54e7e..14806e6 100644
--- a/Help/variable/CMAKE_MSVC_RUNTIME_LIBRARY.rst
+++ b/Help/variable/CMAKE_MSVC_RUNTIME_LIBRARY.rst
@@ -1,6 +1,8 @@
 CMAKE_MSVC_RUNTIME_LIBRARY
 --------------------------
 
+.. versionadded:: 3.15
+
 Select the MSVC runtime library for use by compilers targeting the MSVC ABI.
 This variable is used to initialize the :prop_tgt:`MSVC_RUNTIME_LIBRARY`
 property on all targets as they are created.  It is also propagated by
diff --git a/Help/variable/CMAKE_NETRC.rst b/Help/variable/CMAKE_NETRC.rst
index 903ec31..2c64a81 100644
--- a/Help/variable/CMAKE_NETRC.rst
+++ b/Help/variable/CMAKE_NETRC.rst
@@ -1,6 +1,8 @@
 CMAKE_NETRC
 -----------
 
+.. versionadded:: 3.11
+
 This variable is used to initialize the ``NETRC`` option for
 :command:`file(DOWNLOAD)` and :command:`file(UPLOAD)` commands and the
 module :module:`ExternalProject`. See those commands for additional
diff --git a/Help/variable/CMAKE_NETRC_FILE.rst b/Help/variable/CMAKE_NETRC_FILE.rst
index 0f09afe..97a645e 100644
--- a/Help/variable/CMAKE_NETRC_FILE.rst
+++ b/Help/variable/CMAKE_NETRC_FILE.rst
@@ -1,6 +1,8 @@
 CMAKE_NETRC_FILE
 ----------------
 
+.. versionadded:: 3.11
+
 This variable is used to initialize the ``NETRC_FILE`` option for
 :command:`file(DOWNLOAD)` and :command:`file(UPLOAD)` commands and the
 module :module:`ExternalProject`. See those commands for additional
diff --git a/Help/variable/CMAKE_NINJA_OUTPUT_PATH_PREFIX.rst b/Help/variable/CMAKE_NINJA_OUTPUT_PATH_PREFIX.rst
index 64091aa..a8c4035 100644
--- a/Help/variable/CMAKE_NINJA_OUTPUT_PATH_PREFIX.rst
+++ b/Help/variable/CMAKE_NINJA_OUTPUT_PATH_PREFIX.rst
@@ -1,6 +1,8 @@
 CMAKE_NINJA_OUTPUT_PATH_PREFIX
 ------------------------------
 
+.. versionadded:: 3.6
+
 Set output files path prefix for the :generator:`Ninja` generator.
 
 Every output files listed in the generated ``build.ninja`` will be
diff --git a/Help/variable/CMAKE_OBJCXX_EXTENSIONS.rst b/Help/variable/CMAKE_OBJCXX_EXTENSIONS.rst
index 8afa6f2..b5225ea 100644
--- a/Help/variable/CMAKE_OBJCXX_EXTENSIONS.rst
+++ b/Help/variable/CMAKE_OBJCXX_EXTENSIONS.rst
@@ -1,6 +1,8 @@
 CMAKE_OBJCXX_EXTENSIONS
 -----------------------
 
+.. versionadded:: 3.16
+
 Default value for :prop_tgt:`OBJCXX_EXTENSIONS` property of targets.
 
 This variable is used to initialize the :prop_tgt:`OBJCXX_EXTENSIONS`
diff --git a/Help/variable/CMAKE_OBJCXX_STANDARD.rst b/Help/variable/CMAKE_OBJCXX_STANDARD.rst
index 4e5016a..98e4624 100644
--- a/Help/variable/CMAKE_OBJCXX_STANDARD.rst
+++ b/Help/variable/CMAKE_OBJCXX_STANDARD.rst
@@ -1,6 +1,8 @@
 CMAKE_OBJCXX_STANDARD
 ---------------------
 
+.. versionadded:: 3.16
+
 Default value for :prop_tgt:`OBJCXX_STANDARD` property of targets.
 
 This variable is used to initialize the :prop_tgt:`OBJCXX_STANDARD`
diff --git a/Help/variable/CMAKE_OBJCXX_STANDARD_REQUIRED.rst b/Help/variable/CMAKE_OBJCXX_STANDARD_REQUIRED.rst
index 3a0602a..4b5e77c 100644
--- a/Help/variable/CMAKE_OBJCXX_STANDARD_REQUIRED.rst
+++ b/Help/variable/CMAKE_OBJCXX_STANDARD_REQUIRED.rst
@@ -1,6 +1,8 @@
 CMAKE_OBJCXX_STANDARD_REQUIRED
 ------------------------------
 
+.. versionadded:: 3.16
+
 Default value for :prop_tgt:`OBJCXX_STANDARD_REQUIRED` property of targets.
 
 This variable is used to initialize the :prop_tgt:`OBJCXX_STANDARD_REQUIRED`
diff --git a/Help/variable/CMAKE_OBJC_EXTENSIONS.rst b/Help/variable/CMAKE_OBJC_EXTENSIONS.rst
index d9619d8..d6e3c7d 100644
--- a/Help/variable/CMAKE_OBJC_EXTENSIONS.rst
+++ b/Help/variable/CMAKE_OBJC_EXTENSIONS.rst
@@ -1,6 +1,8 @@
 CMAKE_OBJC_EXTENSIONS
 ---------------------
 
+.. versionadded:: 3.16
+
 Default value for :prop_tgt:`OBJC_EXTENSIONS` property of targets.
 
 This variable is used to initialize the :prop_tgt:`OBJC_EXTENSIONS`
diff --git a/Help/variable/CMAKE_OBJC_STANDARD.rst b/Help/variable/CMAKE_OBJC_STANDARD.rst
index 976c441..fde367d 100644
--- a/Help/variable/CMAKE_OBJC_STANDARD.rst
+++ b/Help/variable/CMAKE_OBJC_STANDARD.rst
@@ -1,6 +1,8 @@
 CMAKE_OBJC_STANDARD
 -------------------
 
+.. versionadded:: 3.16
+
 Default value for :prop_tgt:`OBJC_STANDARD` property of targets.
 
 This variable is used to initialize the :prop_tgt:`OBJC_STANDARD`
diff --git a/Help/variable/CMAKE_OBJC_STANDARD_REQUIRED.rst b/Help/variable/CMAKE_OBJC_STANDARD_REQUIRED.rst
index 5c02096..8d26d95 100644
--- a/Help/variable/CMAKE_OBJC_STANDARD_REQUIRED.rst
+++ b/Help/variable/CMAKE_OBJC_STANDARD_REQUIRED.rst
@@ -1,6 +1,8 @@
 CMAKE_OBJC_STANDARD_REQUIRED
 ----------------------------
 
+.. versionadded:: 3.16
+
 Default value for :prop_tgt:`OBJC_STANDARD_REQUIRED` property of targets.
 
 This variable is used to initialize the :prop_tgt:`OBJC_STANDARD_REQUIRED`
diff --git a/Help/variable/CMAKE_PCH_WARN_INVALID.rst b/Help/variable/CMAKE_PCH_WARN_INVALID.rst
index e152abd..457a428 100644
--- a/Help/variable/CMAKE_PCH_WARN_INVALID.rst
+++ b/Help/variable/CMAKE_PCH_WARN_INVALID.rst
@@ -1,5 +1,7 @@
 CMAKE_PCH_WARN_INVALID
 ----------------------
 
+.. versionadded:: 3.18
+
 This variable is used to initialize the :prop_tgt:`PCH_WARN_INVALID`
 property of targets when they are created.
diff --git a/Help/variable/CMAKE_PROJECT_DESCRIPTION.rst b/Help/variable/CMAKE_PROJECT_DESCRIPTION.rst
index 51b0592..95cbe40 100644
--- a/Help/variable/CMAKE_PROJECT_DESCRIPTION.rst
+++ b/Help/variable/CMAKE_PROJECT_DESCRIPTION.rst
@@ -1,6 +1,8 @@
 CMAKE_PROJECT_DESCRIPTION
 -------------------------
 
+.. versionadded:: 3.9
+
 The description of the top level project.
 
 This variable holds the description of the project as specified in the top
diff --git a/Help/variable/CMAKE_PROJECT_HOMEPAGE_URL.rst b/Help/variable/CMAKE_PROJECT_HOMEPAGE_URL.rst
index ee0bf7c..4c5debe 100644
--- a/Help/variable/CMAKE_PROJECT_HOMEPAGE_URL.rst
+++ b/Help/variable/CMAKE_PROJECT_HOMEPAGE_URL.rst
@@ -1,6 +1,8 @@
 CMAKE_PROJECT_HOMEPAGE_URL
 --------------------------
 
+.. versionadded:: 3.12
+
 The homepage URL of the top level project.
 
 This variable holds the homepage URL of the project as specified in the top
diff --git a/Help/variable/CMAKE_PROJECT_INCLUDE.rst b/Help/variable/CMAKE_PROJECT_INCLUDE.rst
index 5835264..41d9e5d 100644
--- a/Help/variable/CMAKE_PROJECT_INCLUDE.rst
+++ b/Help/variable/CMAKE_PROJECT_INCLUDE.rst
@@ -1,6 +1,8 @@
 CMAKE_PROJECT_INCLUDE
 ---------------------
 
+.. versionadded:: 3.15
+
 A CMake language file or module to be included as the last step of all
 :command:`project` command calls.  This is intended for injecting custom code
 into project builds without modifying their source.
diff --git a/Help/variable/CMAKE_PROJECT_INCLUDE_BEFORE.rst b/Help/variable/CMAKE_PROJECT_INCLUDE_BEFORE.rst
index 280c14a..c2fd0f8 100644
--- a/Help/variable/CMAKE_PROJECT_INCLUDE_BEFORE.rst
+++ b/Help/variable/CMAKE_PROJECT_INCLUDE_BEFORE.rst
@@ -1,6 +1,8 @@
 CMAKE_PROJECT_INCLUDE_BEFORE
 ----------------------------
 
+.. versionadded:: 3.15
+
 A CMake language file or module to be included as the first step of all
 :command:`project` command calls.  This is intended for injecting custom code
 into project builds without modifying their source.
diff --git a/Help/variable/CMAKE_PROJECT_PROJECT-NAME_INCLUDE_BEFORE.rst b/Help/variable/CMAKE_PROJECT_PROJECT-NAME_INCLUDE_BEFORE.rst
index db1432d..39abb12 100644
--- a/Help/variable/CMAKE_PROJECT_PROJECT-NAME_INCLUDE_BEFORE.rst
+++ b/Help/variable/CMAKE_PROJECT_PROJECT-NAME_INCLUDE_BEFORE.rst
@@ -1,6 +1,8 @@
 CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE_BEFORE
 -------------------------------------------
 
+.. versionadded:: 3.17
+
 A CMake language file or module to be included as the first step of any
 :command:`project` command calls that specify ``<PROJECT-NAME>`` as the project
 name.  This is intended for injecting custom code into project builds without
diff --git a/Help/variable/CMAKE_PROJECT_VERSION.rst b/Help/variable/CMAKE_PROJECT_VERSION.rst
index 4f8f556..450c136 100644
--- a/Help/variable/CMAKE_PROJECT_VERSION.rst
+++ b/Help/variable/CMAKE_PROJECT_VERSION.rst
@@ -1,6 +1,8 @@
 CMAKE_PROJECT_VERSION
 ---------------------
 
+.. versionadded:: 3.12
+
 The version of the top level project.
 
 This variable holds the version of the project as specified in the top
diff --git a/Help/variable/CMAKE_PROJECT_VERSION_MAJOR.rst b/Help/variable/CMAKE_PROJECT_VERSION_MAJOR.rst
index f1001ac..c7511e7 100644
--- a/Help/variable/CMAKE_PROJECT_VERSION_MAJOR.rst
+++ b/Help/variable/CMAKE_PROJECT_VERSION_MAJOR.rst
@@ -1,6 +1,8 @@
 CMAKE_PROJECT_VERSION_MAJOR
 ---------------------------
 
+.. versionadded:: 3.12
+
 The major version of the top level project.
 
 This variable holds the major version of the project as specified in the top
diff --git a/Help/variable/CMAKE_PROJECT_VERSION_MINOR.rst b/Help/variable/CMAKE_PROJECT_VERSION_MINOR.rst
index 13202be..dd91dcf 100644
--- a/Help/variable/CMAKE_PROJECT_VERSION_MINOR.rst
+++ b/Help/variable/CMAKE_PROJECT_VERSION_MINOR.rst
@@ -1,6 +1,8 @@
 CMAKE_PROJECT_VERSION_MINOR
 ---------------------------
 
+.. versionadded:: 3.12
+
 The minor version of the top level project.
 
 This variable holds the minor version of the project as specified in the top
diff --git a/Help/variable/CMAKE_PROJECT_VERSION_PATCH.rst b/Help/variable/CMAKE_PROJECT_VERSION_PATCH.rst
index b8570d9..61fd1f3 100644
--- a/Help/variable/CMAKE_PROJECT_VERSION_PATCH.rst
+++ b/Help/variable/CMAKE_PROJECT_VERSION_PATCH.rst
@@ -1,6 +1,8 @@
 CMAKE_PROJECT_VERSION_PATCH
 ---------------------------
 
+.. versionadded:: 3.12
+
 The patch version of the top level project.
 
 This variable holds the patch version of the project as specified in the top
diff --git a/Help/variable/CMAKE_PROJECT_VERSION_TWEAK.rst b/Help/variable/CMAKE_PROJECT_VERSION_TWEAK.rst
index e1ad4be..0deae8b 100644
--- a/Help/variable/CMAKE_PROJECT_VERSION_TWEAK.rst
+++ b/Help/variable/CMAKE_PROJECT_VERSION_TWEAK.rst
@@ -1,6 +1,8 @@
 CMAKE_PROJECT_VERSION_TWEAK
 ---------------------------
 
+.. versionadded:: 3.12
+
 The tweak version of the top level project.
 
 This variable holds the tweak version of the project as specified in the top
diff --git a/Help/variable/CMAKE_RULE_MESSAGES.rst b/Help/variable/CMAKE_RULE_MESSAGES.rst
index 7460a81..39be2e9 100644
--- a/Help/variable/CMAKE_RULE_MESSAGES.rst
+++ b/Help/variable/CMAKE_RULE_MESSAGES.rst
@@ -1,6 +1,8 @@
 CMAKE_RULE_MESSAGES
 -------------------
 
+.. versionadded:: 3.13
+
 Specify whether to report a message for each make rule.
 
 If set in the cache it is used to initialize the value of the :prop_gbl:`RULE_MESSAGES` property.
diff --git a/Help/variable/CMAKE_RUNTIME_OUTPUT_DIRECTORY_CONFIG.rst b/Help/variable/CMAKE_RUNTIME_OUTPUT_DIRECTORY_CONFIG.rst
index 080dea6..c9c55c5 100644
--- a/Help/variable/CMAKE_RUNTIME_OUTPUT_DIRECTORY_CONFIG.rst
+++ b/Help/variable/CMAKE_RUNTIME_OUTPUT_DIRECTORY_CONFIG.rst
@@ -1,6 +1,8 @@
 CMAKE_RUNTIME_OUTPUT_DIRECTORY_<CONFIG>
 ---------------------------------------
 
+.. versionadded:: 3.3
+
 Where to put all the :ref:`RUNTIME <Runtime Output Artifacts>`
 target files when built for a specific configuration.
 
diff --git a/Help/variable/CMAKE_SHARED_LINKER_FLAGS_CONFIG_INIT.rst b/Help/variable/CMAKE_SHARED_LINKER_FLAGS_CONFIG_INIT.rst
index 185df38..7f3dec7 100644
--- a/Help/variable/CMAKE_SHARED_LINKER_FLAGS_CONFIG_INIT.rst
+++ b/Help/variable/CMAKE_SHARED_LINKER_FLAGS_CONFIG_INIT.rst
@@ -1,6 +1,8 @@
 CMAKE_SHARED_LINKER_FLAGS_<CONFIG>_INIT
 ---------------------------------------
 
+.. versionadded:: 3.7
+
 Value used to initialize the :variable:`CMAKE_SHARED_LINKER_FLAGS_<CONFIG>`
 cache entry the first time a build tree is configured.
 This variable is meant to be set by a :variable:`toolchain file
diff --git a/Help/variable/CMAKE_SHARED_LINKER_FLAGS_INIT.rst b/Help/variable/CMAKE_SHARED_LINKER_FLAGS_INIT.rst
index cb819a7..6d51afe 100644
--- a/Help/variable/CMAKE_SHARED_LINKER_FLAGS_INIT.rst
+++ b/Help/variable/CMAKE_SHARED_LINKER_FLAGS_INIT.rst
@@ -1,6 +1,8 @@
 CMAKE_SHARED_LINKER_FLAGS_INIT
 ------------------------------
 
+.. versionadded:: 3.7
+
 Value used to initialize the :variable:`CMAKE_SHARED_LINKER_FLAGS`
 cache entry the first time a build tree is configured.
 This variable is meant to be set by a :variable:`toolchain file
diff --git a/Help/variable/CMAKE_STATIC_LINKER_FLAGS_CONFIG_INIT.rst b/Help/variable/CMAKE_STATIC_LINKER_FLAGS_CONFIG_INIT.rst
index a49d1cb..5e65ef2 100644
--- a/Help/variable/CMAKE_STATIC_LINKER_FLAGS_CONFIG_INIT.rst
+++ b/Help/variable/CMAKE_STATIC_LINKER_FLAGS_CONFIG_INIT.rst
@@ -1,6 +1,8 @@
 CMAKE_STATIC_LINKER_FLAGS_<CONFIG>_INIT
 ---------------------------------------
 
+.. versionadded:: 3.7
+
 Value used to initialize the :variable:`CMAKE_STATIC_LINKER_FLAGS_<CONFIG>`
 cache entry the first time a build tree is configured.
 This variable is meant to be set by a :variable:`toolchain file
diff --git a/Help/variable/CMAKE_STATIC_LINKER_FLAGS_INIT.rst b/Help/variable/CMAKE_STATIC_LINKER_FLAGS_INIT.rst
index 113ca71..cbf681c 100644
--- a/Help/variable/CMAKE_STATIC_LINKER_FLAGS_INIT.rst
+++ b/Help/variable/CMAKE_STATIC_LINKER_FLAGS_INIT.rst
@@ -1,6 +1,8 @@
 CMAKE_STATIC_LINKER_FLAGS_INIT
 ------------------------------
 
+.. versionadded:: 3.7
+
 Value used to initialize the :variable:`CMAKE_STATIC_LINKER_FLAGS`
 cache entry the first time a build tree is configured.
 This variable is meant to be set by a :variable:`toolchain file
diff --git a/Help/variable/CMAKE_SUBLIME_TEXT_2_ENV_SETTINGS.rst b/Help/variable/CMAKE_SUBLIME_TEXT_2_ENV_SETTINGS.rst
index 02c8663..5c1c8d1 100644
--- a/Help/variable/CMAKE_SUBLIME_TEXT_2_ENV_SETTINGS.rst
+++ b/Help/variable/CMAKE_SUBLIME_TEXT_2_ENV_SETTINGS.rst
@@ -1,6 +1,8 @@
 CMAKE_SUBLIME_TEXT_2_ENV_SETTINGS
 ---------------------------------
 
+.. versionadded:: 3.8
+
 This variable contains a list of env vars as a list of tokens with the
 syntax ``var=value``.
 
diff --git a/Help/variable/CMAKE_SUBLIME_TEXT_2_EXCLUDE_BUILD_TREE.rst b/Help/variable/CMAKE_SUBLIME_TEXT_2_EXCLUDE_BUILD_TREE.rst
index d654425..28b0dbd 100644
--- a/Help/variable/CMAKE_SUBLIME_TEXT_2_EXCLUDE_BUILD_TREE.rst
+++ b/Help/variable/CMAKE_SUBLIME_TEXT_2_EXCLUDE_BUILD_TREE.rst
@@ -1,6 +1,8 @@
 CMAKE_SUBLIME_TEXT_2_EXCLUDE_BUILD_TREE
 ---------------------------------------
 
+.. versionadded:: 3.8
+
 If this variable evaluates to ``ON`` at the end of the top-level
 ``CMakeLists.txt`` file, the :generator:`Sublime Text 2` extra generator
 excludes the build tree from the ``.sublime-project`` if it is inside the
diff --git a/Help/variable/CMAKE_SUPPRESS_REGENERATION.rst b/Help/variable/CMAKE_SUPPRESS_REGENERATION.rst
index 96184dd..48490ff 100644
--- a/Help/variable/CMAKE_SUPPRESS_REGENERATION.rst
+++ b/Help/variable/CMAKE_SUPPRESS_REGENERATION.rst
@@ -1,6 +1,8 @@
 CMAKE_SUPPRESS_REGENERATION
 ---------------------------
 
+.. versionadded:: 3.12
+
 If ``CMAKE_SUPPRESS_REGENERATION`` is ``OFF``, which is default, then CMake
 adds a special target on which all other targets depend that checks the build
 system and optionally re-runs CMake to regenerate the build system when
diff --git a/Help/variable/CMAKE_SYSROOT_COMPILE.rst b/Help/variable/CMAKE_SYSROOT_COMPILE.rst
index e96c62b..4aea48e 100644
--- a/Help/variable/CMAKE_SYSROOT_COMPILE.rst
+++ b/Help/variable/CMAKE_SYSROOT_COMPILE.rst
@@ -1,6 +1,8 @@
 CMAKE_SYSROOT_COMPILE
 ---------------------
 
+.. versionadded:: 3.9
+
 Path to pass to the compiler in the ``--sysroot`` flag when compiling source
 files.  This is the same as :variable:`CMAKE_SYSROOT` but is used only for
 compiling sources and not linking.
diff --git a/Help/variable/CMAKE_SYSROOT_LINK.rst b/Help/variable/CMAKE_SYSROOT_LINK.rst
index 88b48ef..9749b7b 100644
--- a/Help/variable/CMAKE_SYSROOT_LINK.rst
+++ b/Help/variable/CMAKE_SYSROOT_LINK.rst
@@ -1,6 +1,8 @@
 CMAKE_SYSROOT_LINK
 ------------------
 
+.. versionadded:: 3.9
+
 Path to pass to the compiler in the ``--sysroot`` flag when linking.  This is
 the same as :variable:`CMAKE_SYSROOT` but is used only for linking and not
 compiling sources.
diff --git a/Help/variable/CMAKE_SYSTEM_APPBUNDLE_PATH.rst b/Help/variable/CMAKE_SYSTEM_APPBUNDLE_PATH.rst
index 666af46..06a99a8 100644
--- a/Help/variable/CMAKE_SYSTEM_APPBUNDLE_PATH.rst
+++ b/Help/variable/CMAKE_SYSTEM_APPBUNDLE_PATH.rst
@@ -1,6 +1,8 @@
 CMAKE_SYSTEM_APPBUNDLE_PATH
 ---------------------------
 
+.. versionadded:: 3.4
+
 Search path for macOS application bundles used by the :command:`find_program`,
 and :command:`find_package` commands.  By default it contains the standard
 directories for the current system.  It is *not* intended to be modified by
diff --git a/Help/variable/CMAKE_SYSTEM_FRAMEWORK_PATH.rst b/Help/variable/CMAKE_SYSTEM_FRAMEWORK_PATH.rst
index 14ba18e..1a402c1 100644
--- a/Help/variable/CMAKE_SYSTEM_FRAMEWORK_PATH.rst
+++ b/Help/variable/CMAKE_SYSTEM_FRAMEWORK_PATH.rst
@@ -1,6 +1,8 @@
 CMAKE_SYSTEM_FRAMEWORK_PATH
 ---------------------------
 
+.. versionadded:: 3.4
+
 Search path for macOS frameworks used by the :command:`find_library`,
 :command:`find_package`, :command:`find_path`, and :command:`find_file`
 commands.  By default it contains the standard directories for the
diff --git a/Help/variable/CMAKE_Swift_LANGUAGE_VERSION.rst b/Help/variable/CMAKE_Swift_LANGUAGE_VERSION.rst
index b4a74eb..fce6fa7 100644
--- a/Help/variable/CMAKE_Swift_LANGUAGE_VERSION.rst
+++ b/Help/variable/CMAKE_Swift_LANGUAGE_VERSION.rst
@@ -1,6 +1,8 @@
 CMAKE_Swift_LANGUAGE_VERSION
 ----------------------------
 
+.. versionadded:: 3.7
+
 Set to the Swift language version number.  If not set, the oldest legacy
 version known to be available in the host Xcode version is assumed:
 
diff --git a/Help/variable/CMAKE_Swift_MODULE_DIRECTORY.rst b/Help/variable/CMAKE_Swift_MODULE_DIRECTORY.rst
index b11253b..3694973 100644
--- a/Help/variable/CMAKE_Swift_MODULE_DIRECTORY.rst
+++ b/Help/variable/CMAKE_Swift_MODULE_DIRECTORY.rst
@@ -1,6 +1,8 @@
 CMAKE_Swift_MODULE_DIRECTORY
 ----------------------------
 
+.. versionadded:: 3.15
+
 Swift module output directory.
 
 This variable is used to initialise the :prop_tgt:`Swift_MODULE_DIRECTORY`
diff --git a/Help/variable/CMAKE_Swift_NUM_THREADS.rst b/Help/variable/CMAKE_Swift_NUM_THREADS.rst
index cb33678..e1dafb0 100644
--- a/Help/variable/CMAKE_Swift_NUM_THREADS.rst
+++ b/Help/variable/CMAKE_Swift_NUM_THREADS.rst
@@ -1,6 +1,8 @@
 CMAKE_Swift_NUM_THREADS
 -----------------------
 
+.. versionadded:: 3.15.1
+
 Number of threads for parallel compilation for Swift targets.
 
 This variable controls the number of parallel jobs that the swift driver creates
diff --git a/Help/variable/CMAKE_TRY_COMPILE_PLATFORM_VARIABLES.rst b/Help/variable/CMAKE_TRY_COMPILE_PLATFORM_VARIABLES.rst
index 0f96787..d178513 100644
--- a/Help/variable/CMAKE_TRY_COMPILE_PLATFORM_VARIABLES.rst
+++ b/Help/variable/CMAKE_TRY_COMPILE_PLATFORM_VARIABLES.rst
@@ -1,6 +1,8 @@
 CMAKE_TRY_COMPILE_PLATFORM_VARIABLES
 ------------------------------------
 
+.. versionadded:: 3.6
+
 List of variables that the :command:`try_compile` command source file signature
 must propagate into the test project in order to target the same platform as
 the host project.
diff --git a/Help/variable/CMAKE_TRY_COMPILE_TARGET_TYPE.rst b/Help/variable/CMAKE_TRY_COMPILE_TARGET_TYPE.rst
index 5fa8dfc..b60539f 100644
--- a/Help/variable/CMAKE_TRY_COMPILE_TARGET_TYPE.rst
+++ b/Help/variable/CMAKE_TRY_COMPILE_TARGET_TYPE.rst
@@ -1,6 +1,8 @@
 CMAKE_TRY_COMPILE_TARGET_TYPE
 -----------------------------
 
+.. versionadded:: 3.6
+
 Type of target generated for :command:`try_compile` calls using the
 source file signature.  Valid values are:
 
diff --git a/Help/variable/CMAKE_UNITY_BUILD.rst b/Help/variable/CMAKE_UNITY_BUILD.rst
index a86cd67..54a781a 100644
--- a/Help/variable/CMAKE_UNITY_BUILD.rst
+++ b/Help/variable/CMAKE_UNITY_BUILD.rst
@@ -1,6 +1,8 @@
 CMAKE_UNITY_BUILD
 -----------------
 
+.. versionadded:: 3.16
+
 This variable is used to initialize the :prop_tgt:`UNITY_BUILD`
 property of targets when they are created.  Setting it to true
 enables batch compilation of multiple sources within each target.
diff --git a/Help/variable/CMAKE_UNITY_BUILD_BATCH_SIZE.rst b/Help/variable/CMAKE_UNITY_BUILD_BATCH_SIZE.rst
index 7988d4b..7733fe8 100644
--- a/Help/variable/CMAKE_UNITY_BUILD_BATCH_SIZE.rst
+++ b/Help/variable/CMAKE_UNITY_BUILD_BATCH_SIZE.rst
@@ -1,6 +1,8 @@
 CMAKE_UNITY_BUILD_BATCH_SIZE
 ----------------------------
 
+.. versionadded:: 3.16
+
 This variable is used to initialize the :prop_tgt:`UNITY_BUILD_BATCH_SIZE`
 property of targets when they are created.  It specifies the default upper
 limit on the number of source files that may be combined in any one unity
diff --git a/Help/variable/CMAKE_VS_GLOBALS.rst b/Help/variable/CMAKE_VS_GLOBALS.rst
index 83777b6..d4514fe 100644
--- a/Help/variable/CMAKE_VS_GLOBALS.rst
+++ b/Help/variable/CMAKE_VS_GLOBALS.rst
@@ -1,6 +1,8 @@
 CMAKE_VS_GLOBALS
 ----------------
 
+.. versionadded:: 3.13
+
 List of ``Key=Value`` records to be set per target as target properties
 :prop_tgt:`VS_GLOBAL_<variable>` with ``variable=Key`` and value ``Value``.
 
diff --git a/Help/variable/CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD.rst b/Help/variable/CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD.rst
index f54472a..ace94e4 100644
--- a/Help/variable/CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD.rst
+++ b/Help/variable/CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD.rst
@@ -1,6 +1,8 @@
 CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD
 -----------------------------------------
 
+.. versionadded:: 3.3
+
 Include ``INSTALL`` target to default build.
 
 In Visual Studio solution, by default the ``INSTALL`` target will not be part
diff --git a/Help/variable/CMAKE_VS_INCLUDE_PACKAGE_TO_DEFAULT_BUILD.rst b/Help/variable/CMAKE_VS_INCLUDE_PACKAGE_TO_DEFAULT_BUILD.rst
index 693ba45..ab4d0fa 100644
--- a/Help/variable/CMAKE_VS_INCLUDE_PACKAGE_TO_DEFAULT_BUILD.rst
+++ b/Help/variable/CMAKE_VS_INCLUDE_PACKAGE_TO_DEFAULT_BUILD.rst
@@ -1,6 +1,8 @@
 CMAKE_VS_INCLUDE_PACKAGE_TO_DEFAULT_BUILD
 -----------------------------------------
 
+.. versionadded:: 3.8
+
 Include ``PACKAGE`` target to default build.
 
 In Visual Studio solution, by default the ``PACKAGE`` target will not be part
diff --git a/Help/variable/CMAKE_VS_JUST_MY_CODE_DEBUGGING.rst b/Help/variable/CMAKE_VS_JUST_MY_CODE_DEBUGGING.rst
index 546cdf4..0a02a32 100644
--- a/Help/variable/CMAKE_VS_JUST_MY_CODE_DEBUGGING.rst
+++ b/Help/variable/CMAKE_VS_JUST_MY_CODE_DEBUGGING.rst
@@ -1,6 +1,8 @@
 CMAKE_VS_JUST_MY_CODE_DEBUGGING
 -------------------------------
 
+.. versionadded:: 3.15
+
 Enable Just My Code with Visual Studio debugger.
 
 This variable is used to initialize the :prop_tgt:`VS_JUST_MY_CODE_DEBUGGING`
diff --git a/Help/variable/CMAKE_VS_NsightTegra_VERSION.rst b/Help/variable/CMAKE_VS_NsightTegra_VERSION.rst
index 386c3a9..2982b39 100644
--- a/Help/variable/CMAKE_VS_NsightTegra_VERSION.rst
+++ b/Help/variable/CMAKE_VS_NsightTegra_VERSION.rst
@@ -1,6 +1,8 @@
 CMAKE_VS_NsightTegra_VERSION
 ----------------------------
 
+.. versionadded:: 3.1
+
 When using a Visual Studio generator with the
 :variable:`CMAKE_SYSTEM_NAME` variable set to ``Android``,
 this variable contains the version number of the
diff --git a/Help/variable/CMAKE_VS_PLATFORM_NAME.rst b/Help/variable/CMAKE_VS_PLATFORM_NAME.rst
index 7a4642a..7d08add 100644
--- a/Help/variable/CMAKE_VS_PLATFORM_NAME.rst
+++ b/Help/variable/CMAKE_VS_PLATFORM_NAME.rst
@@ -1,6 +1,8 @@
 CMAKE_VS_PLATFORM_NAME
 ----------------------
 
+.. versionadded:: 3.1
+
 Visual Studio target platform name used by the current generator.
 
 VS 8 and above allow project files to specify a target platform.
diff --git a/Help/variable/CMAKE_VS_PLATFORM_NAME_DEFAULT.rst b/Help/variable/CMAKE_VS_PLATFORM_NAME_DEFAULT.rst
index c18e6fd..6440174 100644
--- a/Help/variable/CMAKE_VS_PLATFORM_NAME_DEFAULT.rst
+++ b/Help/variable/CMAKE_VS_PLATFORM_NAME_DEFAULT.rst
@@ -1,6 +1,8 @@
 CMAKE_VS_PLATFORM_NAME_DEFAULT
 ------------------------------
 
+.. versionadded:: 3.14.3
+
 Default for the Visual Studio target platform name for the current generator
 without considering the value of the :variable:`CMAKE_GENERATOR_PLATFORM`
 variable.  For :ref:`Visual Studio Generators` for VS 2017 and below this is
diff --git a/Help/variable/CMAKE_VS_PLATFORM_TOOLSET_CUDA.rst b/Help/variable/CMAKE_VS_PLATFORM_TOOLSET_CUDA.rst
index 67b7f74..e66378d 100644
--- a/Help/variable/CMAKE_VS_PLATFORM_TOOLSET_CUDA.rst
+++ b/Help/variable/CMAKE_VS_PLATFORM_TOOLSET_CUDA.rst
@@ -1,6 +1,8 @@
 CMAKE_VS_PLATFORM_TOOLSET_CUDA
 ------------------------------
 
+.. versionadded:: 3.9
+
 NVIDIA CUDA Toolkit version whose Visual Studio toolset to use.
 
 The :ref:`Visual Studio Generators` for VS 2010 and above support using
diff --git a/Help/variable/CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR.rst b/Help/variable/CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR.rst
index 060648a..74db6b1 100644
--- a/Help/variable/CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR.rst
+++ b/Help/variable/CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR.rst
@@ -1,6 +1,8 @@
 CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR
 -----------------------------------------
 
+.. versionadded:: 3.16
+
 Path to standalone NVIDIA CUDA Toolkit (eg. extracted from installer).
 
 The :ref:`Visual Studio Generators` for VS 2010 and above support using
diff --git a/Help/variable/CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE.rst b/Help/variable/CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE.rst
index 99ac90d..84d7212 100644
--- a/Help/variable/CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE.rst
+++ b/Help/variable/CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE.rst
@@ -1,6 +1,8 @@
 CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE
 -------------------------------------------
 
+.. versionadded:: 3.8
+
 Visual Studio preferred tool architecture.
 
 The :ref:`Visual Studio Generators` for VS 2013 and above support using
diff --git a/Help/variable/CMAKE_VS_PLATFORM_TOOLSET_VERSION.rst b/Help/variable/CMAKE_VS_PLATFORM_TOOLSET_VERSION.rst
index 4d9b978..64f2e39 100644
--- a/Help/variable/CMAKE_VS_PLATFORM_TOOLSET_VERSION.rst
+++ b/Help/variable/CMAKE_VS_PLATFORM_TOOLSET_VERSION.rst
@@ -1,6 +1,8 @@
 CMAKE_VS_PLATFORM_TOOLSET_VERSION
 ---------------------------------
 
+.. versionadded:: 3.12
+
 Visual Studio Platform Toolset version.
 
 The :ref:`Visual Studio Generators` for VS 2017 and above allow to
diff --git a/Help/variable/CMAKE_VS_SDK_EXCLUDE_DIRECTORIES.rst b/Help/variable/CMAKE_VS_SDK_EXCLUDE_DIRECTORIES.rst
index 36c4dcc..969f328 100644
--- a/Help/variable/CMAKE_VS_SDK_EXCLUDE_DIRECTORIES.rst
+++ b/Help/variable/CMAKE_VS_SDK_EXCLUDE_DIRECTORIES.rst
@@ -1,4 +1,6 @@
 CMAKE_VS_SDK_EXCLUDE_DIRECTORIES
 --------------------------------
 
+.. versionadded:: 3.12
+
 This variable allows to override Visual Studio default Exclude Directories.
diff --git a/Help/variable/CMAKE_VS_SDK_EXECUTABLE_DIRECTORIES.rst b/Help/variable/CMAKE_VS_SDK_EXECUTABLE_DIRECTORIES.rst
index 3ec755b..7455e10 100644
--- a/Help/variable/CMAKE_VS_SDK_EXECUTABLE_DIRECTORIES.rst
+++ b/Help/variable/CMAKE_VS_SDK_EXECUTABLE_DIRECTORIES.rst
@@ -1,4 +1,6 @@
 CMAKE_VS_SDK_EXECUTABLE_DIRECTORIES
 -----------------------------------
 
+.. versionadded:: 3.12
+
 This variable allows to override Visual Studio default Executable Directories.
diff --git a/Help/variable/CMAKE_VS_SDK_INCLUDE_DIRECTORIES.rst b/Help/variable/CMAKE_VS_SDK_INCLUDE_DIRECTORIES.rst
index da10bde..3f27aea 100644
--- a/Help/variable/CMAKE_VS_SDK_INCLUDE_DIRECTORIES.rst
+++ b/Help/variable/CMAKE_VS_SDK_INCLUDE_DIRECTORIES.rst
@@ -1,4 +1,6 @@
 CMAKE_VS_SDK_INCLUDE_DIRECTORIES
 --------------------------------
 
+.. versionadded:: 3.12
+
 This variable allows to override Visual Studio default Include Directories.
diff --git a/Help/variable/CMAKE_VS_SDK_LIBRARY_DIRECTORIES.rst b/Help/variable/CMAKE_VS_SDK_LIBRARY_DIRECTORIES.rst
index b33754a..35e45a3 100644
--- a/Help/variable/CMAKE_VS_SDK_LIBRARY_DIRECTORIES.rst
+++ b/Help/variable/CMAKE_VS_SDK_LIBRARY_DIRECTORIES.rst
@@ -1,4 +1,6 @@
 CMAKE_VS_SDK_LIBRARY_DIRECTORIES
 --------------------------------
 
+.. versionadded:: 3.12
+
 This variable allows to override Visual Studio default Library Directories.
diff --git a/Help/variable/CMAKE_VS_SDK_LIBRARY_WINRT_DIRECTORIES.rst b/Help/variable/CMAKE_VS_SDK_LIBRARY_WINRT_DIRECTORIES.rst
index b022215..24b90b6 100644
--- a/Help/variable/CMAKE_VS_SDK_LIBRARY_WINRT_DIRECTORIES.rst
+++ b/Help/variable/CMAKE_VS_SDK_LIBRARY_WINRT_DIRECTORIES.rst
@@ -1,5 +1,7 @@
 CMAKE_VS_SDK_LIBRARY_WINRT_DIRECTORIES
 --------------------------------------
 
+.. versionadded:: 3.12
+
 This variable allows to override Visual Studio default Library WinRT
 Directories.
diff --git a/Help/variable/CMAKE_VS_SDK_REFERENCE_DIRECTORIES.rst b/Help/variable/CMAKE_VS_SDK_REFERENCE_DIRECTORIES.rst
index c03f0ae..00382fe 100644
--- a/Help/variable/CMAKE_VS_SDK_REFERENCE_DIRECTORIES.rst
+++ b/Help/variable/CMAKE_VS_SDK_REFERENCE_DIRECTORIES.rst
@@ -1,4 +1,6 @@
 CMAKE_VS_SDK_REFERENCE_DIRECTORIES
 ----------------------------------
 
+.. versionadded:: 3.12
+
 This variable allows to override Visual Studio default Reference Directories.
diff --git a/Help/variable/CMAKE_VS_SDK_SOURCE_DIRECTORIES.rst b/Help/variable/CMAKE_VS_SDK_SOURCE_DIRECTORIES.rst
index 0c73f06..b98c999 100644
--- a/Help/variable/CMAKE_VS_SDK_SOURCE_DIRECTORIES.rst
+++ b/Help/variable/CMAKE_VS_SDK_SOURCE_DIRECTORIES.rst
@@ -1,4 +1,6 @@
 CMAKE_VS_SDK_SOURCE_DIRECTORIES
 -------------------------------
 
+.. versionadded:: 3.12
+
 This variable allows to override Visual Studio default Source Directories.
diff --git a/Help/variable/CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION.rst b/Help/variable/CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION.rst
index 83b9bc1..cb55bc2 100644
--- a/Help/variable/CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION.rst
+++ b/Help/variable/CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION.rst
@@ -1,6 +1,8 @@
 CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION
 ----------------------------------------
 
+.. versionadded:: 3.4
+
 Visual Studio Windows Target Platform Version.
 
 When targeting Windows 10 and above Visual Studio 2015 and above support
diff --git a/Help/variable/CMAKE_VS_WINRT_BY_DEFAULT.rst b/Help/variable/CMAKE_VS_WINRT_BY_DEFAULT.rst
index 2eea424..9ded85f 100644
--- a/Help/variable/CMAKE_VS_WINRT_BY_DEFAULT.rst
+++ b/Help/variable/CMAKE_VS_WINRT_BY_DEFAULT.rst
@@ -1,6 +1,8 @@
 CMAKE_VS_WINRT_BY_DEFAULT
 -------------------------
 
+.. versionadded:: 3.13
+
 Inform :ref:`Visual Studio Generators` for VS 2010 and above that the
 target platform enables WinRT compilation by default and it needs to
 be explicitly disabled if ``/ZW`` or :prop_tgt:`VS_WINRT_COMPONENT` is
diff --git a/Help/variable/CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS.rst b/Help/variable/CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS.rst
index 1636842..7b01185 100644
--- a/Help/variable/CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS.rst
+++ b/Help/variable/CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS.rst
@@ -1,6 +1,8 @@
 CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS
 --------------------------------
 
+.. versionadded:: 3.4
+
 Default value for :prop_tgt:`WINDOWS_EXPORT_ALL_SYMBOLS` target property.
 This variable is used to initialize the property on each target as it is
 created.
diff --git a/Help/variable/CMAKE_XCODE_ATTRIBUTE_an-attribute.rst b/Help/variable/CMAKE_XCODE_ATTRIBUTE_an-attribute.rst
index be683d6..90e4c0e 100644
--- a/Help/variable/CMAKE_XCODE_ATTRIBUTE_an-attribute.rst
+++ b/Help/variable/CMAKE_XCODE_ATTRIBUTE_an-attribute.rst
@@ -1,6 +1,8 @@
 CMAKE_XCODE_ATTRIBUTE_<an-attribute>
 ------------------------------------
 
+.. versionadded:: 3.1
+
 Set Xcode target attributes directly.
 
 Tell the :generator:`Xcode` generator to set '<an-attribute>' to a given value
diff --git a/Help/variable/CMAKE_XCODE_GENERATE_SCHEME.rst b/Help/variable/CMAKE_XCODE_GENERATE_SCHEME.rst
index 5b1a003..40070e1 100644
--- a/Help/variable/CMAKE_XCODE_GENERATE_SCHEME.rst
+++ b/Help/variable/CMAKE_XCODE_GENERATE_SCHEME.rst
@@ -1,6 +1,8 @@
 CMAKE_XCODE_GENERATE_SCHEME
 ---------------------------
 
+.. versionadded:: 3.9
+
 If enabled, the :generator:`Xcode` generator will generate schema files.  These
 are useful to invoke analyze, archive, build-for-testing and test
 actions from the command line.
diff --git a/Help/variable/CMAKE_XCODE_GENERATE_TOP_LEVEL_PROJECT_ONLY.rst b/Help/variable/CMAKE_XCODE_GENERATE_TOP_LEVEL_PROJECT_ONLY.rst
index ea3e240..38d043c 100644
--- a/Help/variable/CMAKE_XCODE_GENERATE_TOP_LEVEL_PROJECT_ONLY.rst
+++ b/Help/variable/CMAKE_XCODE_GENERATE_TOP_LEVEL_PROJECT_ONLY.rst
@@ -1,6 +1,8 @@
 CMAKE_XCODE_GENERATE_TOP_LEVEL_PROJECT_ONLY
 -------------------------------------------
 
+.. versionadded:: 3.11
+
 If enabled, the :generator:`Xcode` generator will generate only a
 single Xcode project file for the topmost :command:`project()` command
 instead of generating one for every ``project()`` command.
diff --git a/Help/variable/CMAKE_XCODE_SCHEME_ADDRESS_SANITIZER.rst b/Help/variable/CMAKE_XCODE_SCHEME_ADDRESS_SANITIZER.rst
index b972ba5..b3fa93b 100644
--- a/Help/variable/CMAKE_XCODE_SCHEME_ADDRESS_SANITIZER.rst
+++ b/Help/variable/CMAKE_XCODE_SCHEME_ADDRESS_SANITIZER.rst
@@ -1,6 +1,8 @@
 CMAKE_XCODE_SCHEME_ADDRESS_SANITIZER
 ------------------------------------
 
+.. versionadded:: 3.13
+
 Whether to enable ``Address Sanitizer`` in the Diagnostics
 section of the generated Xcode scheme.
 
diff --git a/Help/variable/CMAKE_XCODE_SCHEME_ADDRESS_SANITIZER_USE_AFTER_RETURN.rst b/Help/variable/CMAKE_XCODE_SCHEME_ADDRESS_SANITIZER_USE_AFTER_RETURN.rst
index 59eb32d..1a0a17a 100644
--- a/Help/variable/CMAKE_XCODE_SCHEME_ADDRESS_SANITIZER_USE_AFTER_RETURN.rst
+++ b/Help/variable/CMAKE_XCODE_SCHEME_ADDRESS_SANITIZER_USE_AFTER_RETURN.rst
@@ -1,6 +1,8 @@
 CMAKE_XCODE_SCHEME_ADDRESS_SANITIZER_USE_AFTER_RETURN
 -----------------------------------------------------
 
+.. versionadded:: 3.13
+
 Whether to enable ``Detect use of stack after return``
 in the Diagnostics section of the generated Xcode scheme.
 
diff --git a/Help/variable/CMAKE_XCODE_SCHEME_DEBUG_DOCUMENT_VERSIONING.rst b/Help/variable/CMAKE_XCODE_SCHEME_DEBUG_DOCUMENT_VERSIONING.rst
index a264d36..917fc7f 100644
--- a/Help/variable/CMAKE_XCODE_SCHEME_DEBUG_DOCUMENT_VERSIONING.rst
+++ b/Help/variable/CMAKE_XCODE_SCHEME_DEBUG_DOCUMENT_VERSIONING.rst
@@ -1,6 +1,8 @@
 CMAKE_XCODE_SCHEME_DEBUG_DOCUMENT_VERSIONING
 --------------------------------------------
 
+.. versionadded:: 3.16
+
 Whether to enable
 ``Allow debugging when using document Versions Browser``
 in the Options section of the generated Xcode scheme.
diff --git a/Help/variable/CMAKE_XCODE_SCHEME_DISABLE_MAIN_THREAD_CHECKER.rst b/Help/variable/CMAKE_XCODE_SCHEME_DISABLE_MAIN_THREAD_CHECKER.rst
index 71bcf42..b604598 100644
--- a/Help/variable/CMAKE_XCODE_SCHEME_DISABLE_MAIN_THREAD_CHECKER.rst
+++ b/Help/variable/CMAKE_XCODE_SCHEME_DISABLE_MAIN_THREAD_CHECKER.rst
@@ -1,6 +1,8 @@
 CMAKE_XCODE_SCHEME_DISABLE_MAIN_THREAD_CHECKER
 ----------------------------------------------
 
+.. versionadded:: 3.13
+
 Whether to disable the ``Main Thread Checker``
 in the Diagnostics section of the generated Xcode scheme.
 
diff --git a/Help/variable/CMAKE_XCODE_SCHEME_DYNAMIC_LIBRARY_LOADS.rst b/Help/variable/CMAKE_XCODE_SCHEME_DYNAMIC_LIBRARY_LOADS.rst
index 53f55e6..070ddfc 100644
--- a/Help/variable/CMAKE_XCODE_SCHEME_DYNAMIC_LIBRARY_LOADS.rst
+++ b/Help/variable/CMAKE_XCODE_SCHEME_DYNAMIC_LIBRARY_LOADS.rst
@@ -1,6 +1,8 @@
 CMAKE_XCODE_SCHEME_DYNAMIC_LIBRARY_LOADS
 ----------------------------------------
 
+.. versionadded:: 3.13
+
 Whether to enable ``Dynamic Library Loads``
 in the Diagnostics section of the generated Xcode scheme.
 
diff --git a/Help/variable/CMAKE_XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE.rst b/Help/variable/CMAKE_XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE.rst
index 784ceb6..4291816 100644
--- a/Help/variable/CMAKE_XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE.rst
+++ b/Help/variable/CMAKE_XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE.rst
@@ -1,6 +1,8 @@
 CMAKE_XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE
 -------------------------------------------
 
+.. versionadded:: 3.13
+
 Whether to enable ``Dynamic Linker API usage``
 in the Diagnostics section of the generated Xcode scheme.
 
diff --git a/Help/variable/CMAKE_XCODE_SCHEME_ENVIRONMENT.rst b/Help/variable/CMAKE_XCODE_SCHEME_ENVIRONMENT.rst
index 4832659..62b698d 100644
--- a/Help/variable/CMAKE_XCODE_SCHEME_ENVIRONMENT.rst
+++ b/Help/variable/CMAKE_XCODE_SCHEME_ENVIRONMENT.rst
@@ -1,6 +1,8 @@
 CMAKE_XCODE_SCHEME_ENVIRONMENT
 ------------------------------
 
+.. versionadded:: 3.17
+
 Specify environment variables that should be added to the Arguments
 section of the generated Xcode scheme.
 
diff --git a/Help/variable/CMAKE_XCODE_SCHEME_GUARD_MALLOC.rst b/Help/variable/CMAKE_XCODE_SCHEME_GUARD_MALLOC.rst
index 9350244..48b481e 100644
--- a/Help/variable/CMAKE_XCODE_SCHEME_GUARD_MALLOC.rst
+++ b/Help/variable/CMAKE_XCODE_SCHEME_GUARD_MALLOC.rst
@@ -1,6 +1,8 @@
 CMAKE_XCODE_SCHEME_GUARD_MALLOC
 -------------------------------
 
+.. versionadded:: 3.13
+
 Whether to enable ``Guard Malloc``
 in the Diagnostics section of the generated Xcode scheme.
 
diff --git a/Help/variable/CMAKE_XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP.rst b/Help/variable/CMAKE_XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP.rst
index 45a2dad..ef8ed9b 100644
--- a/Help/variable/CMAKE_XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP.rst
+++ b/Help/variable/CMAKE_XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP.rst
@@ -1,6 +1,8 @@
 CMAKE_XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP
 -------------------------------------------
 
+.. versionadded:: 3.13
+
 Whether to enable the ``Main Thread Checker`` option
 ``Pause on issues``
 in the Diagnostics section of the generated Xcode scheme.
diff --git a/Help/variable/CMAKE_XCODE_SCHEME_MALLOC_GUARD_EDGES.rst b/Help/variable/CMAKE_XCODE_SCHEME_MALLOC_GUARD_EDGES.rst
index 94d1c61..d4ae9eb 100644
--- a/Help/variable/CMAKE_XCODE_SCHEME_MALLOC_GUARD_EDGES.rst
+++ b/Help/variable/CMAKE_XCODE_SCHEME_MALLOC_GUARD_EDGES.rst
@@ -1,6 +1,8 @@
 CMAKE_XCODE_SCHEME_MALLOC_GUARD_EDGES
 -------------------------------------
 
+.. versionadded:: 3.13
+
 Whether to enable ``Malloc Guard Edges``
 in the Diagnostics section of the generated Xcode scheme.
 
diff --git a/Help/variable/CMAKE_XCODE_SCHEME_MALLOC_SCRIBBLE.rst b/Help/variable/CMAKE_XCODE_SCHEME_MALLOC_SCRIBBLE.rst
index 9bf0eb4..e28f6a1 100644
--- a/Help/variable/CMAKE_XCODE_SCHEME_MALLOC_SCRIBBLE.rst
+++ b/Help/variable/CMAKE_XCODE_SCHEME_MALLOC_SCRIBBLE.rst
@@ -1,6 +1,8 @@
 CMAKE_XCODE_SCHEME_MALLOC_SCRIBBLE
 ----------------------------------
 
+.. versionadded:: 3.13
+
 Whether to enable ``Malloc Scribble``
 in the Diagnostics section of the generated Xcode scheme.
 
diff --git a/Help/variable/CMAKE_XCODE_SCHEME_MALLOC_STACK.rst b/Help/variable/CMAKE_XCODE_SCHEME_MALLOC_STACK.rst
index 4cc21ee..59fcfd3 100644
--- a/Help/variable/CMAKE_XCODE_SCHEME_MALLOC_STACK.rst
+++ b/Help/variable/CMAKE_XCODE_SCHEME_MALLOC_STACK.rst
@@ -1,6 +1,8 @@
 CMAKE_XCODE_SCHEME_MALLOC_STACK
 -------------------------------
 
+.. versionadded:: 3.13
+
 Whether to enable ``Malloc Stack`` in the Diagnostics
 section of the generated Xcode scheme.
 
diff --git a/Help/variable/CMAKE_XCODE_SCHEME_THREAD_SANITIZER.rst b/Help/variable/CMAKE_XCODE_SCHEME_THREAD_SANITIZER.rst
index 6d1b56e..511eb04 100644
--- a/Help/variable/CMAKE_XCODE_SCHEME_THREAD_SANITIZER.rst
+++ b/Help/variable/CMAKE_XCODE_SCHEME_THREAD_SANITIZER.rst
@@ -1,6 +1,8 @@
 CMAKE_XCODE_SCHEME_THREAD_SANITIZER
 -----------------------------------
 
+.. versionadded:: 3.13
+
 Whether to enable ``Thread Sanitizer`` in the Diagnostics
 section of the generated Xcode scheme.
 
diff --git a/Help/variable/CMAKE_XCODE_SCHEME_THREAD_SANITIZER_STOP.rst b/Help/variable/CMAKE_XCODE_SCHEME_THREAD_SANITIZER_STOP.rst
index de40478..6f3b8ce 100644
--- a/Help/variable/CMAKE_XCODE_SCHEME_THREAD_SANITIZER_STOP.rst
+++ b/Help/variable/CMAKE_XCODE_SCHEME_THREAD_SANITIZER_STOP.rst
@@ -1,6 +1,8 @@
 CMAKE_XCODE_SCHEME_THREAD_SANITIZER_STOP
 ----------------------------------------
 
+.. versionadded:: 3.13
+
 Whether to enable ``Thread Sanitizer - Pause on issues``
 in the Diagnostics section of the generated Xcode scheme.
 
diff --git a/Help/variable/CMAKE_XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER.rst b/Help/variable/CMAKE_XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER.rst
index ec5df66..46d3ccf 100644
--- a/Help/variable/CMAKE_XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER.rst
+++ b/Help/variable/CMAKE_XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER.rst
@@ -1,6 +1,8 @@
 CMAKE_XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER
 ------------------------------------------------
 
+.. versionadded:: 3.13
+
 Whether to enable ``Undefined Behavior Sanitizer``
 in the Diagnostics section of the generated Xcode scheme.
 
diff --git a/Help/variable/CMAKE_XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP.rst b/Help/variable/CMAKE_XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP.rst
index dcec9b0..8fa5ece 100644
--- a/Help/variable/CMAKE_XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP.rst
+++ b/Help/variable/CMAKE_XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP.rst
@@ -1,6 +1,8 @@
 CMAKE_XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP
 -----------------------------------------------------
 
+.. versionadded:: 3.13
+
 Whether to enable ``Undefined Behavior Sanitizer`` option
 ``Pause on issues``
 in the Diagnostics section of the generated Xcode scheme.
diff --git a/Help/variable/CMAKE_XCODE_SCHEME_WORKING_DIRECTORY.rst b/Help/variable/CMAKE_XCODE_SCHEME_WORKING_DIRECTORY.rst
index 5bb7907..4221e48 100644
--- a/Help/variable/CMAKE_XCODE_SCHEME_WORKING_DIRECTORY.rst
+++ b/Help/variable/CMAKE_XCODE_SCHEME_WORKING_DIRECTORY.rst
@@ -1,6 +1,8 @@
 CMAKE_XCODE_SCHEME_WORKING_DIRECTORY
 ------------------------------------
 
+.. versionadded:: 3.17
+
 Specify the ``Working Directory`` of the *Run* and *Profile*
 actions in the generated Xcode scheme.
 
diff --git a/Help/variable/CMAKE_XCODE_SCHEME_ZOMBIE_OBJECTS.rst b/Help/variable/CMAKE_XCODE_SCHEME_ZOMBIE_OBJECTS.rst
index 82e9d76..fd9488e 100644
--- a/Help/variable/CMAKE_XCODE_SCHEME_ZOMBIE_OBJECTS.rst
+++ b/Help/variable/CMAKE_XCODE_SCHEME_ZOMBIE_OBJECTS.rst
@@ -1,6 +1,8 @@
 CMAKE_XCODE_SCHEME_ZOMBIE_OBJECTS
 ---------------------------------
 
+.. versionadded:: 3.13
+
 Whether to enable ``Zombie Objects``
 in the Diagnostics section of the generated Xcode scheme.
 
diff --git a/Help/variable/CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS.rst b/Help/variable/CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS.rst
index 83d5ce7..01fb189 100644
--- a/Help/variable/CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS.rst
+++ b/Help/variable/CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS.rst
@@ -1,6 +1,8 @@
 CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS
 -------------------------------------------
 
+.. versionadded:: 3.11
+
 Default permissions for implicitly created directories during packaging.
 
 This variable serves the same purpose during packaging as the
diff --git a/Help/variable/CTEST_BINARY_DIRECTORY.rst b/Help/variable/CTEST_BINARY_DIRECTORY.rst
index fd8461f..8413e37 100644
--- a/Help/variable/CTEST_BINARY_DIRECTORY.rst
+++ b/Help/variable/CTEST_BINARY_DIRECTORY.rst
@@ -1,5 +1,7 @@
 CTEST_BINARY_DIRECTORY
 ----------------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``BuildDirectory`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_BUILD_COMMAND.rst b/Help/variable/CTEST_BUILD_COMMAND.rst
index 7b13ba0..31c44e2 100644
--- a/Help/variable/CTEST_BUILD_COMMAND.rst
+++ b/Help/variable/CTEST_BUILD_COMMAND.rst
@@ -1,5 +1,7 @@
 CTEST_BUILD_COMMAND
 -------------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``MakeCommand`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_BUILD_NAME.rst b/Help/variable/CTEST_BUILD_NAME.rst
index d25d84c..3d08397 100644
--- a/Help/variable/CTEST_BUILD_NAME.rst
+++ b/Help/variable/CTEST_BUILD_NAME.rst
@@ -1,5 +1,7 @@
 CTEST_BUILD_NAME
 ----------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``BuildName`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_BZR_COMMAND.rst b/Help/variable/CTEST_BZR_COMMAND.rst
index 474d621..0c05d1a 100644
--- a/Help/variable/CTEST_BZR_COMMAND.rst
+++ b/Help/variable/CTEST_BZR_COMMAND.rst
@@ -1,5 +1,7 @@
 CTEST_BZR_COMMAND
 -----------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``BZRCommand`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_BZR_UPDATE_OPTIONS.rst b/Help/variable/CTEST_BZR_UPDATE_OPTIONS.rst
index d0f9579..4dd5e5b 100644
--- a/Help/variable/CTEST_BZR_UPDATE_OPTIONS.rst
+++ b/Help/variable/CTEST_BZR_UPDATE_OPTIONS.rst
@@ -1,5 +1,7 @@
 CTEST_BZR_UPDATE_OPTIONS
 ------------------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``BZRUpdateOptions`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_CHANGE_ID.rst b/Help/variable/CTEST_CHANGE_ID.rst
index a423f49..a6d15f7 100644
--- a/Help/variable/CTEST_CHANGE_ID.rst
+++ b/Help/variable/CTEST_CHANGE_ID.rst
@@ -1,6 +1,8 @@
 CTEST_CHANGE_ID
 ---------------
 
+.. versionadded:: 3.4
+
 Specify the CTest ``ChangeId`` setting
 in a :manual:`ctest(1)` dashboard client script.
 
diff --git a/Help/variable/CTEST_CHECKOUT_COMMAND.rst b/Help/variable/CTEST_CHECKOUT_COMMAND.rst
index da256f2..852c28e 100644
--- a/Help/variable/CTEST_CHECKOUT_COMMAND.rst
+++ b/Help/variable/CTEST_CHECKOUT_COMMAND.rst
@@ -1,5 +1,7 @@
 CTEST_CHECKOUT_COMMAND
 ----------------------
 
+.. versionadded:: 3.1
+
 Tell the :command:`ctest_start` command how to checkout or initialize
 the source directory in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_CONFIGURATION_TYPE.rst b/Help/variable/CTEST_CONFIGURATION_TYPE.rst
index 9e277fa..392845e 100644
--- a/Help/variable/CTEST_CONFIGURATION_TYPE.rst
+++ b/Help/variable/CTEST_CONFIGURATION_TYPE.rst
@@ -1,6 +1,8 @@
 CTEST_CONFIGURATION_TYPE
 ------------------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``DefaultCTestConfigurationType`` setting
 in a :manual:`ctest(1)` dashboard client script.
 
diff --git a/Help/variable/CTEST_CONFIGURE_COMMAND.rst b/Help/variable/CTEST_CONFIGURE_COMMAND.rst
index 5561b6d..992ef47 100644
--- a/Help/variable/CTEST_CONFIGURE_COMMAND.rst
+++ b/Help/variable/CTEST_CONFIGURE_COMMAND.rst
@@ -1,5 +1,7 @@
 CTEST_CONFIGURE_COMMAND
 -----------------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``ConfigureCommand`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_COVERAGE_COMMAND.rst b/Help/variable/CTEST_COVERAGE_COMMAND.rst
index a78792e..f5425cb 100644
--- a/Help/variable/CTEST_COVERAGE_COMMAND.rst
+++ b/Help/variable/CTEST_COVERAGE_COMMAND.rst
@@ -1,6 +1,8 @@
 CTEST_COVERAGE_COMMAND
 ----------------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``CoverageCommand`` setting
 in a :manual:`ctest(1)` dashboard client script.
 
diff --git a/Help/variable/CTEST_COVERAGE_EXTRA_FLAGS.rst b/Help/variable/CTEST_COVERAGE_EXTRA_FLAGS.rst
index 2981955..39d9b5d 100644
--- a/Help/variable/CTEST_COVERAGE_EXTRA_FLAGS.rst
+++ b/Help/variable/CTEST_COVERAGE_EXTRA_FLAGS.rst
@@ -1,5 +1,7 @@
 CTEST_COVERAGE_EXTRA_FLAGS
 --------------------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``CoverageExtraFlags`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_CURL_OPTIONS.rst b/Help/variable/CTEST_CURL_OPTIONS.rst
index fc5dfc4..14af4e4 100644
--- a/Help/variable/CTEST_CURL_OPTIONS.rst
+++ b/Help/variable/CTEST_CURL_OPTIONS.rst
@@ -1,5 +1,7 @@
 CTEST_CURL_OPTIONS
 ------------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``CurlOptions`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_CUSTOM_COVERAGE_EXCLUDE.rst b/Help/variable/CTEST_CUSTOM_COVERAGE_EXCLUDE.rst
index d5893c9..84ba12d 100644
--- a/Help/variable/CTEST_CUSTOM_COVERAGE_EXCLUDE.rst
+++ b/Help/variable/CTEST_CUSTOM_COVERAGE_EXCLUDE.rst
@@ -1,6 +1,8 @@
 CTEST_CUSTOM_COVERAGE_EXCLUDE
 -----------------------------
 
+.. versionadded:: 3.4
+
 A list of regular expressions which will be used to exclude files by their
 path from coverage output by the :command:`ctest_coverage` command.
 
diff --git a/Help/variable/CTEST_CUSTOM_ERROR_EXCEPTION.rst b/Help/variable/CTEST_CUSTOM_ERROR_EXCEPTION.rst
index cd65ae3..7191ce4 100644
--- a/Help/variable/CTEST_CUSTOM_ERROR_EXCEPTION.rst
+++ b/Help/variable/CTEST_CUSTOM_ERROR_EXCEPTION.rst
@@ -1,6 +1,8 @@
 CTEST_CUSTOM_ERROR_EXCEPTION
 ----------------------------
 
+.. versionadded:: 3.4
+
 A list of regular expressions which will be used to exclude when detecting
 error messages in build outputs by the :command:`ctest_test` command.
 
diff --git a/Help/variable/CTEST_CUSTOM_ERROR_MATCH.rst b/Help/variable/CTEST_CUSTOM_ERROR_MATCH.rst
index 558f5e5..5d213f2 100644
--- a/Help/variable/CTEST_CUSTOM_ERROR_MATCH.rst
+++ b/Help/variable/CTEST_CUSTOM_ERROR_MATCH.rst
@@ -1,6 +1,8 @@
 CTEST_CUSTOM_ERROR_MATCH
 ------------------------
 
+.. versionadded:: 3.4
+
 A list of regular expressions which will be used to detect error messages in
 build outputs by the :command:`ctest_test` command.
 
diff --git a/Help/variable/CTEST_CUSTOM_ERROR_POST_CONTEXT.rst b/Help/variable/CTEST_CUSTOM_ERROR_POST_CONTEXT.rst
index 614859b..452d060 100644
--- a/Help/variable/CTEST_CUSTOM_ERROR_POST_CONTEXT.rst
+++ b/Help/variable/CTEST_CUSTOM_ERROR_POST_CONTEXT.rst
@@ -1,6 +1,8 @@
 CTEST_CUSTOM_ERROR_POST_CONTEXT
 -------------------------------
 
+.. versionadded:: 3.4
+
 The number of lines to include as context which follow an error message by the
 :command:`ctest_test` command. The default is 10.
 
diff --git a/Help/variable/CTEST_CUSTOM_ERROR_PRE_CONTEXT.rst b/Help/variable/CTEST_CUSTOM_ERROR_PRE_CONTEXT.rst
index 74dc47a..b7717dd 100644
--- a/Help/variable/CTEST_CUSTOM_ERROR_PRE_CONTEXT.rst
+++ b/Help/variable/CTEST_CUSTOM_ERROR_PRE_CONTEXT.rst
@@ -1,6 +1,8 @@
 CTEST_CUSTOM_ERROR_PRE_CONTEXT
 ------------------------------
 
+.. versionadded:: 3.4
+
 The number of lines to include as context which precede an error message by
 the :command:`ctest_test` command. The default is 10.
 
diff --git a/Help/variable/CTEST_CUSTOM_MAXIMUM_FAILED_TEST_OUTPUT_SIZE.rst b/Help/variable/CTEST_CUSTOM_MAXIMUM_FAILED_TEST_OUTPUT_SIZE.rst
index 5aeae88..31ba099 100644
--- a/Help/variable/CTEST_CUSTOM_MAXIMUM_FAILED_TEST_OUTPUT_SIZE.rst
+++ b/Help/variable/CTEST_CUSTOM_MAXIMUM_FAILED_TEST_OUTPUT_SIZE.rst
@@ -1,6 +1,8 @@
 CTEST_CUSTOM_MAXIMUM_FAILED_TEST_OUTPUT_SIZE
 --------------------------------------------
 
+.. versionadded:: 3.4
+
 When saving a failing test's output, this is the maximum size, in bytes, that
 will be collected by the :command:`ctest_test` command. Defaults to 307200
 (300 KiB).
diff --git a/Help/variable/CTEST_CUSTOM_MAXIMUM_NUMBER_OF_ERRORS.rst b/Help/variable/CTEST_CUSTOM_MAXIMUM_NUMBER_OF_ERRORS.rst
index 920cb04..e5be1ad 100644
--- a/Help/variable/CTEST_CUSTOM_MAXIMUM_NUMBER_OF_ERRORS.rst
+++ b/Help/variable/CTEST_CUSTOM_MAXIMUM_NUMBER_OF_ERRORS.rst
@@ -1,6 +1,8 @@
 CTEST_CUSTOM_MAXIMUM_NUMBER_OF_ERRORS
 -------------------------------------
 
+.. versionadded:: 3.4
+
 The maximum number of errors in a single build step which will be detected.
 After this, the :command:`ctest_test` command will truncate the output.
 Defaults to 50.
diff --git a/Help/variable/CTEST_CUSTOM_MAXIMUM_NUMBER_OF_WARNINGS.rst b/Help/variable/CTEST_CUSTOM_MAXIMUM_NUMBER_OF_WARNINGS.rst
index a1f1cc1..b513a5c 100644
--- a/Help/variable/CTEST_CUSTOM_MAXIMUM_NUMBER_OF_WARNINGS.rst
+++ b/Help/variable/CTEST_CUSTOM_MAXIMUM_NUMBER_OF_WARNINGS.rst
@@ -1,6 +1,8 @@
 CTEST_CUSTOM_MAXIMUM_NUMBER_OF_WARNINGS
 ---------------------------------------
 
+.. versionadded:: 3.4
+
 The maximum number of warnings in a single build step which will be detected.
 After this, the :command:`ctest_test` command will truncate the output.
 Defaults to 50.
diff --git a/Help/variable/CTEST_CUSTOM_MAXIMUM_PASSED_TEST_OUTPUT_SIZE.rst b/Help/variable/CTEST_CUSTOM_MAXIMUM_PASSED_TEST_OUTPUT_SIZE.rst
index 1fbb8c5..08762d8 100644
--- a/Help/variable/CTEST_CUSTOM_MAXIMUM_PASSED_TEST_OUTPUT_SIZE.rst
+++ b/Help/variable/CTEST_CUSTOM_MAXIMUM_PASSED_TEST_OUTPUT_SIZE.rst
@@ -1,6 +1,8 @@
 CTEST_CUSTOM_MAXIMUM_PASSED_TEST_OUTPUT_SIZE
 --------------------------------------------
 
+.. versionadded:: 3.4
+
 When saving a passing test's output, this is the maximum size, in bytes, that
 will be collected by the :command:`ctest_test` command. Defaults to 1024
 (1 KiB).
diff --git a/Help/variable/CTEST_CUSTOM_MEMCHECK_IGNORE.rst b/Help/variable/CTEST_CUSTOM_MEMCHECK_IGNORE.rst
index 578576c..405fc33 100644
--- a/Help/variable/CTEST_CUSTOM_MEMCHECK_IGNORE.rst
+++ b/Help/variable/CTEST_CUSTOM_MEMCHECK_IGNORE.rst
@@ -1,6 +1,8 @@
 CTEST_CUSTOM_MEMCHECK_IGNORE
 ----------------------------
 
+.. versionadded:: 3.4
+
 A list of regular expressions to use to exclude tests during the
 :command:`ctest_memcheck` command.
 
diff --git a/Help/variable/CTEST_CUSTOM_POST_MEMCHECK.rst b/Help/variable/CTEST_CUSTOM_POST_MEMCHECK.rst
index 40291fe..5e488a7 100644
--- a/Help/variable/CTEST_CUSTOM_POST_MEMCHECK.rst
+++ b/Help/variable/CTEST_CUSTOM_POST_MEMCHECK.rst
@@ -1,6 +1,8 @@
 CTEST_CUSTOM_POST_MEMCHECK
 --------------------------
 
+.. versionadded:: 3.4
+
 A list of commands to run at the end of the :command:`ctest_memcheck` command.
 
 .. include:: CTEST_CUSTOM_XXX.txt
diff --git a/Help/variable/CTEST_CUSTOM_POST_TEST.rst b/Help/variable/CTEST_CUSTOM_POST_TEST.rst
index 791292c..7ec42f7 100644
--- a/Help/variable/CTEST_CUSTOM_POST_TEST.rst
+++ b/Help/variable/CTEST_CUSTOM_POST_TEST.rst
@@ -1,6 +1,8 @@
 CTEST_CUSTOM_POST_TEST
 ----------------------
 
+.. versionadded:: 3.4
+
 A list of commands to run at the end of the :command:`ctest_test` command.
 
 .. include:: CTEST_CUSTOM_XXX.txt
diff --git a/Help/variable/CTEST_CUSTOM_PRE_MEMCHECK.rst b/Help/variable/CTEST_CUSTOM_PRE_MEMCHECK.rst
index 00de8aa..99e47bd 100644
--- a/Help/variable/CTEST_CUSTOM_PRE_MEMCHECK.rst
+++ b/Help/variable/CTEST_CUSTOM_PRE_MEMCHECK.rst
@@ -1,6 +1,8 @@
 CTEST_CUSTOM_PRE_MEMCHECK
 -------------------------
 
+.. versionadded:: 3.4
+
 A list of commands to run at the start of the :command:`ctest_memcheck`
 command.
 
diff --git a/Help/variable/CTEST_CUSTOM_PRE_TEST.rst b/Help/variable/CTEST_CUSTOM_PRE_TEST.rst
index 6af7152..95c6314 100644
--- a/Help/variable/CTEST_CUSTOM_PRE_TEST.rst
+++ b/Help/variable/CTEST_CUSTOM_PRE_TEST.rst
@@ -1,6 +1,8 @@
 CTEST_CUSTOM_PRE_TEST
 ----------------------
 
+.. versionadded:: 3.4
+
 A list of commands to run at the start of the :command:`ctest_test` command.
 
 .. include:: CTEST_CUSTOM_XXX.txt
diff --git a/Help/variable/CTEST_CUSTOM_TESTS_IGNORE.rst b/Help/variable/CTEST_CUSTOM_TESTS_IGNORE.rst
index 57222ca..27a75d9 100644
--- a/Help/variable/CTEST_CUSTOM_TESTS_IGNORE.rst
+++ b/Help/variable/CTEST_CUSTOM_TESTS_IGNORE.rst
@@ -1,6 +1,8 @@
 CTEST_CUSTOM_TESTS_IGNORE
 -------------------------
 
+.. versionadded:: 3.14
+
 A list of regular expressions to use to exclude tests during the
 :command:`ctest_test` command.
 
diff --git a/Help/variable/CTEST_CUSTOM_WARNING_EXCEPTION.rst b/Help/variable/CTEST_CUSTOM_WARNING_EXCEPTION.rst
index a03d473..539760b 100644
--- a/Help/variable/CTEST_CUSTOM_WARNING_EXCEPTION.rst
+++ b/Help/variable/CTEST_CUSTOM_WARNING_EXCEPTION.rst
@@ -1,6 +1,8 @@
 CTEST_CUSTOM_WARNING_EXCEPTION
 ------------------------------
 
+.. versionadded:: 3.4
+
 A list of regular expressions which will be used to exclude when detecting
 warning messages in build outputs by the :command:`ctest_build` command.
 
diff --git a/Help/variable/CTEST_CUSTOM_WARNING_MATCH.rst b/Help/variable/CTEST_CUSTOM_WARNING_MATCH.rst
index 18aa6b3..53e7707 100644
--- a/Help/variable/CTEST_CUSTOM_WARNING_MATCH.rst
+++ b/Help/variable/CTEST_CUSTOM_WARNING_MATCH.rst
@@ -1,6 +1,8 @@
 CTEST_CUSTOM_WARNING_MATCH
 --------------------------
 
+.. versionadded:: 3.4
+
 A list of regular expressions which will be used to detect warning messages in
 build outputs by the :command:`ctest_build` command.
 
diff --git a/Help/variable/CTEST_CVS_CHECKOUT.rst b/Help/variable/CTEST_CVS_CHECKOUT.rst
index 6431c02..32cf9eb 100644
--- a/Help/variable/CTEST_CVS_CHECKOUT.rst
+++ b/Help/variable/CTEST_CVS_CHECKOUT.rst
@@ -1,4 +1,6 @@
 CTEST_CVS_CHECKOUT
 ------------------
 
+.. versionadded:: 3.1
+
 Deprecated.  Use :variable:`CTEST_CHECKOUT_COMMAND` instead.
diff --git a/Help/variable/CTEST_CVS_COMMAND.rst b/Help/variable/CTEST_CVS_COMMAND.rst
index 049700b..7932070 100644
--- a/Help/variable/CTEST_CVS_COMMAND.rst
+++ b/Help/variable/CTEST_CVS_COMMAND.rst
@@ -1,5 +1,7 @@
 CTEST_CVS_COMMAND
 -----------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``CVSCommand`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_CVS_UPDATE_OPTIONS.rst b/Help/variable/CTEST_CVS_UPDATE_OPTIONS.rst
index d7f2f7c..359e708 100644
--- a/Help/variable/CTEST_CVS_UPDATE_OPTIONS.rst
+++ b/Help/variable/CTEST_CVS_UPDATE_OPTIONS.rst
@@ -1,5 +1,7 @@
 CTEST_CVS_UPDATE_OPTIONS
 ------------------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``CVSUpdateOptions`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_DROP_LOCATION.rst b/Help/variable/CTEST_DROP_LOCATION.rst
index c0f2215..f66793b 100644
--- a/Help/variable/CTEST_DROP_LOCATION.rst
+++ b/Help/variable/CTEST_DROP_LOCATION.rst
@@ -1,5 +1,7 @@
 CTEST_DROP_LOCATION
 -------------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``DropLocation`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_DROP_METHOD.rst b/Help/variable/CTEST_DROP_METHOD.rst
index 50fbd4d..3a84658 100644
--- a/Help/variable/CTEST_DROP_METHOD.rst
+++ b/Help/variable/CTEST_DROP_METHOD.rst
@@ -1,5 +1,7 @@
 CTEST_DROP_METHOD
 -----------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``DropMethod`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_DROP_SITE.rst b/Help/variable/CTEST_DROP_SITE.rst
index d15d99b..9c871e3 100644
--- a/Help/variable/CTEST_DROP_SITE.rst
+++ b/Help/variable/CTEST_DROP_SITE.rst
@@ -1,5 +1,7 @@
 CTEST_DROP_SITE
 ---------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``DropSite`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_DROP_SITE_CDASH.rst b/Help/variable/CTEST_DROP_SITE_CDASH.rst
index 22b9776..dcdb286 100644
--- a/Help/variable/CTEST_DROP_SITE_CDASH.rst
+++ b/Help/variable/CTEST_DROP_SITE_CDASH.rst
@@ -1,5 +1,7 @@
 CTEST_DROP_SITE_CDASH
 ---------------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``IsCDash`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_DROP_SITE_PASSWORD.rst b/Help/variable/CTEST_DROP_SITE_PASSWORD.rst
index 904d2c8..8259651 100644
--- a/Help/variable/CTEST_DROP_SITE_PASSWORD.rst
+++ b/Help/variable/CTEST_DROP_SITE_PASSWORD.rst
@@ -1,5 +1,7 @@
 CTEST_DROP_SITE_PASSWORD
 ------------------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``DropSitePassword`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_DROP_SITE_USER.rst b/Help/variable/CTEST_DROP_SITE_USER.rst
index a860a03..8d2e3a3 100644
--- a/Help/variable/CTEST_DROP_SITE_USER.rst
+++ b/Help/variable/CTEST_DROP_SITE_USER.rst
@@ -1,5 +1,7 @@
 CTEST_DROP_SITE_USER
 --------------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``DropSiteUser`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_EXTRA_COVERAGE_GLOB.rst b/Help/variable/CTEST_EXTRA_COVERAGE_GLOB.rst
index 286f7df..1d7e8d4 100644
--- a/Help/variable/CTEST_EXTRA_COVERAGE_GLOB.rst
+++ b/Help/variable/CTEST_EXTRA_COVERAGE_GLOB.rst
@@ -1,6 +1,8 @@
 CTEST_EXTRA_COVERAGE_GLOB
 -------------------------
 
+.. versionadded:: 3.4
+
 A list of regular expressions which will be used to find files which should be
 covered by the :command:`ctest_coverage` command.
 
diff --git a/Help/variable/CTEST_GIT_COMMAND.rst b/Help/variable/CTEST_GIT_COMMAND.rst
index eb83792..eb9b440 100644
--- a/Help/variable/CTEST_GIT_COMMAND.rst
+++ b/Help/variable/CTEST_GIT_COMMAND.rst
@@ -1,5 +1,7 @@
 CTEST_GIT_COMMAND
 -----------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``GITCommand`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_GIT_INIT_SUBMODULES.rst b/Help/variable/CTEST_GIT_INIT_SUBMODULES.rst
index fd27003..529bfc7 100644
--- a/Help/variable/CTEST_GIT_INIT_SUBMODULES.rst
+++ b/Help/variable/CTEST_GIT_INIT_SUBMODULES.rst
@@ -1,5 +1,7 @@
 CTEST_GIT_INIT_SUBMODULES
 -------------------------
 
+.. versionadded:: 3.6
+
 Specify the CTest ``GITInitSubmodules`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_GIT_UPDATE_CUSTOM.rst b/Help/variable/CTEST_GIT_UPDATE_CUSTOM.rst
index 0c479e6..82a8a6a 100644
--- a/Help/variable/CTEST_GIT_UPDATE_CUSTOM.rst
+++ b/Help/variable/CTEST_GIT_UPDATE_CUSTOM.rst
@@ -1,5 +1,7 @@
 CTEST_GIT_UPDATE_CUSTOM
 -----------------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``GITUpdateCustom`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_GIT_UPDATE_OPTIONS.rst b/Help/variable/CTEST_GIT_UPDATE_OPTIONS.rst
index 4590a78..1568239 100644
--- a/Help/variable/CTEST_GIT_UPDATE_OPTIONS.rst
+++ b/Help/variable/CTEST_GIT_UPDATE_OPTIONS.rst
@@ -1,5 +1,7 @@
 CTEST_GIT_UPDATE_OPTIONS
 ------------------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``GITUpdateOptions`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_HG_COMMAND.rst b/Help/variable/CTEST_HG_COMMAND.rst
index 3854950..3372fe4 100644
--- a/Help/variable/CTEST_HG_COMMAND.rst
+++ b/Help/variable/CTEST_HG_COMMAND.rst
@@ -1,5 +1,7 @@
 CTEST_HG_COMMAND
 ----------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``HGCommand`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_HG_UPDATE_OPTIONS.rst b/Help/variable/CTEST_HG_UPDATE_OPTIONS.rst
index 9049c1f..85c6b03 100644
--- a/Help/variable/CTEST_HG_UPDATE_OPTIONS.rst
+++ b/Help/variable/CTEST_HG_UPDATE_OPTIONS.rst
@@ -1,5 +1,7 @@
 CTEST_HG_UPDATE_OPTIONS
 -----------------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``HGUpdateOptions`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_LABELS_FOR_SUBPROJECTS.rst b/Help/variable/CTEST_LABELS_FOR_SUBPROJECTS.rst
index 959596b..dd6d125 100644
--- a/Help/variable/CTEST_LABELS_FOR_SUBPROJECTS.rst
+++ b/Help/variable/CTEST_LABELS_FOR_SUBPROJECTS.rst
@@ -1,5 +1,7 @@
 CTEST_LABELS_FOR_SUBPROJECTS
 ----------------------------
 
+.. versionadded:: 3.10
+
 Specify the CTest ``LabelsForSubprojects`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_MEMORYCHECK_COMMAND.rst b/Help/variable/CTEST_MEMORYCHECK_COMMAND.rst
index 8c199ba..25f1bd9 100644
--- a/Help/variable/CTEST_MEMORYCHECK_COMMAND.rst
+++ b/Help/variable/CTEST_MEMORYCHECK_COMMAND.rst
@@ -1,5 +1,7 @@
 CTEST_MEMORYCHECK_COMMAND
 -------------------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``MemoryCheckCommand`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_MEMORYCHECK_COMMAND_OPTIONS.rst b/Help/variable/CTEST_MEMORYCHECK_COMMAND_OPTIONS.rst
index 3e26ab5..51830d5 100644
--- a/Help/variable/CTEST_MEMORYCHECK_COMMAND_OPTIONS.rst
+++ b/Help/variable/CTEST_MEMORYCHECK_COMMAND_OPTIONS.rst
@@ -1,5 +1,7 @@
 CTEST_MEMORYCHECK_COMMAND_OPTIONS
 ---------------------------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``MemoryCheckCommandOptions`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_MEMORYCHECK_SANITIZER_OPTIONS.rst b/Help/variable/CTEST_MEMORYCHECK_SANITIZER_OPTIONS.rst
index 2de5fb6..6cd51fa 100644
--- a/Help/variable/CTEST_MEMORYCHECK_SANITIZER_OPTIONS.rst
+++ b/Help/variable/CTEST_MEMORYCHECK_SANITIZER_OPTIONS.rst
@@ -1,5 +1,7 @@
 CTEST_MEMORYCHECK_SANITIZER_OPTIONS
 -----------------------------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``MemoryCheckSanitizerOptions`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_MEMORYCHECK_SUPPRESSIONS_FILE.rst b/Help/variable/CTEST_MEMORYCHECK_SUPPRESSIONS_FILE.rst
index 1147ee8..a61a3ef 100644
--- a/Help/variable/CTEST_MEMORYCHECK_SUPPRESSIONS_FILE.rst
+++ b/Help/variable/CTEST_MEMORYCHECK_SUPPRESSIONS_FILE.rst
@@ -1,5 +1,7 @@
 CTEST_MEMORYCHECK_SUPPRESSIONS_FILE
 -----------------------------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``MemoryCheckSuppressionFile`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_MEMORYCHECK_TYPE.rst b/Help/variable/CTEST_MEMORYCHECK_TYPE.rst
index 4e7d5c0..2452228 100644
--- a/Help/variable/CTEST_MEMORYCHECK_TYPE.rst
+++ b/Help/variable/CTEST_MEMORYCHECK_TYPE.rst
@@ -1,6 +1,8 @@
 CTEST_MEMORYCHECK_TYPE
 ----------------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``MemoryCheckType`` setting
 in a :manual:`ctest(1)` dashboard client script.
 Valid values are ``Valgrind``, ``Purify``, ``BoundsChecker``, ``DrMemory`` and
diff --git a/Help/variable/CTEST_NIGHTLY_START_TIME.rst b/Help/variable/CTEST_NIGHTLY_START_TIME.rst
index 90841f9..2d707d5 100644
--- a/Help/variable/CTEST_NIGHTLY_START_TIME.rst
+++ b/Help/variable/CTEST_NIGHTLY_START_TIME.rst
@@ -1,6 +1,8 @@
 CTEST_NIGHTLY_START_TIME
 ------------------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``NightlyStartTime`` setting in a :manual:`ctest(1)`
 dashboard client script.
 
diff --git a/Help/variable/CTEST_P4_CLIENT.rst b/Help/variable/CTEST_P4_CLIENT.rst
index 347ea54..0778c5b 100644
--- a/Help/variable/CTEST_P4_CLIENT.rst
+++ b/Help/variable/CTEST_P4_CLIENT.rst
@@ -1,5 +1,7 @@
 CTEST_P4_CLIENT
 ---------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``P4Client`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_P4_COMMAND.rst b/Help/variable/CTEST_P4_COMMAND.rst
index defab12..5cc2a81 100644
--- a/Help/variable/CTEST_P4_COMMAND.rst
+++ b/Help/variable/CTEST_P4_COMMAND.rst
@@ -1,5 +1,7 @@
 CTEST_P4_COMMAND
 ----------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``P4Command`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_P4_OPTIONS.rst b/Help/variable/CTEST_P4_OPTIONS.rst
index fee4ce2..01b6534 100644
--- a/Help/variable/CTEST_P4_OPTIONS.rst
+++ b/Help/variable/CTEST_P4_OPTIONS.rst
@@ -1,5 +1,7 @@
 CTEST_P4_OPTIONS
 ----------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``P4Options`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_P4_UPDATE_OPTIONS.rst b/Help/variable/CTEST_P4_UPDATE_OPTIONS.rst
index 0e2790f..365aa3f 100644
--- a/Help/variable/CTEST_P4_UPDATE_OPTIONS.rst
+++ b/Help/variable/CTEST_P4_UPDATE_OPTIONS.rst
@@ -1,5 +1,7 @@
 CTEST_P4_UPDATE_OPTIONS
 -----------------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``P4UpdateOptions`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_RESOURCE_SPEC_FILE.rst b/Help/variable/CTEST_RESOURCE_SPEC_FILE.rst
index a6fdbc9..8e9bf01 100644
--- a/Help/variable/CTEST_RESOURCE_SPEC_FILE.rst
+++ b/Help/variable/CTEST_RESOURCE_SPEC_FILE.rst
@@ -1,6 +1,8 @@
 CTEST_RESOURCE_SPEC_FILE
 ------------------------
 
+.. versionadded:: 3.18
+
 Specify the CTest ``ResourceSpecFile`` setting in a :manual:`ctest(1)`
 dashboard client script.
 
diff --git a/Help/variable/CTEST_RUN_CURRENT_SCRIPT.rst b/Help/variable/CTEST_RUN_CURRENT_SCRIPT.rst
index abc123c..32c85ad 100644
--- a/Help/variable/CTEST_RUN_CURRENT_SCRIPT.rst
+++ b/Help/variable/CTEST_RUN_CURRENT_SCRIPT.rst
@@ -1,5 +1,7 @@
 CTEST_RUN_CURRENT_SCRIPT
 ------------------------
 
+.. versionadded:: 3.11
+
 Setting this to 0 prevents :manual:`ctest(1)` from being run again when it
 reaches the end of a script run by calling ``ctest -S``.
diff --git a/Help/variable/CTEST_SCP_COMMAND.rst b/Help/variable/CTEST_SCP_COMMAND.rst
index 19ea8b3..155b058 100644
--- a/Help/variable/CTEST_SCP_COMMAND.rst
+++ b/Help/variable/CTEST_SCP_COMMAND.rst
@@ -1,4 +1,6 @@
 CTEST_SCP_COMMAND
 -----------------
 
+.. versionadded:: 3.1
+
 Legacy option.  Not used.
diff --git a/Help/variable/CTEST_SITE.rst b/Help/variable/CTEST_SITE.rst
index 8a5ec25..526e6ed 100644
--- a/Help/variable/CTEST_SITE.rst
+++ b/Help/variable/CTEST_SITE.rst
@@ -1,5 +1,7 @@
 CTEST_SITE
 ----------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``Site`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_SOURCE_DIRECTORY.rst b/Help/variable/CTEST_SOURCE_DIRECTORY.rst
index b6837d1..4c6ac54 100644
--- a/Help/variable/CTEST_SOURCE_DIRECTORY.rst
+++ b/Help/variable/CTEST_SOURCE_DIRECTORY.rst
@@ -1,5 +1,7 @@
 CTEST_SOURCE_DIRECTORY
 ----------------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``SourceDirectory`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_SUBMIT_URL.rst b/Help/variable/CTEST_SUBMIT_URL.rst
index 7d84da4..b6e7f68 100644
--- a/Help/variable/CTEST_SUBMIT_URL.rst
+++ b/Help/variable/CTEST_SUBMIT_URL.rst
@@ -1,5 +1,7 @@
 CTEST_SUBMIT_URL
 ----------------
 
+.. versionadded:: 3.14
+
 Specify the CTest ``SubmitURL`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_SVN_COMMAND.rst b/Help/variable/CTEST_SVN_COMMAND.rst
index af90143..e97acd0 100644
--- a/Help/variable/CTEST_SVN_COMMAND.rst
+++ b/Help/variable/CTEST_SVN_COMMAND.rst
@@ -1,5 +1,7 @@
 CTEST_SVN_COMMAND
 -----------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``SVNCommand`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_SVN_OPTIONS.rst b/Help/variable/CTEST_SVN_OPTIONS.rst
index 76551dc..5326e20 100644
--- a/Help/variable/CTEST_SVN_OPTIONS.rst
+++ b/Help/variable/CTEST_SVN_OPTIONS.rst
@@ -1,5 +1,7 @@
 CTEST_SVN_OPTIONS
 -----------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``SVNOptions`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_SVN_UPDATE_OPTIONS.rst b/Help/variable/CTEST_SVN_UPDATE_OPTIONS.rst
index 5f01a19..24e0bbf 100644
--- a/Help/variable/CTEST_SVN_UPDATE_OPTIONS.rst
+++ b/Help/variable/CTEST_SVN_UPDATE_OPTIONS.rst
@@ -1,5 +1,7 @@
 CTEST_SVN_UPDATE_OPTIONS
 ------------------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``SVNUpdateOptions`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_TEST_LOAD.rst b/Help/variable/CTEST_TEST_LOAD.rst
index 80823fe..b6a9d62 100644
--- a/Help/variable/CTEST_TEST_LOAD.rst
+++ b/Help/variable/CTEST_TEST_LOAD.rst
@@ -1,6 +1,8 @@
 CTEST_TEST_LOAD
 ---------------
 
+.. versionadded:: 3.4
+
 Specify the ``TestLoad`` setting in the :ref:`CTest Test Step`
 of a :manual:`ctest(1)` dashboard client script.  This sets the
 default value for the ``TEST_LOAD`` option of the :command:`ctest_test`
diff --git a/Help/variable/CTEST_TEST_TIMEOUT.rst b/Help/variable/CTEST_TEST_TIMEOUT.rst
index c031437..61d9191 100644
--- a/Help/variable/CTEST_TEST_TIMEOUT.rst
+++ b/Help/variable/CTEST_TEST_TIMEOUT.rst
@@ -1,5 +1,7 @@
 CTEST_TEST_TIMEOUT
 ------------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``TimeOut`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_TRIGGER_SITE.rst b/Help/variable/CTEST_TRIGGER_SITE.rst
index a50e405..6abb852 100644
--- a/Help/variable/CTEST_TRIGGER_SITE.rst
+++ b/Help/variable/CTEST_TRIGGER_SITE.rst
@@ -1,4 +1,6 @@
 CTEST_TRIGGER_SITE
 ------------------
 
+.. versionadded:: 3.1
+
 Legacy option.  Not used.
diff --git a/Help/variable/CTEST_UPDATE_COMMAND.rst b/Help/variable/CTEST_UPDATE_COMMAND.rst
index 90155d0..c4ed645 100644
--- a/Help/variable/CTEST_UPDATE_COMMAND.rst
+++ b/Help/variable/CTEST_UPDATE_COMMAND.rst
@@ -1,5 +1,7 @@
 CTEST_UPDATE_COMMAND
 --------------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``UpdateCommand`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_UPDATE_OPTIONS.rst b/Help/variable/CTEST_UPDATE_OPTIONS.rst
index e43d61d..96c4b6c 100644
--- a/Help/variable/CTEST_UPDATE_OPTIONS.rst
+++ b/Help/variable/CTEST_UPDATE_OPTIONS.rst
@@ -1,5 +1,7 @@
 CTEST_UPDATE_OPTIONS
 --------------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``UpdateOptions`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_UPDATE_VERSION_ONLY.rst b/Help/variable/CTEST_UPDATE_VERSION_ONLY.rst
index a862baa..f7c863c 100644
--- a/Help/variable/CTEST_UPDATE_VERSION_ONLY.rst
+++ b/Help/variable/CTEST_UPDATE_VERSION_ONLY.rst
@@ -1,5 +1,7 @@
 CTEST_UPDATE_VERSION_ONLY
 -------------------------
 
+.. versionadded:: 3.1
+
 Specify the CTest :ref:`UpdateVersionOnly <UpdateVersionOnly>` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_UPDATE_VERSION_OVERRIDE.rst b/Help/variable/CTEST_UPDATE_VERSION_OVERRIDE.rst
index 39fbaba..87918cb 100644
--- a/Help/variable/CTEST_UPDATE_VERSION_OVERRIDE.rst
+++ b/Help/variable/CTEST_UPDATE_VERSION_OVERRIDE.rst
@@ -1,5 +1,7 @@
 CTEST_UPDATE_VERSION_OVERRIDE
 -----------------------------
 
+.. versionadded:: 3.15
+
 Specify the CTest :ref:`UpdateVersionOverride <UpdateVersionOverride>` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_USE_LAUNCHERS.rst b/Help/variable/CTEST_USE_LAUNCHERS.rst
index 9f48a2e..728cdc5 100644
--- a/Help/variable/CTEST_USE_LAUNCHERS.rst
+++ b/Help/variable/CTEST_USE_LAUNCHERS.rst
@@ -1,5 +1,7 @@
 CTEST_USE_LAUNCHERS
 -------------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``UseLaunchers`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/GHS-MULTI.rst b/Help/variable/GHS-MULTI.rst
index fe3b17e..bb139af 100644
--- a/Help/variable/GHS-MULTI.rst
+++ b/Help/variable/GHS-MULTI.rst
@@ -1,4 +1,6 @@
 GHS-MULTI
 ---------
 
+.. versionadded:: 3.3
+
 ``True`` when using :generator:`Green Hills MULTI` generator.
diff --git a/Help/variable/IOS.rst b/Help/variable/IOS.rst
index e5cc3f6..b27be55 100644
--- a/Help/variable/IOS.rst
+++ b/Help/variable/IOS.rst
@@ -1,4 +1,6 @@
 IOS
 ---
 
+.. versionadded:: 3.14
+
 Set to ``1`` when the target system (:variable:`CMAKE_SYSTEM_NAME`) is ``iOS``.
diff --git a/Help/variable/MINGW.rst b/Help/variable/MINGW.rst
index 6d29be4..27c56ea 100644
--- a/Help/variable/MINGW.rst
+++ b/Help/variable/MINGW.rst
@@ -1,6 +1,8 @@
 MINGW
 -----
 
+.. versionadded:: 3.2
+
 ``True`` when using MinGW
 
 Set to ``true`` when the compiler is some version of MinGW.
diff --git a/Help/variable/MSVC14.rst b/Help/variable/MSVC14.rst
index 79e0c10..1eb5183 100644
--- a/Help/variable/MSVC14.rst
+++ b/Help/variable/MSVC14.rst
@@ -1,6 +1,8 @@
 MSVC14
 ------
 
+.. versionadded:: 3.1
+
 Discouraged.  Use the :variable:`MSVC_VERSION` variable instead.
 
 ``True`` when using the Microsoft Visual Studio ``v140`` or ``v141``
diff --git a/Help/variable/MSVC_TOOLSET_VERSION.rst b/Help/variable/MSVC_TOOLSET_VERSION.rst
index f4a33e2..c642a9f 100644
--- a/Help/variable/MSVC_TOOLSET_VERSION.rst
+++ b/Help/variable/MSVC_TOOLSET_VERSION.rst
@@ -1,6 +1,8 @@
 MSVC_TOOLSET_VERSION
 --------------------
 
+.. versionadded:: 3.12
+
 The toolset version of Microsoft Visual C/C++ being used if any.
 If MSVC-like is being used, this variable is set based on the version
 of the compiler as given by the :variable:`MSVC_VERSION` variable.
diff --git a/Help/variable/MSYS.rst b/Help/variable/MSYS.rst
index 25ddc7f..6be7681 100644
--- a/Help/variable/MSYS.rst
+++ b/Help/variable/MSYS.rst
@@ -1,4 +1,6 @@
 MSYS
 ----
 
+.. versionadded:: 3.14
+
 ``True`` when using the :generator:`MSYS Makefiles` generator.
diff --git a/Help/variable/PROJECT-NAME_DESCRIPTION.rst b/Help/variable/PROJECT-NAME_DESCRIPTION.rst
index 2b88b1a..f372f5c 100644
--- a/Help/variable/PROJECT-NAME_DESCRIPTION.rst
+++ b/Help/variable/PROJECT-NAME_DESCRIPTION.rst
@@ -1,5 +1,7 @@
 <PROJECT-NAME>_DESCRIPTION
 --------------------------
 
+.. versionadded:: 3.12
+
 Value given to the ``DESCRIPTION`` option of the most recent call to the
 :command:`project` command with project name ``<PROJECT-NAME>``, if any.
diff --git a/Help/variable/PROJECT-NAME_HOMEPAGE_URL.rst b/Help/variable/PROJECT-NAME_HOMEPAGE_URL.rst
index 22cc304..4800b13 100644
--- a/Help/variable/PROJECT-NAME_HOMEPAGE_URL.rst
+++ b/Help/variable/PROJECT-NAME_HOMEPAGE_URL.rst
@@ -1,5 +1,7 @@
 <PROJECT-NAME>_HOMEPAGE_URL
 ---------------------------
 
+.. versionadded:: 3.12
+
 Value given to the ``HOMEPAGE_URL`` option of the most recent call to the
 :command:`project` command with project name ``<PROJECT-NAME>``, if any.
diff --git a/Help/variable/PROJECT_DESCRIPTION.rst b/Help/variable/PROJECT_DESCRIPTION.rst
index 2833e11..1fefcdc 100644
--- a/Help/variable/PROJECT_DESCRIPTION.rst
+++ b/Help/variable/PROJECT_DESCRIPTION.rst
@@ -1,6 +1,8 @@
 PROJECT_DESCRIPTION
 -------------------
 
+.. versionadded:: 3.9
+
 Short project description given to the project command.
 
 This is the description given to the most recently called :command:`project`
diff --git a/Help/variable/PROJECT_HOMEPAGE_URL.rst b/Help/variable/PROJECT_HOMEPAGE_URL.rst
index 754c9e8..0d2c937 100644
--- a/Help/variable/PROJECT_HOMEPAGE_URL.rst
+++ b/Help/variable/PROJECT_HOMEPAGE_URL.rst
@@ -1,6 +1,8 @@
 PROJECT_HOMEPAGE_URL
 --------------------
 
+.. versionadded:: 3.12
+
 The homepage URL of the project.
 
 This is the homepage URL given to the most recently called :command:`project`
diff --git a/Help/variable/PackageName_ROOT.rst b/Help/variable/PackageName_ROOT.rst
index 1c2fd34..3f7ee4c 100644
--- a/Help/variable/PackageName_ROOT.rst
+++ b/Help/variable/PackageName_ROOT.rst
@@ -1,6 +1,8 @@
 <PackageName>_ROOT
 ------------------
 
+.. versionadded:: 3.12.1
+
 Calls to :command:`find_package(<PackageName>)` will search in prefixes
 specified by the ``<PackageName>_ROOT`` CMake variable, where
 ``<PackageName>`` is the name given to the :command:`find_package` call
diff --git a/Help/variable/WINCE.rst b/Help/variable/WINCE.rst
index 54ff7de..4dca297 100644
--- a/Help/variable/WINCE.rst
+++ b/Help/variable/WINCE.rst
@@ -1,5 +1,7 @@
 WINCE
 -----
 
+.. versionadded:: 3.1
+
 True when the :variable:`CMAKE_SYSTEM_NAME` variable is set
 to ``WindowsCE``.
diff --git a/Help/variable/WINDOWS_PHONE.rst b/Help/variable/WINDOWS_PHONE.rst
index 61d91b0..bf7099d 100644
--- a/Help/variable/WINDOWS_PHONE.rst
+++ b/Help/variable/WINDOWS_PHONE.rst
@@ -1,5 +1,7 @@
 WINDOWS_PHONE
 -------------
 
+.. versionadded:: 3.1
+
 True when the :variable:`CMAKE_SYSTEM_NAME` variable is set
 to ``WindowsPhone``.
diff --git a/Help/variable/WINDOWS_STORE.rst b/Help/variable/WINDOWS_STORE.rst
index dae3b53..13831c2 100644
--- a/Help/variable/WINDOWS_STORE.rst
+++ b/Help/variable/WINDOWS_STORE.rst
@@ -1,5 +1,7 @@
 WINDOWS_STORE
 -------------
 
+.. versionadded:: 3.1
+
 True when the :variable:`CMAKE_SYSTEM_NAME` variable is set
 to ``WindowsStore``.
diff --git a/Help/variable/XCODE.rst b/Help/variable/XCODE.rst
index 99f20fb..167ca86 100644
--- a/Help/variable/XCODE.rst
+++ b/Help/variable/XCODE.rst
@@ -1,4 +1,6 @@
 XCODE
 -----
 
+.. versionadded:: 3.7
+
 ``True`` when using :generator:`Xcode` generator.
diff --git a/Modules/AndroidTestUtilities.cmake b/Modules/AndroidTestUtilities.cmake
index 95e2ef7..ddccf58 100644
--- a/Modules/AndroidTestUtilities.cmake
+++ b/Modules/AndroidTestUtilities.cmake
@@ -5,6 +5,8 @@
 AndroidTestUtilities
 ------------------------
 
+.. versionadded:: 3.7
+
 Create a test that automatically loads specified data onto an Android device.
 
 Introduction
diff --git a/Modules/BundleUtilities.cmake b/Modules/BundleUtilities.cmake
index 2f3b9e1..f521d22 100644
--- a/Modules/BundleUtilities.cmake
+++ b/Modules/BundleUtilities.cmake
@@ -894,11 +894,16 @@
   # to install_name_tool:
   #
   if(changes)
-    set(cmd ${CMAKE_INSTALL_NAME_TOOL} ${changes} "${resolved_embedded_item}")
-    execute_process(COMMAND ${cmd} RESULT_VARIABLE install_name_tool_result)
-    if(NOT install_name_tool_result EQUAL 0)
-      string(REPLACE ";" "' '" msg "'${cmd}'")
-      message(FATAL_ERROR "Command failed:\n ${msg}")
+    # Check for a script by extension (.bat,.sh,...) or if the file starts with "#!" (shebang)
+    file(READ ${resolved_embedded_item} file_contents LIMIT 5)
+    if(NOT "${resolved_embedded_item}" MATCHES "\\.(bat|c?sh|bash|ksh|cmd)$" AND
+       NOT file_contents MATCHES "^#!")
+      set(cmd ${CMAKE_INSTALL_NAME_TOOL} ${changes} "${resolved_embedded_item}")
+      execute_process(COMMAND ${cmd} RESULT_VARIABLE install_name_tool_result)
+      if(NOT install_name_tool_result EQUAL 0)
+        string(REPLACE ";" "' '" msg "'${cmd}'")
+        message(FATAL_ERROR "Command failed:\n ${msg}")
+      endif()
     endif()
   endif()
 endfunction()
diff --git a/Modules/CMakeASMInformation.cmake b/Modules/CMakeASMInformation.cmake
index 03195cc..2dc1585 100644
--- a/Modules/CMakeASMInformation.cmake
+++ b/Modules/CMakeASMInformation.cmake
@@ -96,15 +96,5 @@
   set(CMAKE_EXECUTABLE_RPATH_LINK_ASM${ASM_DIALECT}_FLAG ${CMAKE_SHARED_LIBRARY_RPATH_LINK_ASM${ASM_DIALECT}_FLAG})
 endif()
 
-# to be done
-if(NOT CMAKE_ASM${ASM_DIALECT}_CREATE_SHARED_LIBRARY)
-  set(CMAKE_ASM${ASM_DIALECT}_CREATE_SHARED_LIBRARY)
-endif()
-
-if(NOT CMAKE_ASM${ASM_DIALECT}_CREATE_SHARED_MODULE)
-  set(CMAKE_ASM${ASM_DIALECT}_CREATE_SHARED_MODULE)
-endif()
-
 
 set(CMAKE_ASM${ASM_DIALECT}_INFOMATION_LOADED 1)
-
diff --git a/Modules/CMakeDetermineASMCompiler.cmake b/Modules/CMakeDetermineASMCompiler.cmake
index bc8b86b..a3e5a12 100644
--- a/Modules/CMakeDetermineASMCompiler.cmake
+++ b/Modules/CMakeDetermineASMCompiler.cmake
@@ -11,7 +11,7 @@
   if(NOT $ENV{ASM${ASM_DIALECT}} STREQUAL "")
     get_filename_component(CMAKE_ASM${ASM_DIALECT}_COMPILER_INIT $ENV{ASM${ASM_DIALECT}} PROGRAM PROGRAM_ARGS CMAKE_ASM${ASM_DIALECT}_FLAGS_ENV_INIT)
     if(CMAKE_ASM${ASM_DIALECT}_FLAGS_ENV_INIT)
-      set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ARG1 "${CMAKE_ASM${ASM_DIALECT}_FLAGS_ENV_INIT}" CACHE STRING "First argument to ASM${ASM_DIALECT} compiler")
+      set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ARG1 "${CMAKE_ASM${ASM_DIALECT}_FLAGS_ENV_INIT}" CACHE STRING "Arguments to ASM${ASM_DIALECT} compiler")
     endif()
     if(NOT EXISTS ${CMAKE_ASM${ASM_DIALECT}_COMPILER_INIT})
       message(FATAL_ERROR "Could not find compiler set in environment variable ASM${ASM_DIALECT}:\n$ENV{ASM${ASM_DIALECT}}.")
diff --git a/Modules/CMakeDetermineCCompiler.cmake b/Modules/CMakeDetermineCCompiler.cmake
index 86683d1..96f32e5 100644
--- a/Modules/CMakeDetermineCCompiler.cmake
+++ b/Modules/CMakeDetermineCCompiler.cmake
@@ -43,7 +43,7 @@
     if(NOT $ENV{CC} STREQUAL "")
       get_filename_component(CMAKE_C_COMPILER_INIT $ENV{CC} PROGRAM PROGRAM_ARGS CMAKE_C_FLAGS_ENV_INIT)
       if(CMAKE_C_FLAGS_ENV_INIT)
-        set(CMAKE_C_COMPILER_ARG1 "${CMAKE_C_FLAGS_ENV_INIT}" CACHE STRING "First argument to C compiler")
+        set(CMAKE_C_COMPILER_ARG1 "${CMAKE_C_FLAGS_ENV_INIT}" CACHE STRING "Arguments to C compiler")
       endif()
       if(NOT EXISTS ${CMAKE_C_COMPILER_INIT})
         message(FATAL_ERROR "Could not find compiler set in environment variable CC:\n$ENV{CC}.")
@@ -87,7 +87,9 @@
     "--target=arm-arm-none-eabi -mcpu=cortex-m3"
     )
 endif()
-
+if(CMAKE_C_COMPILER_TARGET)
+  list(PREPEND CMAKE_C_COMPILER_ID_TEST_FLAGS "-c --target=${CMAKE_C_COMPILER_TARGET}")
+endif()
 # Build a small source file to identify the compiler.
 if(NOT CMAKE_C_COMPILER_ID_RUN)
   set(CMAKE_C_COMPILER_ID_RUN 1)
diff --git a/Modules/CMakeDetermineCUDACompiler.cmake b/Modules/CMakeDetermineCUDACompiler.cmake
index fa497cd..daca382 100644
--- a/Modules/CMakeDetermineCUDACompiler.cmake
+++ b/Modules/CMakeDetermineCUDACompiler.cmake
@@ -19,7 +19,7 @@
       if(NOT $ENV{CUDACXX} STREQUAL "")
         get_filename_component(CMAKE_CUDA_COMPILER_INIT $ENV{CUDACXX} PROGRAM PROGRAM_ARGS CMAKE_CUDA_FLAGS_ENV_INIT)
         if(CMAKE_CUDA_FLAGS_ENV_INIT)
-          set(CMAKE_CUDA_COMPILER_ARG1 "${CMAKE_CUDA_FLAGS_ENV_INIT}" CACHE STRING "First argument to CXX compiler")
+          set(CMAKE_CUDA_COMPILER_ARG1 "${CMAKE_CUDA_FLAGS_ENV_INIT}" CACHE STRING "Arguments to CXX compiler")
         endif()
         if(NOT EXISTS ${CMAKE_CUDA_COMPILER_INIT})
           message(FATAL_ERROR "Could not find compiler set in environment variable CUDACXX:\n$ENV{CUDACXX}.\n${CMAKE_CUDA_COMPILER_INIT}")
@@ -232,7 +232,7 @@
   list(APPEND CMAKE_CUDA_COMPILER_ID_TEST_FLAGS_FIRST "${clang_test_flags}")
 
   # We perform compiler identification for a second time to extract implicit linking info and host compiler for NVCC.
-  # We also use it to verify that CMAKE_CUDA_ARCHITECTURES and additionaly on Clang that CUDA toolkit path works.
+  # We also use it to verify that CMAKE_CUDA_ARCHITECTURES and additionally on Clang that CUDA toolkit path works.
   # The latter could be done during compiler testing in the future to avoid doing this for Clang.
   # We need to unset the compiler ID otherwise CMAKE_DETERMINE_COMPILER_ID() doesn't work.
   set(CMAKE_CUDA_COMPILER_ID)
diff --git a/Modules/CMakeDetermineCXXCompiler.cmake b/Modules/CMakeDetermineCXXCompiler.cmake
index 662b831..4c2924a 100644
--- a/Modules/CMakeDetermineCXXCompiler.cmake
+++ b/Modules/CMakeDetermineCXXCompiler.cmake
@@ -42,7 +42,7 @@
     if(NOT $ENV{CXX} STREQUAL "")
       get_filename_component(CMAKE_CXX_COMPILER_INIT $ENV{CXX} PROGRAM PROGRAM_ARGS CMAKE_CXX_FLAGS_ENV_INIT)
       if(CMAKE_CXX_FLAGS_ENV_INIT)
-        set(CMAKE_CXX_COMPILER_ARG1 "${CMAKE_CXX_FLAGS_ENV_INIT}" CACHE STRING "First argument to CXX compiler")
+        set(CMAKE_CXX_COMPILER_ARG1 "${CMAKE_CXX_FLAGS_ENV_INIT}" CACHE STRING "Arguments to CXX compiler")
       endif()
       if(NOT EXISTS ${CMAKE_CXX_COMPILER_INIT})
         message(FATAL_ERROR "Could not find compiler set in environment variable CXX:\n$ENV{CXX}.\n${CMAKE_CXX_COMPILER_INIT}")
@@ -83,6 +83,10 @@
     )
 endif()
 
+if(CMAKE_CXX_COMPILER_TARGET)
+  list(PREPEND CMAKE_CXX_COPMILER_ID_TEST_FLAGS "-c --target=${CMAKE_CXX_COMPILER_TARGET}")
+endif()
+
 # Build a small source file to identify the compiler.
 if(NOT CMAKE_CXX_COMPILER_ID_RUN)
   set(CMAKE_CXX_COMPILER_ID_RUN 1)
diff --git a/Modules/CMakeDetermineCompiler.cmake b/Modules/CMakeDetermineCompiler.cmake
index cb1ab1d..2780399 100644
--- a/Modules/CMakeDetermineCompiler.cmake
+++ b/Modules/CMakeDetermineCompiler.cmake
@@ -107,16 +107,14 @@
   if(CMAKE_${lang}_COMPILER)
     # we only get here if CMAKE_${lang}_COMPILER was specified using -D or a pre-made CMakeCache.txt
     # (e.g. via ctest) or set in CMAKE_TOOLCHAIN_FILE
-    # if CMAKE_${lang}_COMPILER is a list of length 2, use the first item as
-    # CMAKE_${lang}_COMPILER and the 2nd one as CMAKE_${lang}_COMPILER_ARG1
-    list(LENGTH CMAKE_${lang}_COMPILER _CMAKE_${lang}_COMPILER_LIST_LENGTH)
-    if("${_CMAKE_${lang}_COMPILER_LIST_LENGTH}" EQUAL 2)
-      list(GET CMAKE_${lang}_COMPILER 1 CMAKE_${lang}_COMPILER_ARG1)
-      list(GET CMAKE_${lang}_COMPILER 0 CMAKE_${lang}_COMPILER)
-    endif()
-    unset(_CMAKE_${lang}_COMPILER_LIST_LENGTH)
+    # if CMAKE_${lang}_COMPILER is a list, use the first item as
+    # CMAKE_${lang}_COMPILER and the rest as CMAKE_${lang}_COMPILER_ARG1
+    set(CMAKE_${lang}_COMPILER_ARG1 "${CMAKE_${lang}_COMPILER}")
+    list(POP_FRONT CMAKE_${lang}_COMPILER_ARG1 CMAKE_${lang}_COMPILER)
+    list(JOIN CMAKE_${lang}_COMPILER_ARG1 " " CMAKE_${lang}_COMPILER_ARG1)
 
     # find the compiler in the PATH if necessary
+    # if compiler (and arguments) comes from cache then synchronize cache with updated CMAKE_<LANG>_COMPILER
     get_filename_component(_CMAKE_USER_${lang}_COMPILER_PATH "${CMAKE_${lang}_COMPILER}" PATH)
     if(NOT _CMAKE_USER_${lang}_COMPILER_PATH)
       find_program(CMAKE_${lang}_COMPILER_WITH_PATH NAMES ${CMAKE_${lang}_COMPILER})
@@ -129,6 +127,12 @@
         unset(_CMAKE_${lang}_COMPILER_CACHED)
       endif()
       unset(CMAKE_${lang}_COMPILER_WITH_PATH CACHE)
+    elseif (EXISTS ${CMAKE_${lang}_COMPILER})
+      get_property(_CMAKE_${lang}_COMPILER_CACHED CACHE CMAKE_${lang}_COMPILER PROPERTY TYPE)
+      if(_CMAKE_${lang}_COMPILER_CACHED)
+        set(CMAKE_${lang}_COMPILER "${CMAKE_${lang}_COMPILER}" CACHE STRING "${lang} compiler" FORCE)
+      endif()
+      unset(_CMAKE_${lang}_COMPILER_CACHED)
     endif()
   endif()
 endmacro()
diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake
index 44332a6..d7a35e1 100644
--- a/Modules/CMakeDetermineCompilerId.cmake
+++ b/Modules/CMakeDetermineCompilerId.cmake
@@ -14,8 +14,10 @@
   # Make sure user-specified compiler flags are used.
   if(CMAKE_${lang}_FLAGS)
     set(CMAKE_${lang}_COMPILER_ID_FLAGS ${CMAKE_${lang}_FLAGS})
-  else()
+  elseif(DEFINED ENV{${flagvar}})
     set(CMAKE_${lang}_COMPILER_ID_FLAGS $ENV{${flagvar}})
+  else(CMAKE_${lang}_FLAGS_INIT)
+    set(CMAKE_${lang}_COMPILER_ID_FLAGS ${CMAKE_${lang}_FLAGS_INIT})
   endif()
   string(REPLACE " " ";" CMAKE_${lang}_COMPILER_ID_FLAGS_LIST "${CMAKE_${lang}_COMPILER_ID_FLAGS}")
 
@@ -248,7 +250,7 @@
     set(id_PostBuildEvent_Command "")
     if(CMAKE_VS_PLATFORM_TOOLSET MATCHES "^[Ll][Ll][Vv][Mm](_v[0-9]+(_xp)?)?$")
       set(id_cl_var "ClangClExecutable")
-    elseif(CMAKE_VS_PLATFORM_TOOLSET MATCHES "^[Cc][Ll][Aa][Nn][Gg][Cc][Ll]$")
+    elseif(CMAKE_VS_PLATFORM_TOOLSET MATCHES "^[Cc][Ll][Aa][Nn][Gg]([Cc][Ll]$|_[0-9])")
       set(id_cl "$(CLToolExe)")
     elseif(CMAKE_VS_PLATFORM_TOOLSET MATCHES "v[0-9]+_clang_.*")
       set(id_cl clang.exe)
@@ -310,17 +312,36 @@
       set(id_PreferredToolArchitecture "")
     endif()
     if(CMAKE_SYSTEM_NAME STREQUAL "WindowsPhone")
+      set(id_keyword "Win32Proj")
       set(id_system "<ApplicationType>Windows Phone</ApplicationType>")
     elseif(CMAKE_SYSTEM_NAME STREQUAL "WindowsStore")
+      set(id_keyword "Win32Proj")
       set(id_system "<ApplicationType>Windows Store</ApplicationType>")
+    elseif(CMAKE_SYSTEM_NAME STREQUAL "Android")
+      set(id_keyword "Android")
+      set(id_system "<ApplicationType>Android</ApplicationType>")
     else()
+      set(id_keyword "Win32Proj")
       set(id_system "")
     endif()
-    if(id_system AND CMAKE_SYSTEM_VERSION MATCHES "^([0-9]+\\.[0-9]+)")
+    if(id_keyword STREQUAL "Android")
+      if(CMAKE_GENERATOR MATCHES "Visual Studio 14")
+        set(id_system_version "<ApplicationTypeRevision>2.0</ApplicationTypeRevision>")
+      elseif(CMAKE_GENERATOR MATCHES "Visual Studio 1[56]")
+        set(id_system_version "<ApplicationTypeRevision>3.0</ApplicationTypeRevision>")
+      else()
+        set(id_system_version "")
+      endif()
+    elseif(id_system AND CMAKE_SYSTEM_VERSION MATCHES "^([0-9]+\\.[0-9]+)")
       set(id_system_version "<ApplicationTypeRevision>${CMAKE_MATCH_1}</ApplicationTypeRevision>")
     else()
       set(id_system_version "")
     endif()
+    if(id_keyword STREQUAL "Android")
+      set(id_config_type "DynamicLibrary")
+    else()
+      set(id_config_type "Application")
+    endif()
     if(CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION)
       set(id_WindowsTargetPlatformVersion "<WindowsTargetPlatformVersion>${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}</WindowsTargetPlatformVersion>")
     endif()
@@ -333,9 +354,11 @@
         string(APPEND id_CustomGlobals "<${CMAKE_MATCH_1}>${CMAKE_MATCH_2}</${CMAKE_MATCH_1}>\n    ")
       endif()
     endforeach()
-    if(id_platform STREQUAL ARM64)
+    if(id_keyword STREQUAL "Android")
+      set(id_WindowsSDKDesktopARMSupport "")
+    elseif(id_platform STREQUAL "ARM64")
       set(id_WindowsSDKDesktopARMSupport "<WindowsSDKDesktopARM64Support>true</WindowsSDKDesktopARM64Support>")
-    elseif(id_platform STREQUAL ARM)
+    elseif(id_platform STREQUAL "ARM")
       set(id_WindowsSDKDesktopARMSupport "<WindowsSDKDesktopARMSupport>true</WindowsSDKDesktopARMSupport>")
     else()
       set(id_WindowsSDKDesktopARMSupport "")
@@ -702,7 +725,7 @@
     foreach(info ${CMAKE_${lang}_COMPILER_ID_STRINGS})
       # The IAR-AVR compiler uses a binary format that places a '6'
       # character (0x34) before each character in the string.  Strip
-      # out these characters without removing any legitamate characters.
+      # out these characters without removing any legitimate characters.
       if("${info}" MATCHES "(.)I.N.F.O.:.")
         string(REGEX REPLACE "${CMAKE_MATCH_1}(.)" "\\1" info "${info}")
       endif()
diff --git a/Modules/CMakeDetermineFortranCompiler.cmake b/Modules/CMakeDetermineFortranCompiler.cmake
index 5f5a70a..8a57408 100644
--- a/Modules/CMakeDetermineFortranCompiler.cmake
+++ b/Modules/CMakeDetermineFortranCompiler.cmake
@@ -26,7 +26,7 @@
     if(NOT $ENV{FC} STREQUAL "")
       get_filename_component(CMAKE_Fortran_COMPILER_INIT $ENV{FC} PROGRAM PROGRAM_ARGS CMAKE_Fortran_FLAGS_ENV_INIT)
       if(CMAKE_Fortran_FLAGS_ENV_INIT)
-        set(CMAKE_Fortran_COMPILER_ARG1 "${CMAKE_Fortran_FLAGS_ENV_INIT}" CACHE STRING "First argument to Fortran compiler")
+        set(CMAKE_Fortran_COMPILER_ARG1 "${CMAKE_Fortran_FLAGS_ENV_INIT}" CACHE STRING "Arguments to Fortran compiler")
       endif()
       if(EXISTS ${CMAKE_Fortran_COMPILER_INIT})
       else()
diff --git a/Modules/CMakeDetermineJavaCompiler.cmake b/Modules/CMakeDetermineJavaCompiler.cmake
index 3092bb5..db456c0 100644
--- a/Modules/CMakeDetermineJavaCompiler.cmake
+++ b/Modules/CMakeDetermineJavaCompiler.cmake
@@ -11,7 +11,7 @@
   if(NOT $ENV{JAVA_COMPILER} STREQUAL "")
     get_filename_component(CMAKE_Java_COMPILER_INIT $ENV{JAVA_COMPILER} PROGRAM PROGRAM_ARGS CMAKE_Java_FLAGS_ENV_INIT)
     if(CMAKE_Java_FLAGS_ENV_INIT)
-      set(CMAKE_Java_COMPILER_ARG1 "${CMAKE_Java_FLAGS_ENV_INIT}" CACHE STRING "First argument to Java compiler")
+      set(CMAKE_Java_COMPILER_ARG1 "${CMAKE_Java_FLAGS_ENV_INIT}" CACHE STRING "Arguments to Java compiler")
     endif()
     if(NOT EXISTS ${CMAKE_Java_COMPILER_INIT})
       message(SEND_ERROR "Could not find compiler set in environment variable JAVA_COMPILER:\n$ENV{JAVA_COMPILER}.")
diff --git a/Modules/CMakeDetermineOBJCCompiler.cmake b/Modules/CMakeDetermineOBJCCompiler.cmake
index 11b47fd..709eb25 100644
--- a/Modules/CMakeDetermineOBJCCompiler.cmake
+++ b/Modules/CMakeDetermineOBJCCompiler.cmake
@@ -39,7 +39,7 @@
       if($ENV{${var}} MATCHES ".+")
         get_filename_component(CMAKE_OBJC_COMPILER_INIT $ENV{${var}} PROGRAM PROGRAM_ARGS CMAKE_OBJC_FLAGS_ENV_INIT)
         if(CMAKE_OBJC_FLAGS_ENV_INIT)
-          set(CMAKE_OBJC_COMPILER_ARG1 "${CMAKE_OBJC_FLAGS_ENV_INIT}" CACHE STRING "First argument to Objective-C compiler")
+          set(CMAKE_OBJC_COMPILER_ARG1 "${CMAKE_OBJC_FLAGS_ENV_INIT}" CACHE STRING "Arguments to Objective-C compiler")
         endif()
         if(NOT EXISTS ${CMAKE_OBJC_COMPILER_INIT})
           message(FATAL_ERROR "Could not find compiler set in environment variable ${var}:\n  $ENV{${var}}")
@@ -65,14 +65,11 @@
   else()
     # we only get here if CMAKE_OBJC_COMPILER was specified using -D or a pre-made CMakeCache.txt
     # (e.g. via ctest) or set in CMAKE_TOOLCHAIN_FILE
-    # if CMAKE_OBJC_COMPILER is a list of length 2, use the first item as
-    # CMAKE_OBJC_COMPILER and the 2nd one as CMAKE_OBJC_COMPILER_ARG1
-
-    list(LENGTH CMAKE_OBJC_COMPILER _CMAKE_OBJC_COMPILER_LIST_LENGTH)
-    if("${_CMAKE_OBJC_COMPILER_LIST_LENGTH}" EQUAL 2)
-      list(GET CMAKE_OBJC_COMPILER 1 CMAKE_OBJC_COMPILER_ARG1)
-      list(GET CMAKE_OBJC_COMPILER 0 CMAKE_OBJC_COMPILER)
-    endif()
+    # if CMAKE_OBJC_COMPILER is a list, use the first item as
+    # CMAKE_OBJC_COMPILER and the rest as CMAKE_OBJC_COMPILER_ARG1
+    set(CMAKE_OBJC_COMPILER_ARG1 "${CMAKE_OBJC_COMPILER}")
+    list(POP_FRONT CMAKE_OBJC_COMPILER_ARG1 CMAKE_OBJC_COMPILER)
+    list(JOIN CMAKE_OBJC_COMPILER_ARG1 " " CMAKE_OBJC_COMPILER_ARG1)
 
     # if a compiler was specified by the user but without path,
     # now try to find it with the full path
diff --git a/Modules/CMakeDetermineOBJCXXCompiler.cmake b/Modules/CMakeDetermineOBJCXXCompiler.cmake
index 99ad6c3..ffd0091 100644
--- a/Modules/CMakeDetermineOBJCXXCompiler.cmake
+++ b/Modules/CMakeDetermineOBJCXXCompiler.cmake
@@ -41,7 +41,7 @@
       if($ENV{${var}} MATCHES ".+")
         get_filename_component(CMAKE_OBJCXX_COMPILER_INIT $ENV{${var}} PROGRAM PROGRAM_ARGS CMAKE_OBJCXX_FLAGS_ENV_INIT)
         if(CMAKE_OBJCXX_FLAGS_ENV_INIT)
-          set(CMAKE_OBJCXX_COMPILER_ARG1 "${CMAKE_OBJCXX_FLAGS_ENV_INIT}" CACHE STRING "First argument to Objective-C++ compiler")
+          set(CMAKE_OBJCXX_COMPILER_ARG1 "${CMAKE_OBJCXX_FLAGS_ENV_INIT}" CACHE STRING "Arguments to Objective-C++ compiler")
         endif()
         if(NOT EXISTS ${CMAKE_OBJCXX_COMPILER_INIT})
           message(FATAL_ERROR "Could not find compiler set in environment variable ${var}:\n  $ENV{${var}}")
@@ -67,14 +67,11 @@
   else()
     # we only get here if CMAKE_OBJCXX_COMPILER was specified using -D or a pre-made CMakeCache.txt
     # (e.g. via ctest) or set in CMAKE_TOOLCHAIN_FILE
-    # if CMAKE_OBJCXX_COMPILER is a list of length 2, use the first item as
-    # CMAKE_OBJCXX_COMPILER and the 2nd one as CMAKE_OBJCXX_COMPILER_ARG1
-
-    list(LENGTH CMAKE_OBJCXX_COMPILER _CMAKE_OBJCXX_COMPILER_LIST_LENGTH)
-    if("${_CMAKE_OBJCXX_COMPILER_LIST_LENGTH}" EQUAL 2)
-      list(GET CMAKE_OBJCXX_COMPILER 1 CMAKE_OBJCXX_COMPILER_ARG1)
-      list(GET CMAKE_OBJCXX_COMPILER 0 CMAKE_OBJCXX_COMPILER)
-    endif()
+    # if CMAKE_OBJCXX_COMPILER is a list, use the first item as
+    # CMAKE_OBJCXX_COMPILER and the rest as CMAKE_OBJCXX_COMPILER_ARG1
+    set(CMAKE_OBJCXX_COMPILER_ARG1 "${CMAKE_OBJCXX_COMPILER}")
+    list(POP_FRONT CMAKE_OBJCXX_COMPILER_ARG1 CMAKE_OBJCXX_COMPILER)
+    list(JOIN CMAKE_OBJCXX_COMPILER_ARG1 " " CMAKE_OBJCXX_COMPILER_ARG1)
 
     # if a compiler was specified by the user but without path,
     # now try to find it with the full path
diff --git a/Modules/CMakeDetermineRCCompiler.cmake b/Modules/CMakeDetermineRCCompiler.cmake
index 8801e16..f8d55a5 100644
--- a/Modules/CMakeDetermineRCCompiler.cmake
+++ b/Modules/CMakeDetermineRCCompiler.cmake
@@ -13,7 +13,7 @@
   if(NOT $ENV{RC} STREQUAL "")
     get_filename_component(CMAKE_RC_COMPILER_INIT $ENV{RC} PROGRAM PROGRAM_ARGS CMAKE_RC_FLAGS_ENV_INIT)
     if(CMAKE_RC_FLAGS_ENV_INIT)
-      set(CMAKE_RC_COMPILER_ARG1 "${CMAKE_RC_FLAGS_ENV_INIT}" CACHE STRING "First argument to RC compiler")
+      set(CMAKE_RC_COMPILER_ARG1 "${CMAKE_RC_FLAGS_ENV_INIT}" CACHE STRING "Arguments to RC compiler")
     endif()
     if(EXISTS ${CMAKE_RC_COMPILER_INIT})
     else()
diff --git a/Modules/CMakeDetermineSwiftCompiler.cmake b/Modules/CMakeDetermineSwiftCompiler.cmake
index 688133f..aaad560 100644
--- a/Modules/CMakeDetermineSwiftCompiler.cmake
+++ b/Modules/CMakeDetermineSwiftCompiler.cmake
@@ -27,7 +27,7 @@
         PROGRAM_ARGS CMAKE_Swift_FLAGS_ENV_INIT)
       if(CMAKE_Swift_FLAGS_ENV_INIT)
         set(CMAKE_Swift_COMPILER_ARG1 "${CMAKE_Swift_FLAGS_ENV_INIT}" CACHE
-          STRING "First argument to the Swift compiler")
+          STRING "Arguments to the Swift compiler")
       endif()
       if(NOT EXISTS ${CMAKE_Swift_COMPILER_INIT})
         message(FATAL_ERROR "Could not find compiler set in environment variable SWIFTC\n$ENV{SWIFTC}.\n${CMAKE_Swift_COMPILER_INIT}")
diff --git a/Modules/CMakeParseImplicitIncludeInfo.cmake b/Modules/CMakeParseImplicitIncludeInfo.cmake
index ff4c325..7cd7548 100644
--- a/Modules/CMakeParseImplicitIncludeInfo.cmake
+++ b/Modules/CMakeParseImplicitIncludeInfo.cmake
@@ -7,7 +7,7 @@
 # for compilers that report them that way.  on success we return the
 # list of dirs in id_var and set state_var to the 'done' state.
 function(cmake_parse_implicit_include_line line lang id_var log_var state_var)
-  # clear variables we append to (avoids possible polution from parent scopes)
+  # clear variables we append to (avoids possible pollution from parent scopes)
   unset(rv)
   set(log "")
 
@@ -162,7 +162,7 @@
 function(cmake_parse_implicit_include_info text lang dir_var log_var state_var)
   set(state start)    # values: start, loading, done
 
-  # clear variables we append to (avoids possible polution from parent scopes)
+  # clear variables we append to (avoids possible pollution from parent scopes)
   set(implicit_dirs_tmp)
   set(log "")
 
diff --git a/Modules/CMakePlatformId.h.in b/Modules/CMakePlatformId.h.in
index 40668a3..0b81c88 100644
--- a/Modules/CMakePlatformId.h.in
+++ b/Modules/CMakePlatformId.h.in
@@ -206,6 +206,24 @@
 # else /* unknown architecture */
 #  define ARCHITECTURE_ID ""
 # endif
+
+#elif defined(__TI_COMPILER_VERSION__)
+# if defined(__TI_ARM__)
+#  define ARCHITECTURE_ID "ARM"
+
+# elif defined(__MSP430__)
+#  define ARCHITECTURE_ID "MSP430"
+
+# elif defined(__TMS320C28XX__)
+#  define ARCHITECTURE_ID "TMS320C28x"
+
+# elif defined(__TMS320C6X__) || defined(_TMS320C6X)
+#  define ARCHITECTURE_ID "TMS320C6x"
+
+# else /* unknown architecture */
+#  define ARCHITECTURE_ID ""
+# endif
+
 #else
 #  define ARCHITECTURE_ID
 #endif
@@ -283,4 +301,3 @@
    array rather than assigning a pointer to a static array.  */
 char const* info_platform = "INFO" ":" "platform[" PLATFORM_ID "]";
 char const* info_arch = "INFO" ":" "arch[" ARCHITECTURE_ID "]";
-
diff --git a/Modules/CMakeTestCCompiler.cmake b/Modules/CMakeTestCCompiler.cmake
index 3734ec4..03f2db2 100644
--- a/Modules/CMakeTestCCompiler.cmake
+++ b/Modules/CMakeTestCCompiler.cmake
@@ -11,7 +11,7 @@
 
 include(CMakeTestCompilerCommon)
 
-# work around enforced code signing and / or missing exectuable target type
+# work around enforced code signing and / or missing executable target type
 set(__CMAKE_SAVED_TRY_COMPILE_TARGET_TYPE ${CMAKE_TRY_COMPILE_TARGET_TYPE})
 if(_CMAKE_FEATURE_DETECTION_TARGET_TYPE)
   set(CMAKE_TRY_COMPILE_TARGET_TYPE ${_CMAKE_FEATURE_DETECTION_TARGET_TYPE})
diff --git a/Modules/CMakeTestCXXCompiler.cmake b/Modules/CMakeTestCXXCompiler.cmake
index b9cb1dd..0d2d0b0 100644
--- a/Modules/CMakeTestCXXCompiler.cmake
+++ b/Modules/CMakeTestCXXCompiler.cmake
@@ -11,7 +11,7 @@
 
 include(CMakeTestCompilerCommon)
 
-# work around enforced code signing and / or missing exectuable target type
+# work around enforced code signing and / or missing executable target type
 set(__CMAKE_SAVED_TRY_COMPILE_TARGET_TYPE ${CMAKE_TRY_COMPILE_TARGET_TYPE})
 if(_CMAKE_FEATURE_DETECTION_TARGET_TYPE)
   set(CMAKE_TRY_COMPILE_TARGET_TYPE ${_CMAKE_FEATURE_DETECTION_TARGET_TYPE})
diff --git a/Modules/CMakeTestOBJCCompiler.cmake b/Modules/CMakeTestOBJCCompiler.cmake
index 0e333c0..298272b 100644
--- a/Modules/CMakeTestOBJCCompiler.cmake
+++ b/Modules/CMakeTestOBJCCompiler.cmake
@@ -11,7 +11,7 @@
 
 include(CMakeTestCompilerCommon)
 
-# work around enforced code signing and / or missing exectuable target type
+# work around enforced code signing and / or missing executable target type
 set(__CMAKE_SAVED_TRY_COMPILE_TARGET_TYPE ${CMAKE_TRY_COMPILE_TARGET_TYPE})
 if(_CMAKE_FEATURE_DETECTION_TARGET_TYPE)
   set(CMAKE_TRY_COMPILE_TARGET_TYPE ${_CMAKE_FEATURE_DETECTION_TARGET_TYPE})
diff --git a/Modules/CMakeTestOBJCXXCompiler.cmake b/Modules/CMakeTestOBJCXXCompiler.cmake
index dc153a7..36e3efc 100644
--- a/Modules/CMakeTestOBJCXXCompiler.cmake
+++ b/Modules/CMakeTestOBJCXXCompiler.cmake
@@ -11,7 +11,7 @@
 
 include(CMakeTestCompilerCommon)
 
-# work around enforced code signing and / or missing exectuable target type
+# work around enforced code signing and / or missing executable target type
 set(__CMAKE_SAVED_TRY_COMPILE_TARGET_TYPE ${CMAKE_TRY_COMPILE_TARGET_TYPE})
 if(_CMAKE_FEATURE_DETECTION_TARGET_TYPE)
   set(CMAKE_TRY_COMPILE_TARGET_TYPE ${_CMAKE_FEATURE_DETECTION_TARGET_TYPE})
diff --git a/Modules/CPack.cmake b/Modules/CPack.cmake
index d0cfc2b..8a0ef30 100644
--- a/Modules/CPack.cmake
+++ b/Modules/CPack.cmake
@@ -22,9 +22,13 @@
 The generated binary installers will contain all files that have been installed
 via CMake's :command:`install` command (and the deprecated commands
 :command:`install_files`, :command:`install_programs`, and
-:command:`install_targets`).  Certain kinds of binary installers can be
-configured such that users can select individual application components to
-install.  See the :module:`CPackComponent` module for further details.
+:command:`install_targets`). Note that the ``DESTINATION`` option of the
+:command:`install` command must be a relative path; otherwise installed files
+are ignored by CPack.
+
+Certain kinds of binary installers can be configured such that users can select
+individual application components to install.  See the :module:`CPackComponent`
+module for further details.
 
 Source packages (configured through ``CPackSourceConfig.cmake`` and generated
 by the :cpack_gen:`CPack Archive Generator`) will contain all source files in
@@ -386,6 +390,21 @@
   select the CPack generator(s) to be used when building the ``package``
   target or when running :manual:`cpack <cpack(1)>` without the ``-G`` option.
 
+.. variable:: CPACK_PRE_BUILD_SCRIPTS
+
+  List of CMake scripts to execute after CPack has installed the files to
+  be packed into a staging directory and before producing the result
+  packages.
+
+.. variable:: CPACK_POST_BUILD_SCRIPTS
+
+  List of CMake scripts to execute after CPack has produced the result
+  packages and before copying them back to a build directory.
+
+.. variable:: CPACK_PACKAGE_FILES
+
+  List of resulting package files passed to the ``CPACK_POST_BUILD_SCRIPTS``.
+
 #]=======================================================================]
 
 # Define this var in order to avoid (or warn) concerning multiple inclusion
@@ -420,7 +439,7 @@
 # find any variable that starts with CPACK and create a variable
 # _CPACK_OTHER_VARIABLES_ that contains SET commands for
 # each cpack variable.  _CPACK_OTHER_VARIABLES_ is then
-# used as an @ replacment in configure_file for the CPackConfig.
+# used as an @ replacement in configure_file for the CPackConfig.
 function(cpack_encode_variables)
   set(commands "")
   get_cmake_property(res VARIABLES)
diff --git a/Modules/CPackIFW.cmake b/Modules/CPackIFW.cmake
index 80a907f..58e6a37 100644
--- a/Modules/CPackIFW.cmake
+++ b/Modules/CPackIFW.cmake
@@ -5,6 +5,8 @@
 CPackIFW
 --------
 
+.. versionadded:: 3.1
+
 This module looks for the location of the command-line utilities supplied with the
 `Qt Installer Framework <http://doc.qt.io/qtinstallerframework/index.html>`_
 (QtIFW).
diff --git a/Modules/CPackIFWConfigureFile.cmake b/Modules/CPackIFWConfigureFile.cmake
index 0abe0da..296b13f 100644
--- a/Modules/CPackIFWConfigureFile.cmake
+++ b/Modules/CPackIFWConfigureFile.cmake
@@ -5,6 +5,8 @@
 CPackIFWConfigureFile
 ---------------------
 
+.. versionadded:: 3.8
+
 The module defines :command:`configure_file` similar command to
 configure file templates prepared in QtIFW/SDK/Creator style.
 
diff --git a/Modules/CSharpUtilities.cmake b/Modules/CSharpUtilities.cmake
index 6a4b5c7..dedb146 100644
--- a/Modules/CSharpUtilities.cmake
+++ b/Modules/CSharpUtilities.cmake
@@ -5,6 +5,8 @@
 CSharpUtilities
 ---------------
 
+.. versionadded:: 3.8
+
 Functions to make configuration of CSharp/.NET targets easier.
 
 A collection of CMake utility functions useful for dealing with CSharp
diff --git a/Modules/CTestCoverageCollectGCOV.cmake b/Modules/CTestCoverageCollectGCOV.cmake
index b1268be..a01a2fe 100644
--- a/Modules/CTestCoverageCollectGCOV.cmake
+++ b/Modules/CTestCoverageCollectGCOV.cmake
@@ -5,6 +5,8 @@
 CTestCoverageCollectGCOV
 ------------------------
 
+.. versionadded:: 3.2
+
 This module provides the ``ctest_coverage_collect_gcov`` function.
 
 This function runs gcov on all .gcda files found in the binary tree
diff --git a/Modules/CheckFortranCompilerFlag.cmake b/Modules/CheckFortranCompilerFlag.cmake
index 299cd8c..b8fac97 100644
--- a/Modules/CheckFortranCompilerFlag.cmake
+++ b/Modules/CheckFortranCompilerFlag.cmake
@@ -5,6 +5,8 @@
 CheckFortranCompilerFlag
 ------------------------
 
+.. versionadded:: 3.3
+
 Check whether the Fortran compiler supports a given flag.
 
 .. command:: check_fortran_compiler_flag
diff --git a/Modules/CheckFortranSourceCompiles.cmake b/Modules/CheckFortranSourceCompiles.cmake
index 3354bfb..d776b0c 100644
--- a/Modules/CheckFortranSourceCompiles.cmake
+++ b/Modules/CheckFortranSourceCompiles.cmake
@@ -5,6 +5,8 @@
 CheckFortranSourceCompiles
 --------------------------
 
+.. versionadded:: 3.1
+
 Check if given Fortran source compiles and links into an executable.
 
 .. command:: check_fortran_source_compiles
diff --git a/Modules/CheckFortranSourceRuns.cmake b/Modules/CheckFortranSourceRuns.cmake
index f858b84..a710352 100644
--- a/Modules/CheckFortranSourceRuns.cmake
+++ b/Modules/CheckFortranSourceRuns.cmake
@@ -5,6 +5,8 @@
 CheckFortranSourceRuns
 ----------------------
 
+.. versionadded:: 3.14
+
 Check if given Fortran source compiles and links into an executable and can
 subsequently be run.
 
diff --git a/Modules/CheckIPOSupported.cmake b/Modules/CheckIPOSupported.cmake
index 90a9f61..1dd951d 100644
--- a/Modules/CheckIPOSupported.cmake
+++ b/Modules/CheckIPOSupported.cmake
@@ -5,6 +5,8 @@
 CheckIPOSupported
 -----------------
 
+.. versionadded:: 3.9
+
 Check whether the compiler supports an interprocedural optimization (IPO/LTO).
 Use this before enabling the :prop_tgt:`INTERPROCEDURAL_OPTIMIZATION` target
 property.
diff --git a/Modules/CheckLanguage.cmake b/Modules/CheckLanguage.cmake
index d67d8d3..44387d4 100644
--- a/Modules/CheckLanguage.cmake
+++ b/Modules/CheckLanguage.cmake
@@ -20,7 +20,7 @@
 as the compiler that was found, or ``NOTFOUND`` if the language cannot be
 enabled. For CUDA which can have an explicit host compiler, the cache
 :variable:`CMAKE_CUDA_HOST_COMPILER` variable will be set if it was required
-for compilation.
+for compilation (and cleared if it was not).
 
 Example:
 
diff --git a/Modules/CheckLinkerFlag.cmake b/Modules/CheckLinkerFlag.cmake
index beda5fe..cd7301f 100644
--- a/Modules/CheckLinkerFlag.cmake
+++ b/Modules/CheckLinkerFlag.cmake
@@ -5,6 +5,8 @@
 CheckLinkerFlag
 ---------------
 
+.. versionadded:: 3.18
+
 Check whether the compiler supports a given link flag.
 
 .. command:: check_linker_flag
diff --git a/Modules/CheckOBJCCompilerFlag.cmake b/Modules/CheckOBJCCompilerFlag.cmake
index 1d975da..a98f429 100644
--- a/Modules/CheckOBJCCompilerFlag.cmake
+++ b/Modules/CheckOBJCCompilerFlag.cmake
@@ -5,6 +5,8 @@
 CheckOBJCCompilerFlag
 ---------------------
 
+.. versionadded:: 3.16
+
 Check whether the Objective-C compiler supports a given flag.
 
 .. command:: check_objc_compiler_flag
diff --git a/Modules/CheckOBJCSourceCompiles.cmake b/Modules/CheckOBJCSourceCompiles.cmake
index 601f1fa..502ed74 100644
--- a/Modules/CheckOBJCSourceCompiles.cmake
+++ b/Modules/CheckOBJCSourceCompiles.cmake
@@ -5,6 +5,8 @@
 CheckOBJCSourceCompiles
 -----------------------
 
+.. versionadded:: 3.16
+
 Check if given Objective-C source compiles and links into an executable.
 
 .. command:: check_objc_source_compiles
diff --git a/Modules/CheckOBJCSourceRuns.cmake b/Modules/CheckOBJCSourceRuns.cmake
index 6684693..9d4fb1b 100644
--- a/Modules/CheckOBJCSourceRuns.cmake
+++ b/Modules/CheckOBJCSourceRuns.cmake
@@ -5,6 +5,8 @@
 CheckOBJCSourceRuns
 -------------------
 
+.. versionadded:: 3.16
+
 Check if given Objective-C source compiles and links into an executable and can
 subsequently be run.
 
diff --git a/Modules/CheckOBJCXXCompilerFlag.cmake b/Modules/CheckOBJCXXCompilerFlag.cmake
index c32741b..7944ab0 100644
--- a/Modules/CheckOBJCXXCompilerFlag.cmake
+++ b/Modules/CheckOBJCXXCompilerFlag.cmake
@@ -5,6 +5,8 @@
 CheckOBJCXXCompilerFlag
 -----------------------
 
+.. versionadded:: 3.16
+
 Check whether the Objective-C++ compiler supports a given flag.
 
 .. command:: check_objcxx_compiler_flag
diff --git a/Modules/CheckOBJCXXSourceCompiles.cmake b/Modules/CheckOBJCXXSourceCompiles.cmake
index 2ee79f4..7b839e4 100644
--- a/Modules/CheckOBJCXXSourceCompiles.cmake
+++ b/Modules/CheckOBJCXXSourceCompiles.cmake
@@ -5,6 +5,8 @@
 CheckOBJCXXSourceCompiles
 -------------------------
 
+.. versionadded:: 3.16
+
 Check if given Objective-C++ source compiles and links into an executable.
 
 .. command:: check_objcxx_source_compiles
diff --git a/Modules/CheckOBJCXXSourceRuns.cmake b/Modules/CheckOBJCXXSourceRuns.cmake
index 7f7e04f..c327598 100644
--- a/Modules/CheckOBJCXXSourceRuns.cmake
+++ b/Modules/CheckOBJCXXSourceRuns.cmake
@@ -5,6 +5,8 @@
 CheckOBJCXXSourceRuns
 ---------------------
 
+.. versionadded:: 3.16
+
 Check if given Objective-C++ source compiles and links into an executable and can
 subsequently be run.
 
diff --git a/Modules/CheckPIESupported.cmake b/Modules/CheckPIESupported.cmake
index 6d63f0b..a99d8c4 100644
--- a/Modules/CheckPIESupported.cmake
+++ b/Modules/CheckPIESupported.cmake
@@ -5,6 +5,8 @@
 CheckPIESupported
 -----------------
 
+.. versionadded:: 3.14
+
 Check whether the linker supports Position Independent Code (PIE) or No
 Position Independent Code (NO_PIE) for executables.
 Use this to ensure that the :prop_tgt:`POSITION_INDEPENDENT_CODE` target
diff --git a/Modules/CheckTypeSize.cmake b/Modules/CheckTypeSize.cmake
index 2b07b7c..17beadc 100644
--- a/Modules/CheckTypeSize.cmake
+++ b/Modules/CheckTypeSize.cmake
@@ -89,25 +89,7 @@
     message(CHECK_START "Check size of ${type}")
   endif()
 
-  # Include header files.
-  set(headers)
-  if(builtin)
-    if(HAVE_SYS_TYPES_H)
-      string(APPEND headers "#include <sys/types.h>\n")
-    endif()
-    if(HAVE_STDINT_H)
-      string(APPEND headers "#include <stdint.h>\n")
-    endif()
-    if(HAVE_STDDEF_H)
-      string(APPEND headers "#include <stddef.h>\n")
-    endif()
-  endif()
-  foreach(h ${CMAKE_EXTRA_INCLUDE_FILES})
-    string(APPEND headers "#include \"${h}\"\n")
-  endforeach()
-
-  # Perform the check.
-
+  # Perform language check
   if(language STREQUAL "C")
     set(src ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CheckTypeSize/${var}.c)
   elseif(language STREQUAL "CXX")
@@ -115,6 +97,37 @@
   else()
     message(FATAL_ERROR "Unknown language:\n  ${language}\nSupported languages: C, CXX.\n")
   endif()
+
+  # Include header files.
+  set(headers)
+  if(builtin)
+    if(language STREQUAL "CXX" AND type MATCHES "^std::")
+      if(HAVE_SYS_TYPES_H)
+        string(APPEND headers "#include <sys/types.h>\n")
+      endif()
+      if(HAVE_CSTDINT)
+        string(APPEND headers "#include <cstdint>\n")
+      endif()
+      if(HAVE_CSTDDEF)
+        string(APPEND headers "#include <cstddef>\n")
+      endif()
+    else()
+      if(HAVE_SYS_TYPES_H)
+        string(APPEND headers "#include <sys/types.h>\n")
+      endif()
+      if(HAVE_STDINT_H)
+        string(APPEND headers "#include <stdint.h>\n")
+      endif()
+      if(HAVE_STDDEF_H)
+        string(APPEND headers "#include <stddef.h>\n")
+      endif()
+    endif()
+  endif()
+  foreach(h ${CMAKE_EXTRA_INCLUDE_FILES})
+    string(APPEND headers "#include \"${h}\"\n")
+  endforeach()
+
+  # Perform the check.
   set(bin ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CheckTypeSize/${var}.bin)
   configure_file(${__check_type_size_dir}/CheckTypeSize.c.in ${src} @ONLY)
   try_compile(HAVE_${var} ${CMAKE_BINARY_DIR} ${src}
@@ -232,8 +245,13 @@
       check_include_file(stddef.h HAVE_STDDEF_H)
     elseif(_language STREQUAL "CXX")
       check_include_file_cxx(sys/types.h HAVE_SYS_TYPES_H)
-      check_include_file_cxx(stdint.h HAVE_STDINT_H)
-      check_include_file_cxx(stddef.h HAVE_STDDEF_H)
+      if("${TYPE}" MATCHES "^std::")
+        check_include_file_cxx(cstdint HAVE_CSTDINT)
+        check_include_file_cxx(cstddef HAVE_CSTDDEF)
+      else()
+        check_include_file_cxx(stdint.h HAVE_STDINT_H)
+        check_include_file_cxx(stddef.h HAVE_STDDEF_H)
+      endif()
     endif()
   endif()
   unset(_CHECK_TYPE_SIZE_BUILTIN_TYPES_ONLY)
diff --git a/Modules/Compiler/ARMClang.cmake b/Modules/Compiler/ARMClang.cmake
index 01ce91d..70e6ffb 100644
--- a/Modules/Compiler/ARMClang.cmake
+++ b/Modules/Compiler/ARMClang.cmake
@@ -98,7 +98,7 @@
       set(__mcpu_flag_set TRUE)
     endif()
     if(NOT __march_flag_set AND NOT __mcpu_flag_set)
-      message(FATAL_ERROR "Atleast one of the variables CMAKE_SYSTEM_PROCESSOR or CMAKE_SYSTEM_ARCH must be set for ARMClang\n"
+      message(FATAL_ERROR "At least one of the variables CMAKE_SYSTEM_PROCESSOR or CMAKE_SYSTEM_ARCH must be set for ARMClang\n"
                           "Supported processor: ${CMAKE_${lang}_COMPILER_PROCESSOR_LIST}\n"
                           "  Supported Architecture: ${CMAKE_${lang}_COMPILER_ARCH_LIST}")
     endif()
diff --git a/Modules/Compiler/AppleClang-C.cmake b/Modules/Compiler/AppleClang-C.cmake
index 2794f52..26a4bbd 100644
--- a/Modules/Compiler/AppleClang-C.cmake
+++ b/Modules/Compiler/AppleClang-C.cmake
@@ -1,6 +1,8 @@
 include(Compiler/Clang)
 __compiler_clang(C)
 
+set(CMAKE_C_COMPILE_OPTIONS_EXPLICIT_LANGUAGE -x c)
+
 if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.0)
   set(CMAKE_C90_STANDARD_COMPILE_OPTION "-std=c90")
   set(CMAKE_C90_EXTENSION_COMPILE_OPTION "-std=gnu90")
diff --git a/Modules/Compiler/AppleClang-CXX.cmake b/Modules/Compiler/AppleClang-CXX.cmake
index 15edc21..611c674 100644
--- a/Modules/Compiler/AppleClang-CXX.cmake
+++ b/Modules/Compiler/AppleClang-CXX.cmake
@@ -1,6 +1,8 @@
 include(Compiler/Clang)
 __compiler_clang(CXX)
 
+set(CMAKE_CXX_COMPILE_OPTIONS_EXPLICIT_LANGUAGE -x c++)
+
 if(NOT "x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC")
   set(CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN "-fvisibility-inlines-hidden")
 endif()
diff --git a/Modules/Compiler/Clang-C.cmake b/Modules/Compiler/Clang-C.cmake
index 7c4a263..fb6ffa7 100644
--- a/Modules/Compiler/Clang-C.cmake
+++ b/Modules/Compiler/Clang-C.cmake
@@ -8,6 +8,8 @@
 
 if("x${CMAKE_C_COMPILER_FRONTEND_VARIANT}" STREQUAL "xMSVC")
   set(CMAKE_C_CLANG_TIDY_DRIVER_MODE "cl")
+elseif("x${CMAKE_CXX_COMPILER_FRONTEND_VARIANT}" STREQUAL "xGNU")
+  set(CMAKE_C_COMPILE_OPTIONS_EXPLICIT_LANGUAGE -x c)
 endif()
 
 if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 3.4)
diff --git a/Modules/Compiler/Clang-CXX.cmake b/Modules/Compiler/Clang-CXX.cmake
index 789e991..311d2b0 100644
--- a/Modules/Compiler/Clang-CXX.cmake
+++ b/Modules/Compiler/Clang-CXX.cmake
@@ -2,7 +2,9 @@
 __compiler_clang(CXX)
 __compiler_clang_cxx_standards(CXX)
 
+
 if("x${CMAKE_CXX_COMPILER_FRONTEND_VARIANT}" STREQUAL "xGNU")
+  set(CMAKE_CXX_COMPILE_OPTIONS_EXPLICIT_LANGUAGE -x c++)
   set(CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN "-fvisibility-inlines-hidden")
 endif()
 
diff --git a/Modules/Compiler/GNU-C.cmake b/Modules/Compiler/GNU-C.cmake
index ca286b3..8105a77 100644
--- a/Modules/Compiler/GNU-C.cmake
+++ b/Modules/Compiler/GNU-C.cmake
@@ -1,6 +1,8 @@
 include(Compiler/GNU)
 __compiler_gnu(C)
 
+set(CMAKE_C_COMPILE_OPTIONS_EXPLICIT_LANGUAGE -x c)
+
 if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.5)
   set(CMAKE_C90_STANDARD_COMPILE_OPTION "-std=c90")
   set(CMAKE_C90_EXTENSION_COMPILE_OPTION "-std=gnu90")
diff --git a/Modules/Compiler/GNU-CXX.cmake b/Modules/Compiler/GNU-CXX.cmake
index fcaaeab..59ec056 100644
--- a/Modules/Compiler/GNU-CXX.cmake
+++ b/Modules/Compiler/GNU-CXX.cmake
@@ -1,6 +1,8 @@
 include(Compiler/GNU)
 __compiler_gnu(CXX)
 
+set(CMAKE_CXX_COMPILE_OPTIONS_EXPLICIT_LANGUAGE -x c++)
+
 if (WIN32)
   if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.6)
     set(CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN "-fno-keep-inline-dllexport")
diff --git a/Modules/Compiler/Intel-C.cmake b/Modules/Compiler/Intel-C.cmake
index ec3bfd8..322f63d 100644
--- a/Modules/Compiler/Intel-C.cmake
+++ b/Modules/Compiler/Intel-C.cmake
@@ -28,6 +28,8 @@
 
 else()
 
+  set(CMAKE_C_COMPILE_OPTIONS_EXPLICIT_LANGUAGE -x c)
+
   if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 15.0.0)
     set(CMAKE_C11_STANDARD_COMPILE_OPTION "-std=c11")
     set(CMAKE_C11_EXTENSION_COMPILE_OPTION "-std=gnu11")
diff --git a/Modules/Compiler/Intel-CXX.cmake b/Modules/Compiler/Intel-CXX.cmake
index b71b946..42adfd1 100644
--- a/Modules/Compiler/Intel-CXX.cmake
+++ b/Modules/Compiler/Intel-CXX.cmake
@@ -42,6 +42,8 @@
 
 else()
 
+  set(CMAKE_CXX_COMPILE_OPTIONS_EXPLICIT_LANGUAGE -x c++)
+
   if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19.0.0)
     set(CMAKE_CXX20_STANDARD_COMPILE_OPTION "-std=c++20")
     set(CMAKE_CXX20_EXTENSION_COMPILE_OPTION "-std=gnu++20")
diff --git a/Modules/Compiler/OpenWatcom.cmake b/Modules/Compiler/OpenWatcom.cmake
index 9efbfc2..a962513 100644
--- a/Modules/Compiler/OpenWatcom.cmake
+++ b/Modules/Compiler/OpenWatcom.cmake
@@ -86,7 +86,7 @@
 set(CMAKE_CXX_CREATE_STATIC_LIBRARY ${CMAKE_C_CREATE_STATIC_LIBRARY})
 
 
-# old CMake internaly used OpenWatcom version macros
+# old CMake internally used OpenWatcom version macros
 # for backward compatibility
 if(NOT _CMAKE_WATCOM_VERSION)
   set(_CMAKE_WATCOM_VERSION 1)
diff --git a/Modules/Compiler/PGI-CXX.cmake b/Modules/Compiler/PGI-CXX.cmake
index c77de36..2d7a303 100644
--- a/Modules/Compiler/PGI-CXX.cmake
+++ b/Modules/Compiler/PGI-CXX.cmake
@@ -4,19 +4,19 @@
 string(APPEND CMAKE_CXX_FLAGS_RELEASE_INIT " -DNDEBUG")
 
 if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 12.10)
-  set(CMAKE_CXX98_STANDARD_COMPILE_OPTION  -A)
+  set(CMAKE_CXX98_STANDARD_COMPILE_OPTION "")
   set(CMAKE_CXX98_EXTENSION_COMPILE_OPTION --gnu_extensions)
   set(CMAKE_CXX98_STANDARD__HAS_FULL_SUPPORT ON)
   if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 13.10)
-    set(CMAKE_CXX11_STANDARD_COMPILE_OPTION  --c++11 -A)
+    set(CMAKE_CXX11_STANDARD_COMPILE_OPTION  --c++11)
     set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION --c++11 --gnu_extensions)
     set(CMAKE_CXX11_STANDARD__HAS_FULL_SUPPORT ON)
     if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 15.7)
-      set(CMAKE_CXX14_STANDARD_COMPILE_OPTION  --c++14 -A)
+      set(CMAKE_CXX14_STANDARD_COMPILE_OPTION  --c++14)
       set(CMAKE_CXX14_EXTENSION_COMPILE_OPTION --c++14 --gnu_extensions)
       set(CMAKE_CXX14_STANDARD__HAS_FULL_SUPPORT ON)
       if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 17.1)
-        set(CMAKE_CXX17_STANDARD_COMPILE_OPTION  --c++17 -A)
+        set(CMAKE_CXX17_STANDARD_COMPILE_OPTION  --c++17)
         set(CMAKE_CXX17_EXTENSION_COMPILE_OPTION --c++17 --gnu_extensions)
         set(CMAKE_CXX17_STANDARD__HAS_FULL_SUPPORT ON)
       endif()
diff --git a/Modules/Compiler/TI-ASM.cmake b/Modules/Compiler/TI-ASM.cmake
index a566d70..01965d2 100644
--- a/Modules/Compiler/TI-ASM.cmake
+++ b/Modules/Compiler/TI-ASM.cmake
@@ -1,8 +1,4 @@
-set(CMAKE_LIBRARY_PATH_FLAG "--search_path=")
-set(CMAKE_LINK_LIBRARY_FLAG "--library=")
-set(CMAKE_INCLUDE_FLAG_ASM "--include_path=")
-
-set(CMAKE_ASM_COMPILE_OBJECT  "<CMAKE_ASM_COMPILER> --compile_only --asm_file=<SOURCE> <DEFINES> <INCLUDES> <FLAGS> --output_file=<OBJECT>")
-set(CMAKE_ASM_LINK_EXECUTABLE "<CMAKE_ASM_COMPILER> <OBJECTS> --run_linker --output_file=<TARGET> <CMAKE_ASM_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES>")
+include(Compiler/TI)
+__compiler_ti(ASM)
 
 set(CMAKE_ASM_SOURCE_FILE_EXTENSIONS asm;s;abs)
diff --git a/Modules/Compiler/TI-C.cmake b/Modules/Compiler/TI-C.cmake
index b060ee9..8ea01b5 100644
--- a/Modules/Compiler/TI-C.cmake
+++ b/Modules/Compiler/TI-C.cmake
@@ -1,22 +1,8 @@
-set(CMAKE_LIBRARY_PATH_FLAG "--search_path=")
-set(CMAKE_LINK_LIBRARY_FLAG "--library=")
-set(CMAKE_INCLUDE_FLAG_C "--include_path=")
+include(Compiler/TI)
+__compiler_ti(C)
 
 set(CMAKE_C90_STANDARD_COMPILE_OPTION "--c89")
 set(CMAKE_C90_EXTENSION_COMPILE_OPTION "--c89 --relaxed_ansi")
 
 set(CMAKE_C99_STANDARD_COMPILE_OPTION "--c99")
 set(CMAKE_C99_EXTENSION_COMPILE_OPTION "--c99 --relaxed_ansi")
-
-set(CMAKE_DEPFILE_FLAGS_C "--preproc_with_compile --preproc_dependency=<DEPFILE>")
-
-set(CMAKE_C_CREATE_ASSEMBLY_SOURCE "<CMAKE_C_COMPILER> --compile_only --skip_assembler --c_file=<SOURCE> <DEFINES> <INCLUDES> <FLAGS> --output_file=<ASSEMBLY_SOURCE>")
-set(CMAKE_C_CREATE_PREPROCESSED_SOURCE "<CMAKE_C_COMPILER> --preproc_only --c_file=<SOURCE> <DEFINES> <INCLUDES> <FLAGS> --output_file=<PREPROCESSED_SOURCE>")
-
-set(CMAKE_C_COMPILE_OBJECT  "<CMAKE_C_COMPILER> --compile_only --c_file=<SOURCE> <DEFINES> <INCLUDES> <FLAGS> --output_file=<OBJECT>")
-set(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> qr <TARGET> <OBJECTS>")
-set(CMAKE_C_ARCHIVE_APPEND "<CMAKE_AR> qa <TARGET> <OBJECTS>")
-set(CMAKE_C_LINK_EXECUTABLE "<CMAKE_C_COMPILER> --run_linker --output_file=<TARGET> --map_file=<TARGET_NAME>.map <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> <LINK_LIBRARIES>")
-set(CMAKE_ASM_RESPONSE_FILE_FLAG "--cmd_file=")
-set(CMAKE_C_RESPONSE_FILE_FLAG "--cmd_file=")
-set(CMAKE_C_RESPONSE_FILE_LINK_FLAG " ")
diff --git a/Modules/Compiler/TI-CXX.cmake b/Modules/Compiler/TI-CXX.cmake
index 7836543..c08d9a1 100644
--- a/Modules/Compiler/TI-CXX.cmake
+++ b/Modules/Compiler/TI-CXX.cmake
@@ -1,15 +1,2 @@
-set(CMAKE_LIBRARY_PATH_FLAG "--search_path=")
-set(CMAKE_LINK_LIBRARY_FLAG "--library=")
-set(CMAKE_INCLUDE_FLAG_CXX "--include_path=")
-
-set(CMAKE_DEPFILE_FLAGS_CXX "--preproc_with_compile --preproc_dependency=<DEPFILE>")
-
-set(CMAKE_CXX_CREATE_ASSEMBLY_SOURCE "<CMAKE_CXX_COMPILER> --compile_only --skip_assembler --cpp_file=<SOURCE> <DEFINES> <INCLUDES> <FLAGS> --output_file=<ASSEMBLY_SOURCE>")
-set(CMAKE_CXX_CREATE_PREPROCESSED_SOURCE "<CMAKE_CXX_COMPILER> --preproc_only --cpp_file=<SOURCE> <DEFINES> <INCLUDES> <FLAGS> --output_file=<PREPROCESSED_SOURCE>")
-
-set(CMAKE_CXX_COMPILE_OBJECT  "<CMAKE_CXX_COMPILER> --compile_only --cpp_file=<SOURCE> <DEFINES> <INCLUDES> <FLAGS> --output_file=<OBJECT>")
-set(CMAKE_CXX_ARCHIVE_CREATE "<CMAKE_AR> qr <TARGET> <OBJECTS>")
-set(CMAKE_CXX_ARCHIVE_APPEND "<CMAKE_AR> qa <TARGET> <OBJECTS>")
-set(CMAKE_CXX_LINK_EXECUTABLE "<CMAKE_CXX_COMPILER> --run_linker --output_file=<TARGET> --map_file=<TARGET_NAME>.map <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> <LINK_LIBRARIES>")
-set(CMAKE_CXX_RESPONSE_FILE_FLAG "--cmd_file=")
-set(CMAKE_CXX_RESPONSE_FILE_LINK_FLAG " ")
+include(Compiler/TI)
+__compiler_ti(CXX)
diff --git a/Modules/Compiler/TI.cmake b/Modules/Compiler/TI.cmake
new file mode 100644
index 0000000..9f2e813
--- /dev/null
+++ b/Modules/Compiler/TI.cmake
@@ -0,0 +1,40 @@
+# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+
+# This module is shared by multiple languages; use include blocker.
+if(__COMPILER_TI)
+  return()
+endif()
+set(__COMPILER_TI 1)
+
+macro(__compiler_ti lang)
+  string(TOLOWER ${lang} prefix)
+  if("x${lang}" STREQUAL "xCXX")
+    set(prefix "cpp")
+  endif()
+
+  set(CMAKE_${lang}_RESPONSE_FILE_FLAG "--cmd_file=")
+
+  set(CMAKE_INCLUDE_FLAG_${lang} "--include_path=")
+  set(CMAKE_DEPFILE_FLAGS_${lang} "--preproc_with_compile --preproc_dependency=<DEPFILE>")
+
+  set(CMAKE_${lang}_CREATE_PREPROCESSED_SOURCE "<CMAKE_${lang}_COMPILER> --preproc_only --${prefix}_file=<SOURCE> <DEFINES> <INCLUDES> <FLAGS> --output_file=<PREPROCESSED_SOURCE>")
+  set(CMAKE_${lang}_CREATE_ASSEMBLY_SOURCE     "<CMAKE_${lang}_COMPILER> --compile_only --skip_assembler --${prefix}_file=<SOURCE> <DEFINES> <INCLUDES> <FLAGS> --output_file=<ASSEMBLY_SOURCE>")
+
+  set(CMAKE_${lang}_COMPILE_OBJECT  "<CMAKE_${lang}_COMPILER> --compile_only --${prefix}_file=<SOURCE> <DEFINES> <INCLUDES> <FLAGS> --output_file=<OBJECT>")
+
+  set(CMAKE_${lang}_ARCHIVE_CREATE "<CMAKE_AR> qr <TARGET> <OBJECTS>")
+  set(CMAKE_${lang}_ARCHIVE_APPEND "<CMAKE_AR> qa <TARGET> <OBJECTS>")
+  set(CMAKE_${lang}_ARCHIVE_FINISH "")
+
+  # After the --run_linker flag a response file is not possible
+  set(CMAKE_${lang}_RESPONSE_FILE_LINK_FLAG "")
+  set(CMAKE_${lang}_USE_RESPONSE_FILE_FOR_LIBRARIES 0)
+  set(CMAKE_${lang}_USE_RESPONSE_FILE_FOR_OBJECTS 0)
+
+  set(CMAKE_${lang}_LINK_EXECUTABLE "<CMAKE_${lang}_COMPILER> <FLAGS> --run_linker --output_file=<TARGET> --map_file=<TARGET_NAME>.map <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> <LINK_LIBRARIES>")
+endmacro()
+
+set(CMAKE_LIBRARY_PATH_FLAG "--search_path=")
+set(CMAKE_LINK_LIBRARY_FLAG "--library=")
diff --git a/Modules/Compiler/XL-C.cmake b/Modules/Compiler/XL-C.cmake
index 2077bda..78c44d5 100644
--- a/Modules/Compiler/XL-C.cmake
+++ b/Modules/Compiler/XL-C.cmake
@@ -6,6 +6,8 @@
 # -qthreaded = Ensures that all optimizations will be thread-safe
 string(APPEND CMAKE_C_FLAGS_INIT " -qthreaded")
 
+set(CMAKE_C_COMPILE_OPTIONS_EXPLICIT_LANGUAGE -qsourcetype=c)
+
 if (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 10.1)
   set(CMAKE_C90_STANDARD_COMPILE_OPTION "-qlanglvl=stdc89")
   set(CMAKE_C90_EXTENSION_COMPILE_OPTION "-qlanglvl=extc89")
diff --git a/Modules/Compiler/XL-CXX.cmake b/Modules/Compiler/XL-CXX.cmake
index 41e3e11..3b911f3 100644
--- a/Modules/Compiler/XL-CXX.cmake
+++ b/Modules/Compiler/XL-CXX.cmake
@@ -6,6 +6,8 @@
 # -qthreaded = Ensures that all optimizations will be thread-safe
 string(APPEND CMAKE_CXX_FLAGS_INIT " -qthreaded")
 
+set(CMAKE_CXX_COMPILE_OPTIONS_EXPLICIT_LANGUAGE -+)
+
 if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 10.1)
   if(CMAKE_SYSTEM MATCHES "Linux")
     set(CMAKE_CXX98_STANDARD_COMPILE_OPTION "")
@@ -32,6 +34,3 @@
 endif ()
 
 __compiler_check_default_language_standard(CXX 10.1 98)
-
-set(CMAKE_CXX_COMPILE_OBJECT
-  "<CMAKE_CXX_COMPILER> -+ <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE>")
diff --git a/Modules/Compiler/XLClang-C.cmake b/Modules/Compiler/XLClang-C.cmake
index 54c18a6..1668a4d 100644
--- a/Modules/Compiler/XLClang-C.cmake
+++ b/Modules/Compiler/XLClang-C.cmake
@@ -1,6 +1,8 @@
 include(Compiler/XLClang)
 __compiler_xlclang(C)
 
+set(CMAKE_C_COMPILE_OPTIONS_EXPLICIT_LANGUAGE -x c)
+
 if (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 13.1.1)
   set(CMAKE_C90_STANDARD_COMPILE_OPTION  "-std=c89")
   set(CMAKE_C90_EXTENSION_COMPILE_OPTION "-std=gnu89")
diff --git a/Modules/Compiler/XLClang-CXX.cmake b/Modules/Compiler/XLClang-CXX.cmake
index 9ea3d7c..02638c7 100644
--- a/Modules/Compiler/XLClang-CXX.cmake
+++ b/Modules/Compiler/XLClang-CXX.cmake
@@ -1,6 +1,8 @@
 include(Compiler/XLClang)
 __compiler_xlclang(CXX)
 
+set(CMAKE_CXX_COMPILE_OPTIONS_EXPLICIT_LANGUAGE -x c++)
+
 if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 13.1.1)
   set(CMAKE_CXX98_STANDARD_COMPILE_OPTION  "")
   set(CMAKE_CXX98_EXTENSION_COMPILE_OPTION "")
diff --git a/Modules/CompilerId/VS-10.vcxproj.in b/Modules/CompilerId/VS-10.vcxproj.in
index b48a332..3598fc7 100644
--- a/Modules/CompilerId/VS-10.vcxproj.in
+++ b/Modules/CompilerId/VS-10.vcxproj.in
@@ -9,7 +9,7 @@
   <PropertyGroup Label="Globals">
     <ProjectGuid>{CAE07175-D007-4FC3-BFE8-47B392814159}</ProjectGuid>
     <RootNamespace>CompilerId@id_lang@</RootNamespace>
-    <Keyword>Win32Proj</Keyword>
+    <Keyword>@id_keyword@</Keyword>
     @id_system@
     @id_system_version@
     @id_WindowsTargetPlatformVersion@
@@ -24,7 +24,7 @@
     @id_PreferredToolArchitecture@
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|@id_platform@'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
+    <ConfigurationType>@id_config_type@</ConfigurationType>
     @id_toolset@
     <CharacterSet>MultiByte</CharacterSet>
   </PropertyGroup>
diff --git a/Modules/FetchContent.cmake b/Modules/FetchContent.cmake
index e05ca96..c85e2d8 100644
--- a/Modules/FetchContent.cmake
+++ b/Modules/FetchContent.cmake
@@ -5,6 +5,8 @@
 FetchContent
 ------------------
 
+.. versionadded:: 3.11
+
 .. only:: html
 
   .. contents::
diff --git a/Modules/FindArmadillo.cmake b/Modules/FindArmadillo.cmake
index 243b9e0..c8a31a0 100644
--- a/Modules/FindArmadillo.cmake
+++ b/Modules/FindArmadillo.cmake
@@ -84,6 +84,7 @@
   # Link to the armadillo wrapper library.
   find_library(ARMADILLO_LIBRARY
     NAMES armadillo
+    NAMES_PER_DIR
     PATHS
       "$ENV{ProgramFiles}/Armadillo/lib"
       "$ENV{ProgramFiles}/Armadillo/lib64"
diff --git a/Modules/FindBLAS.cmake b/Modules/FindBLAS.cmake
index 60f178b..88a252d 100644
--- a/Modules/FindBLAS.cmake
+++ b/Modules/FindBLAS.cmake
@@ -36,7 +36,7 @@
   * ``SCSL``
   * ``SGIMATH``
   * ``IBMESSL``
-  * ``Intel10_32`` (intel mkl v10 32 bit)
+  * ``Intel10_32`` (intel mkl v10 32 bit, threaded code)
   * ``Intel10_64lp`` (intel mkl v10+ 64 bit, threaded code, lp64 model)
   * ``Intel10_64lp_seq`` (intel mkl v10+ 64 bit, sequential code, lp64 model)
   * ``Intel10_64ilp`` (intel mkl v10+ 64 bit, threaded code, ilp64 model)
@@ -208,6 +208,7 @@
       if(_libraries_work)
         find_library(${_prefix}_${_library}_LIBRARY
           NAMES ${_library}
+          NAMES_PER_DIR
           PATHS ${_extaddlibdir}
           PATH_SUFFIXES ${_subdirs}
         )
@@ -397,6 +398,10 @@
 
           # Add threading/sequential libs
           set(BLAS_SEARCH_LIBS_WIN_THREAD "")
+          if(BLA_VENDOR STREQUAL "Intel10_32" OR BLA_VENDOR STREQUAL "All")
+            list(APPEND BLAS_SEARCH_LIBS_WIN_THREAD
+              "libiomp5md mkl_intel_thread${BLAS_mkl_DLL_SUFFIX}")
+          endif()
           if(BLA_VENDOR MATCHES "^Intel10_64i?lp$" OR BLA_VENDOR STREQUAL "All")
             # old version
             list(APPEND BLAS_SEARCH_LIBS_WIN_THREAD
@@ -441,7 +446,7 @@
               "${BLAS_mkl_START_GROUP} mkl_${BLAS_mkl_INTFACE}_${BLAS_mkl_ILP_MODE} mkl_sequential mkl_core ${BLAS_mkl_END_GROUP}")
           endif()
 
-          #older vesions of intel mkl libs
+          #older versions of intel mkl libs
           if(BLA_VENDOR STREQUAL "Intel" OR BLA_VENDOR STREQUAL "All")
             list(APPEND BLAS_SEARCH_LIBS
               "mkl")
@@ -483,7 +488,9 @@
       endif()
       set(BLAS_mkl_LIB_PATH_SUFFIXES
           "compiler/lib" "compiler/lib/${BLAS_mkl_ARCH_NAME}_${BLAS_mkl_OS_NAME}"
+          "compiler/lib/${BLAS_mkl_ARCH_NAME}"
           "mkl/lib" "mkl/lib/${BLAS_mkl_ARCH_NAME}_${BLAS_mkl_OS_NAME}"
+          "mkl/lib/${BLAS_mkl_ARCH_NAME}"
           "lib/${BLAS_mkl_ARCH_NAME}_${BLAS_mkl_OS_NAME}")
 
       foreach(IT ${BLAS_SEARCH_LIBS})
diff --git a/Modules/FindBZip2.cmake b/Modules/FindBZip2.cmake
index 98ab72c..5704d1d 100644
--- a/Modules/FindBZip2.cmake
+++ b/Modules/FindBZip2.cmake
@@ -45,8 +45,8 @@
 find_path(BZIP2_INCLUDE_DIR bzlib.h ${_BZIP2_PATHS} PATH_SUFFIXES include)
 
 if (NOT BZIP2_LIBRARIES)
-    find_library(BZIP2_LIBRARY_RELEASE NAMES bz2 bzip2 libbz2 libbzip2 ${_BZIP2_PATHS} PATH_SUFFIXES lib)
-    find_library(BZIP2_LIBRARY_DEBUG NAMES bz2d bzip2d libbz2d libbzip2d ${_BZIP2_PATHS} PATH_SUFFIXES lib)
+    find_library(BZIP2_LIBRARY_RELEASE NAMES bz2 bzip2 libbz2 libbzip2 NAMES_PER_DIR ${_BZIP2_PATHS} PATH_SUFFIXES lib)
+    find_library(BZIP2_LIBRARY_DEBUG NAMES bz2d bzip2d libbz2d libbzip2d NAMES_PER_DIR ${_BZIP2_PATHS} PATH_SUFFIXES lib)
 
     include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake)
     SELECT_LIBRARY_CONFIGURATIONS(BZIP2)
diff --git a/Modules/FindBoost.cmake b/Modules/FindBoost.cmake
index 13981d3..ec087ad 100644
--- a/Modules/FindBoost.cmake
+++ b/Modules/FindBoost.cmake
@@ -305,7 +305,7 @@
 endfunction()
 
 macro(_boost_set_in_parent_scope name value)
-  # Set a variable in parent scope and make it visibile in current scope
+  # Set a variable in parent scope and make it visible in current scope
   set(${name} "${value}" PARENT_SCOPE)
   set(${name} "${value}")
 endmacro()
@@ -1270,10 +1270,8 @@
   set(_Boost_UNIT_TEST_FRAMEWORK_HEADERS "boost/test/framework.hpp")
   set(_Boost_WAVE_HEADERS                "boost/wave.hpp")
   set(_Boost_WSERIALIZATION_HEADERS      "boost/archive/text_wiarchive.hpp")
-  if(WIN32)
-    set(_Boost_BZIP2_HEADERS             "boost/iostreams/filter/bzip2.hpp")
-    set(_Boost_ZLIB_HEADERS              "boost/iostreams/filter/zlib.hpp")
-  endif()
+  set(_Boost_BZIP2_HEADERS               "boost/iostreams/filter/bzip2.hpp")
+  set(_Boost_ZLIB_HEADERS                "boost/iostreams/filter/zlib.hpp")
 
   string(TOUPPER ${component} uppercomponent)
   set(${_hdrs} ${_Boost_${uppercomponent}_HEADERS} PARENT_SCOPE)
diff --git a/Modules/FindCUDA/run_nvcc.cmake b/Modules/FindCUDA/run_nvcc.cmake
index ba35433..17e12f8 100644
--- a/Modules/FindCUDA/run_nvcc.cmake
+++ b/Modules/FindCUDA/run_nvcc.cmake
@@ -155,7 +155,7 @@
     # copy and paste a runnable command line.
     set(cuda_execute_process_string)
     foreach(arg ${ARGN})
-      # If there are quotes, excape them, so they come through.
+      # If there are quotes, escape them, so they come through.
       string(REPLACE "\"" "\\\"" arg ${arg})
       # Args with spaces need quotes around them to get them to be parsed as a single argument.
       if(arg MATCHES " ")
diff --git a/Modules/FindCUDAToolkit.cmake b/Modules/FindCUDAToolkit.cmake
index 47bc546..1054f60 100644
--- a/Modules/FindCUDAToolkit.cmake
+++ b/Modules/FindCUDAToolkit.cmake
@@ -5,6 +5,8 @@
 FindCUDAToolkit
 ---------------
 
+.. versionadded:: 3.17
+
 This script locates the NVIDIA CUDA toolkit and the associated libraries, but
 does not require the ``CUDA`` language be enabled for a given project. This
 module does not search for the NVIDIA CUDA Samples.
@@ -12,8 +14,7 @@
 Search Behavior
 ^^^^^^^^^^^^^^^
 
-Finding the CUDA Toolkit requires finding the ``nvcc`` executable, which is
-searched for in the following order:
+The CUDA Toolkit search behavior uses the following order:
 
 1. If the ``CUDA`` language has been enabled we will use the directory
    containing the compiler as the first search location for ``nvcc``.
@@ -24,13 +25,12 @@
    configuration variable are specified, the *configuration* variable takes
    precedence.
 
-   The directory specified here must be such that the executable ``nvcc`` can be
-   found underneath the directory specified by ``CUDAToolkit_ROOT``.  If
-   ``CUDAToolkit_ROOT`` is specified, but no ``nvcc`` is found underneath, this
-   package is marked as **not** found.  No subsequent search attempts are
-   performed.
+   The directory specified here must be such that the executable ``nvcc`` or
+   the appropriate ``version.txt`` file can be found underneath the specified
+   directory.
 
-3. If the CUDA_PATH environment variable is defined, it will be searched.
+3. If the CUDA_PATH environment variable is defined, it will be searched
+   for ``nvcc``.
 
 4. The user's path is searched for ``nvcc`` using :command:`find_program`.  If
    this is found, no subsequent search attempts are performed.  Users are
@@ -402,7 +402,7 @@
 
 ``CUDAToolkit_VERSION``
     The exact version of the CUDA Toolkit found (as reported by
-    ``nvcc --version``).
+    ``nvcc --version`` or ``version.txt``).
 
 ``CUDAToolkit_VERSION_MAJOR``
     The major version of the CUDA Toolkit.
@@ -431,8 +431,8 @@
 
 ``CUDAToolkit_TARGET_DIR``
     The path to the CUDA Toolkit directory including the target architecture
-    when cross-compiling. When not cross-compiling this will be equivalant to
-    ``CUDAToolkit_ROOT_DIR``.
+    when cross-compiling. When not cross-compiling this will be equivalent to
+    the parent directory of ``CUDAToolkit_BIN_DIR``.
 
 ``CUDAToolkit_NVCC_EXECUTABLE``
     The path to the NVIDIA CUDA compiler ``nvcc``.  Note that this path may
@@ -491,31 +491,81 @@
   set(CUDAToolkit_BIN_DIR "${CUDAToolkit_ROOT_DIR}/bin")
   set(CUDAToolkit_NVCC_EXECUTABLE "${CUDAToolkit_BIN_DIR}/nvcc${CMAKE_EXECUTABLE_SUFFIX}")
 else()
+
+  function(_CUDAToolkit_find_root_dir )
+    cmake_parse_arguments(arg "" "" "SEARCH_PATHS;FIND_FLAGS" ${ARGN})
+
+
+    if(NOT CUDAToolkit_BIN_DIR)
+      if(NOT CUDAToolkit_SENTINEL_FILE)
+        find_program(CUDAToolkit_NVCC_EXECUTABLE
+          NAMES nvcc nvcc.exe
+          PATHS ${arg_SEARCH_PATHS}
+          ${arg_FIND_FLAGS}
+        )
+      endif()
+
+      if(NOT CUDAToolkit_NVCC_EXECUTABLE)
+        find_file(CUDAToolkit_SENTINEL_FILE
+          NAMES version.txt
+          PATHS ${arg_SEARCH_PATHS}
+          NO_DEFAULT_PATH
+        )
+      endif()
+
+      if(CUDAToolkit_NVCC_EXECUTABLE)
+        get_filename_component(CUDAToolkit_BIN_DIR "${CUDAToolkit_NVCC_EXECUTABLE}" DIRECTORY)
+
+        set(CUDAToolkit_BIN_DIR "${CUDAToolkit_BIN_DIR}" CACHE PATH "" FORCE)
+        mark_as_advanced(CUDAToolkit_BIN_DIR)
+      elseif(CUDAToolkit_SENTINEL_FILE)
+        get_filename_component(CUDAToolkit_BIN_DIR ${CUDAToolkit_SENTINEL_FILE} DIRECTORY ABSOLUTE)
+        set(CUDAToolkit_BIN_DIR "${CUDAToolkit_BIN_DIR}/bin")
+
+        set(CUDAToolkit_BIN_DIR "${CUDAToolkit_BIN_DIR}" CACHE PATH "" FORCE)
+        mark_as_advanced(CUDAToolkit_BIN_DIR)
+      endif()
+    endif()
+
+    if(CUDAToolkit_BIN_DIR)
+      get_filename_component(CUDAToolkit_ROOT_DIR ${CUDAToolkit_BIN_DIR} DIRECTORY ABSOLUTE)
+      set(CUDAToolkit_ROOT_DIR "${CUDAToolkit_ROOT_DIR}" PARENT_SCOPE)
+    endif()
+
+  endfunction()
+
+  function(_CUDAToolkit_find_version_file result_variable)
+    # We first check for a non-scattered installation to prefer it over a scattered installation.
+    if(CUDAToolkit_ROOT AND EXISTS "${CUDAToolkit_ROOT}/version.txt")
+      set(${result_variable} "${CUDAToolkit_ROOT}/version.txt" PARENT_SCOPE)
+    elseif(CUDAToolkit_ROOT_DIR AND EXISTS "${CUDAToolkit_ROOT_DIR}/version.txt")
+      set(${result_variable} "${CUDAToolkit_ROOT_DIR}/version.txt" PARENT_SCOPE)
+    elseif(CMAKE_SYSROOT_LINK AND EXISTS "${CMAKE_SYSROOT_LINK}/usr/lib/cuda/version.txt")
+      set(${result_variable} "${CMAKE_SYSROOT_LINK}/usr/lib/cuda/version.txt" PARENT_SCOPE)
+    elseif(EXISTS "${CMAKE_SYSROOT}/usr/lib/cuda/version.txt")
+      set(${result_variable} "${CMAKE_SYSROOT}/usr/lib/cuda/version.txt" PARENT_SCOPE)
+    endif()
+  endfunction()
+
   # For NVCC we can easily deduce the SDK binary directory from the compiler path.
   if(CMAKE_CUDA_COMPILER_LOADED AND NOT CUDAToolkit_BIN_DIR AND CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA")
     get_filename_component(CUDAToolkit_BIN_DIR "${CMAKE_CUDA_COMPILER}" DIRECTORY)
     set(CUDAToolkit_BIN_DIR "${CUDAToolkit_BIN_DIR}" CACHE PATH "")
+    # Try language provided path first.
+    _CUDAToolkit_find_root_dir(SEARCH_PATHS "${CUDAToolkit_BIN_DIR}" FIND_FLAGS NO_DEFAULT_PATH)
     mark_as_advanced(CUDAToolkit_BIN_DIR)
   endif()
 
-  # Try language- or user-provided path first.
-  if(CUDAToolkit_BIN_DIR)
-    find_program(CUDAToolkit_NVCC_EXECUTABLE
-      NAMES nvcc nvcc.exe
-      PATHS ${CUDAToolkit_BIN_DIR}
-      NO_DEFAULT_PATH
-    )
+  # Try user provided path
+  if(NOT CUDAToolkit_ROOT_DIR AND CUDAToolkit_ROOT)
+    _CUDAToolkit_find_root_dir(SEARCH_PATHS "${CUDAToolkit_ROOT}" FIND_FLAGS PATH_SUFFIXES bin NO_DEFAULT_PATH)
+  endif()
+  if(NOT CUDAToolkit_ROOT_DIR)
+    _CUDAToolkit_find_root_dir(FIND_FLAGS PATHS "ENV CUDA_PATH" PATH_SUFFIXES bin)
   endif()
 
-  # Search using CUDAToolkit_ROOT
-  find_program(CUDAToolkit_NVCC_EXECUTABLE
-    NAMES nvcc nvcc.exe
-    PATHS ENV CUDA_PATH
-    PATH_SUFFIXES bin
-  )
-
-  # If the user specified CUDAToolkit_ROOT but nvcc could not be found, this is an error.
-  if(NOT CUDAToolkit_NVCC_EXECUTABLE AND (DEFINED CUDAToolkit_ROOT OR DEFINED ENV{CUDAToolkit_ROOT}))
+  # If the user specified CUDAToolkit_ROOT but the toolkit could not be found, this is an error.
+  if(NOT CUDAToolkit_ROOT_DIR AND (DEFINED CUDAToolkit_ROOT OR DEFINED ENV{CUDAToolkit_ROOT}))
     # Declare error messages now, print later depending on find_package args.
     set(fail_base "Could not find nvcc executable in path specified by")
     set(cuda_root_fail "${fail_base} CUDAToolkit_ROOT=${CUDAToolkit_ROOT}")
@@ -552,7 +602,7 @@
   # We will also search the default symlink location /usr/local/cuda first since
   # if CUDAToolkit_ROOT is not specified, it is assumed that the symlinked
   # directory is the desired location.
-  if(NOT CUDAToolkit_NVCC_EXECUTABLE)
+  if(NOT CUDAToolkit_ROOT_DIR)
     if(UNIX)
       if(NOT APPLE)
         set(platform_base "/usr/local/cuda-")
@@ -589,12 +639,8 @@
       list(INSERT search_paths 0 "/usr/local/cuda")
     endif()
 
-    # Now search for nvcc again using the platform default search paths.
-    find_program(CUDAToolkit_NVCC_EXECUTABLE
-      NAMES nvcc nvcc.exe
-      PATHS ${search_paths}
-      PATH_SUFFIXES bin
-    )
+    # Now search for the toolkit again using the platform default search paths.
+    _CUDAToolkit_find_root_dir(SEARCH_PATHS "${search_paths}" FIND_FLAGS PATH_SUFFIXES bin)
 
     # We are done with these variables now, cleanup for caller.
     unset(platform_base)
@@ -602,7 +648,7 @@
     unset(versions)
     unset(search_paths)
 
-    if(NOT CUDAToolkit_NVCC_EXECUTABLE)
+    if(NOT CUDAToolkit_ROOT_DIR)
       if(CUDAToolkit_FIND_REQUIRED)
         message(FATAL_ERROR "Could not find nvcc, please set CUDAToolkit_ROOT.")
       elseif(NOT CUDAToolkit_FIND_QUIETLY)
@@ -614,24 +660,12 @@
     endif()
   endif()
 
-  if(NOT CUDAToolkit_BIN_DIR AND CUDAToolkit_NVCC_EXECUTABLE)
-    get_filename_component(CUDAToolkit_BIN_DIR "${CUDAToolkit_NVCC_EXECUTABLE}" DIRECTORY)
-    set(CUDAToolkit_BIN_DIR "${CUDAToolkit_BIN_DIR}" CACHE PATH "" FORCE)
-    mark_as_advanced(CUDAToolkit_BIN_DIR)
+  _CUDAToolkit_find_version_file( _CUDAToolkit_version_file )
+  if(_CUDAToolkit_version_file)
+    # CUDAToolkit_LIBRARY_ROOT contains the device library and version file.
+    get_filename_component(CUDAToolkit_LIBRARY_ROOT "${_CUDAToolkit_version_file}" DIRECTORY ABSOLUTE)
   endif()
-
-  get_filename_component(CUDAToolkit_ROOT_DIR ${CUDAToolkit_BIN_DIR} DIRECTORY ABSOLUTE)
-
-  # CUDAToolkit_LIBRARY_ROOT contains the device library and version file.
-  # In a non-scattered installation this is equivalent to CUDAToolkit_ROOT_DIR.
-  # We first check for a non-scattered installation to prefer it over a scattered installation.
-  if(EXISTS "${CUDAToolkit_ROOT_DIR}/version.txt")
-    set(CUDAToolkit_LIBRARY_ROOT "${CUDAToolkit_ROOT_DIR}")
-  elseif(CMAKE_SYSROOT_LINK AND EXISTS "${CMAKE_SYSROOT_LINK}/usr/lib/cuda/version.txt")
-    set(CUDAToolkit_LIBRARY_ROOT "${CMAKE_SYSROOT_LINK}/usr/lib/cuda")
-  elseif(EXISTS "${CMAKE_SYSROOT}/usr/lib/cuda/version.txt")
-    set(CUDAToolkit_LIBRARY_ROOT "${CMAKE_SYSROOT}/usr/lib/cuda")
-  endif()
+  unset(_CUDAToolkit_version_file)
 endif()
 
 # Handle cross compilation
@@ -693,7 +727,7 @@
     set(CUDAToolkit_VERSION_PATCH "${CMAKE_MATCH_3}")
     set(CUDAToolkit_VERSION "${CMAKE_CUDA_COMPILER_VERSION}")
   endif()
-else()
+elseif(CUDAToolkit_NVCC_EXECUTABLE)
   # Compute the version by invoking nvcc
   execute_process(COMMAND ${CUDAToolkit_NVCC_EXECUTABLE} "--version" OUTPUT_VARIABLE NVCC_OUT)
   if(NVCC_OUT MATCHES [=[ V([0-9]+)\.([0-9]+)\.([0-9]+)]=])
@@ -703,6 +737,17 @@
     set(CUDAToolkit_VERSION  "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3}")
   endif()
   unset(NVCC_OUT)
+else()
+  _CUDAToolkit_find_version_file(version_file)
+  if(version_file)
+    file(READ "${version_file}" VERSION_INFO)
+    if(VERSION_INFO MATCHES [=[CUDA Version ([0-9]+)\.([0-9]+)\.([0-9]+)]=])
+      set(CUDAToolkit_VERSION_MAJOR "${CMAKE_MATCH_1}")
+      set(CUDAToolkit_VERSION_MINOR "${CMAKE_MATCH_2}")
+      set(CUDAToolkit_VERSION_PATCH "${CMAKE_MATCH_3}")
+      set(CUDAToolkit_VERSION  "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3}")
+    endif()
+  endif()
 endif()
 
 # Find the CUDA Runtime Library libcudart
@@ -719,7 +764,6 @@
   message(STATUS "Unable to find cudart library.")
 endif()
 
-unset(CUDAToolkit_ROOT_DIR)
 if(_CUDAToolkit_Pop_Prefix)
   list(REMOVE_AT CMAKE_PREFIX_PATH -1)
   unset(_CUDAToolkit_Pop_Prefix)
@@ -732,13 +776,16 @@
   REQUIRED_VARS
     CUDAToolkit_INCLUDE_DIR
     CUDA_CUDART
-    CUDAToolkit_NVCC_EXECUTABLE
+    CUDAToolkit_BIN_DIR
   VERSION_VAR
     CUDAToolkit_VERSION
 )
+
+unset(CUDAToolkit_ROOT_DIR)
 mark_as_advanced(CUDA_CUDART
                  CUDAToolkit_INCLUDE_DIR
                  CUDAToolkit_NVCC_EXECUTABLE
+                 CUDAToolkit_SENTINEL_FILE
                  )
 
 #-----------------------------------------------------------------------------
diff --git a/Modules/FindCURL.cmake b/Modules/FindCURL.cmake
index be7e16e..74b36c6 100644
--- a/Modules/FindCURL.cmake
+++ b/Modules/FindCURL.cmake
@@ -92,6 +92,7 @@
       curllib_static
     # Windows older "Win32 - MSVC" prebuilts (libcurl.lib, e.g. libcurl-7.15.5-win32-msvc.zip):
       libcurl
+      NAMES_PER_DIR
       HINTS ${PC_CURL_LIBRARY_DIRS}
   )
   mark_as_advanced(CURL_LIBRARY_RELEASE)
@@ -100,6 +101,7 @@
     # Windows MSVC CMake builds in debug configuration on vcpkg:
       libcurl-d_imp
       libcurl-d
+      NAMES_PER_DIR
       HINTS ${PC_CURL_LIBRARY_DIRS}
   )
   mark_as_advanced(CURL_LIBRARY_DEBUG)
diff --git a/Modules/FindCurses.cmake b/Modules/FindCurses.cmake
index ba56078..cde3a4d 100644
--- a/Modules/FindCurses.cmake
+++ b/Modules/FindCurses.cmake
@@ -156,7 +156,9 @@
 
   CHECK_LIBRARY_EXISTS("${CURSES_NCURSES_LIBRARY}"
     cbreak "" CURSES_NCURSES_HAS_CBREAK)
-  if(NOT CURSES_NCURSES_HAS_CBREAK)
+  CHECK_LIBRARY_EXISTS("${CURSES_NCURSES_LIBRARY}"
+    nodelay "" CURSES_NCURSES_HAS_NODELAY)
+  if(NOT CURSES_NCURSES_HAS_CBREAK OR NOT CURSES_NCURSES_HAS_NODELAY)
     find_library(CURSES_EXTRA_LIBRARY "${CURSES_TINFO_LIBRARY_NAME}" HINTS "${_cursesLibDir}")
     find_library(CURSES_EXTRA_LIBRARY "${CURSES_TINFO_LIBRARY_NAME}" )
 
diff --git a/Modules/FindEXPAT.cmake b/Modules/FindEXPAT.cmake
index 15b419a..b0bb02a 100644
--- a/Modules/FindEXPAT.cmake
+++ b/Modules/FindEXPAT.cmake
@@ -38,7 +38,7 @@
 find_path(EXPAT_INCLUDE_DIR NAMES expat.h HINTS ${PC_EXPAT_INCLUDE_DIRS})
 
 # Look for the library.
-find_library(EXPAT_LIBRARY NAMES expat libexpat HINTS ${PC_EXPAT_LIBRARY_DIRS})
+find_library(EXPAT_LIBRARY NAMES expat libexpat NAMES_PER_DIR HINTS ${PC_EXPAT_LIBRARY_DIRS})
 
 if (EXPAT_INCLUDE_DIR AND EXISTS "${EXPAT_INCLUDE_DIR}/expat.h")
     file(STRINGS "${EXPAT_INCLUDE_DIR}/expat.h" expat_version_str
diff --git a/Modules/FindEnvModules.cmake b/Modules/FindEnvModules.cmake
index 4dd5116..a4ac0b4 100644
--- a/Modules/FindEnvModules.cmake
+++ b/Modules/FindEnvModules.cmake
@@ -5,6 +5,8 @@
 FindEnvModules
 --------------
 
+.. versionadded:: 3.15
+
 Locate an environment module implementation and make commands available to
 CMake scripts to use them.  This is compatible with both Lua-based Lmod
 and TCL-based EnvironmentModules.
diff --git a/Modules/FindFontconfig.cmake b/Modules/FindFontconfig.cmake
index a6f0180..5228831 100644
--- a/Modules/FindFontconfig.cmake
+++ b/Modules/FindFontconfig.cmake
@@ -5,6 +5,8 @@
 FindFontconfig
 --------------
 
+.. versionadded:: 3.14
+
 Find Fontconfig headers and library.
 
 Imported Targets
diff --git a/Modules/FindGIF.cmake b/Modules/FindGIF.cmake
index d5a143e..cea9cd8 100644
--- a/Modules/FindGIF.cmake
+++ b/Modules/FindGIF.cmake
@@ -60,6 +60,7 @@
 
 find_library(GIF_LIBRARY
   NAMES ${POTENTIAL_GIF_LIBS}
+  NAMES_PER_DIR
   HINTS
     ENV GIF_DIR
   PATH_SUFFIXES lib
diff --git a/Modules/FindGLEW.cmake b/Modules/FindGLEW.cmake
index 27ffa13..080371a 100644
--- a/Modules/FindGLEW.cmake
+++ b/Modules/FindGLEW.cmake
@@ -139,11 +139,13 @@
 
 find_library(GLEW_SHARED_LIBRARY_RELEASE
              NAMES GLEW glew glew32
+             NAMES_PER_DIR
              PATH_SUFFIXES lib lib64 libx32 lib/Release/${_arch}
              PATHS ENV GLEW_ROOT)
 
 find_library(GLEW_SHARED_LIBRARY_DEBUG
              NAMES GLEWd glewd glew32d
+             NAMES_PER_DIR
              PATH_SUFFIXES lib lib64
              PATHS ENV GLEW_ROOT)
 
@@ -152,11 +154,13 @@
 
 find_library(GLEW_STATIC_LIBRARY_RELEASE
              NAMES GLEW glew glew32s
+             NAMES_PER_DIR
              PATH_SUFFIXES lib lib64 libx32 lib/Release/${_arch}
              PATHS ENV GLEW_ROOT)
 
 find_library(GLEW_STATIC_LIBRARY_DEBUG
              NAMES GLEWds glewds glew32ds
+             NAMES_PER_DIR
              PATH_SUFFIXES lib lib64
              PATHS ENV GLEW_ROOT)
 
diff --git a/Modules/FindGSL.cmake b/Modules/FindGSL.cmake
index da1b3c4..3d4e7f9 100644
--- a/Modules/FindGSL.cmake
+++ b/Modules/FindGSL.cmake
@@ -5,6 +5,8 @@
 FindGSL
 --------
 
+.. versionadded:: 3.2
+
 Find the native GNU Scientific Library (GSL) includes and libraries.
 
 The GNU Scientific Library (GSL) is a numerical library for C and C++
diff --git a/Modules/FindGTest.cmake b/Modules/FindGTest.cmake
index 53cab1a..10e31b2 100644
--- a/Modules/FindGTest.cmake
+++ b/Modules/FindGTest.cmake
@@ -96,6 +96,27 @@
     mark_as_advanced(${_name})
 endfunction()
 
+function(__gtest_find_library_configuration _name _lib _cfg_suffix)
+    set(_libs ${_lib})
+    if(MSVC AND GTEST_MSVC_SEARCH STREQUAL "MD")
+        # The provided /MD project files for Google Test add -md suffixes to the
+        # library names.
+        list(INSERT _libs 0 ${_lib}-md)
+    endif()
+    list(TRANSFORM _libs APPEND "${_cfg_suffix}")
+
+    __gtest_find_library(${_name} ${_libs})
+endfunction()
+
+include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake)
+function(__gtest_find_and_select_library_configurations _basename _lib)
+    __gtest_find_library_configuration(${_basename}_LIBRARY_RELEASE ${_lib} "")
+    __gtest_find_library_configuration(${_basename}_LIBRARY_DEBUG   ${_lib} "d")
+
+    select_library_configurations(${_basename})
+    set(${_basename}_LIBRARY ${${_basename}_LIBRARY} PARENT_SCOPE)
+endfunction()
+
 macro(__gtest_determine_windows_library_type _var)
     if(EXISTS "${${_var}}")
         file(TO_NATIVE_PATH "${${_var}}" _lib_path)
@@ -187,18 +208,13 @@
 )
 mark_as_advanced(GTEST_INCLUDE_DIR)
 
-if(MSVC AND GTEST_MSVC_SEARCH STREQUAL "MD")
-    # The provided /MD project files for Google Test add -md suffixes to the
-    # library names.
-    __gtest_find_library(GTEST_LIBRARY            gtest-md  gtest)
-    __gtest_find_library(GTEST_LIBRARY_DEBUG      gtest-mdd gtestd)
-    __gtest_find_library(GTEST_MAIN_LIBRARY       gtest_main-md  gtest_main)
-    __gtest_find_library(GTEST_MAIN_LIBRARY_DEBUG gtest_main-mdd gtest_maind)
-else()
-    __gtest_find_library(GTEST_LIBRARY            gtest)
-    __gtest_find_library(GTEST_LIBRARY_DEBUG      gtestd)
-    __gtest_find_library(GTEST_MAIN_LIBRARY       gtest_main)
-    __gtest_find_library(GTEST_MAIN_LIBRARY_DEBUG gtest_maind)
+# Allow GTEST_LIBRARY and GTEST_MAIN_LIBRARY to be set manually, as the
+# locations of the gtest and gtest_main libraries, respectively.
+if(NOT GTEST_LIBRARY)
+    __gtest_find_and_select_library_configurations(GTEST gtest)
+endif()
+if(NOT GTEST_MAIN_LIBRARY)
+    __gtest_find_and_select_library_configurations(GTEST_MAIN gtest_main)
 endif()
 
 include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
diff --git a/Modules/FindHDF5.cmake b/Modules/FindHDF5.cmake
index 60a313d..7a1c252 100644
--- a/Modules/FindHDF5.cmake
+++ b/Modules/FindHDF5.cmake
@@ -125,8 +125,6 @@
   Set ``true`` to skip trying to find ``hdf5-config.cmake``.
 #]=======================================================================]
 
-# This module is maintained by Will Dicharry <wdicharry@stellarscience.com>.
-
 include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake)
 include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
 
@@ -347,6 +345,7 @@
   # wrapper exists, but not the compiler.  E.g. Miniconda / Anaconda Python
   execute_process(
     COMMAND ${HDF5_${language}_COMPILER_EXECUTABLE} ${test_file}
+    WORKING_DIRECTORY ${scratch_dir}
     RESULT_VARIABLE return_value
     )
   if(return_value)
@@ -355,6 +354,7 @@
   else()
     execute_process(
       COMMAND ${HDF5_${language}_COMPILER_EXECUTABLE} -show ${lib_type_args} ${test_file}
+      WORKING_DIRECTORY ${scratch_dir}
       OUTPUT_VARIABLE output
       ERROR_VARIABLE output
       RESULT_VARIABLE return_value
diff --git a/Modules/FindICU.cmake b/Modules/FindICU.cmake
index 38081f5..c8b3e1f 100644
--- a/Modules/FindICU.cmake
+++ b/Modules/FindICU.cmake
@@ -5,6 +5,8 @@
 FindICU
 -------
 
+.. versionadded:: 3.7
+
 Find the International Components for Unicode (ICU) libraries and
 programs.
 
diff --git a/Modules/FindIce.cmake b/Modules/FindIce.cmake
index 5ce2b42..0f821e8 100644
--- a/Modules/FindIce.cmake
+++ b/Modules/FindIce.cmake
@@ -5,6 +5,8 @@
 FindIce
 -------
 
+.. versionadded:: 3.1
+
 Find the ZeroC Internet Communication Engine (ICE) programs,
 libraries and datafiles.
 
diff --git a/Modules/FindIconv.cmake b/Modules/FindIconv.cmake
index bf20f6f..41b7550 100644
--- a/Modules/FindIconv.cmake
+++ b/Modules/FindIconv.cmake
@@ -5,6 +5,8 @@
 FindIconv
 ---------
 
+.. versionadded:: 3.11
+
 This module finds the ``iconv()`` POSIX.1 functions on the system.
 These functions might be provided in the regular C library or externally
 in the form of an additional library.
@@ -110,6 +112,7 @@
 
 find_library(Iconv_LIBRARY
   NAMES ${Iconv_LIBRARY_NAMES}
+  NAMES_PER_DIR
   DOC "iconv library (potentially the C library)")
 
 mark_as_advanced(Iconv_INCLUDE_DIR)
diff --git a/Modules/FindIntl.cmake b/Modules/FindIntl.cmake
index 3818d45..1a09a60 100644
--- a/Modules/FindIntl.cmake
+++ b/Modules/FindIntl.cmake
@@ -5,6 +5,8 @@
 FindIntl
 --------
 
+.. versionadded:: 3.2
+
 Find the Gettext libintl headers and libraries.
 
 This module reports information about the Gettext libintl
@@ -40,7 +42,7 @@
 mark_as_advanced(Intl_INCLUDE_DIR)
 
 # Find all Intl libraries
-find_library(Intl_LIBRARY "intl"
+find_library(Intl_LIBRARY "intl" NAMES_PER_DIR
   DOC "libintl libraries (if not in the C library)")
 mark_as_advanced(Intl_LIBRARY)
 
diff --git a/Modules/FindJPEG.cmake b/Modules/FindJPEG.cmake
index 0bb6989..632fc9a 100644
--- a/Modules/FindJPEG.cmake
+++ b/Modules/FindJPEG.cmake
@@ -58,8 +58,8 @@
 endforeach()
 
 if(NOT JPEG_LIBRARY)
-  find_library(JPEG_LIBRARY_RELEASE NAMES ${jpeg_names})
-  find_library(JPEG_LIBRARY_DEBUG NAMES ${jpeg_names_debug})
+  find_library(JPEG_LIBRARY_RELEASE NAMES ${jpeg_names} NAMES_PER_DIR)
+  find_library(JPEG_LIBRARY_DEBUG NAMES ${jpeg_names_debug} NAMES_PER_DIR)
   include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake)
   select_library_configurations(JPEG)
   mark_as_advanced(JPEG_LIBRARY_RELEASE JPEG_LIBRARY_DEBUG)
diff --git a/Modules/FindLAPACK.cmake b/Modules/FindLAPACK.cmake
index 31e7de6..f996d4c 100644
--- a/Modules/FindLAPACK.cmake
+++ b/Modules/FindLAPACK.cmake
@@ -28,7 +28,7 @@
 
   * ``OpenBLAS``
   * ``FLAME``
-  * ``Intel10_32`` (intel mkl v10 32 bit)
+  * ``Intel10_32`` (intel mkl v10 32 bit, threaded code)
   * ``Intel10_64lp`` (intel mkl v10+ 64 bit, threaded code, lp64 model)
   * ``Intel10_64lp_seq`` (intel mkl v10+ 64 bit, sequential code, lp64 model)
   * ``Intel10_64ilp`` (intel mkl v10+ 64 bit, threaded code, ilp64 model)
@@ -162,6 +162,7 @@
       if(_libraries_work)
         find_library(${_prefix}_${_library}_LIBRARY
           NAMES ${_library}
+          NAMES_PER_DIR
           PATHS ${_extaddlibdir}
           PATH_SUFFIXES ${_subdirs}
         )
@@ -289,7 +290,9 @@
         endif()
         set(LAPACK_mkl_LIB_PATH_SUFFIXES
             "compiler/lib" "compiler/lib/${LAPACK_mkl_ARCH_NAME}_${LAPACK_mkl_OS_NAME}"
+            "compiler/lib/${LAPACK_mkl_ARCH_NAME}"
             "mkl/lib" "mkl/lib/${LAPACK_mkl_ARCH_NAME}_${LAPACK_mkl_OS_NAME}"
+            "mkl/lib/${LAPACK_mkl_ARCH_NAME}"
             "lib/${LAPACK_mkl_ARCH_NAME}_${LAPACK_mkl_OS_NAME}")
 
         # First try empty lapack libs
diff --git a/Modules/FindLTTngUST.cmake b/Modules/FindLTTngUST.cmake
index 9cd17eb..f478e4d 100644
--- a/Modules/FindLTTngUST.cmake
+++ b/Modules/FindLTTngUST.cmake
@@ -5,6 +5,8 @@
 FindLTTngUST
 ------------
 
+.. versionadded:: 3.6
+
 Find
 `Linux Trace Toolkit Next Generation (LTTng-UST) <http://lttng.org/>`__ library.
 
diff --git a/Modules/FindLibLZMA.cmake b/Modules/FindLibLZMA.cmake
index 200d6bf..4a79a10 100644
--- a/Modules/FindLibLZMA.cmake
+++ b/Modules/FindLibLZMA.cmake
@@ -43,8 +43,8 @@
 
 find_path(LIBLZMA_INCLUDE_DIR lzma.h )
 if(NOT LIBLZMA_LIBRARY)
-  find_library(LIBLZMA_LIBRARY_RELEASE NAMES lzma liblzma PATH_SUFFIXES lib)
-  find_library(LIBLZMA_LIBRARY_DEBUG NAMES lzmad liblzmad PATH_SUFFIXES lib)
+  find_library(LIBLZMA_LIBRARY_RELEASE NAMES lzma liblzma NAMES_PER_DIR PATH_SUFFIXES lib)
+  find_library(LIBLZMA_LIBRARY_DEBUG NAMES lzmad liblzmad NAMES_PER_DIR PATH_SUFFIXES lib)
   include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake)
   select_library_configurations(LIBLZMA)
 else()
diff --git a/Modules/FindLibinput.cmake b/Modules/FindLibinput.cmake
index c1fe455..88d5b2f 100644
--- a/Modules/FindLibinput.cmake
+++ b/Modules/FindLibinput.cmake
@@ -5,6 +5,8 @@
 FindLibinput
 ------------
 
+.. versionadded:: 3.14
+
 Find libinput headers and library.
 
 Imported Targets
diff --git a/Modules/FindMPI.cmake b/Modules/FindMPI.cmake
index 25de562..b2526c1 100644
--- a/Modules/FindMPI.cmake
+++ b/Modules/FindMPI.cmake
@@ -760,7 +760,7 @@
   # Save the explicitly given link directories
   set(MPI_LINK_DIRECTORIES_LEFTOVER "${MPI_LINK_DIRECTORIES_WORK}")
 
-  # An MPI compiler wrapper could have its MPI libraries in the implictly
+  # An MPI compiler wrapper could have its MPI libraries in the implicitly
   # linked directories of the compiler itself.
   if(DEFINED CMAKE_${LANG}_IMPLICIT_LINK_DIRECTORIES)
     list(APPEND MPI_LINK_DIRECTORIES_WORK "${CMAKE_${LANG}_IMPLICIT_LINK_DIRECTORIES}")
diff --git a/Modules/FindMatlab.cmake b/Modules/FindMatlab.cmake
index e42c206..05ec3ae 100644
--- a/Modules/FindMatlab.cmake
+++ b/Modules/FindMatlab.cmake
@@ -992,7 +992,10 @@
     endif()
   endif()
 
-  if(NOT Matlab_VERSION_STRING VERSION_LESS "9.4") # For 9.4 (R2018a) and newer, add API macro
+  # For 9.4 (R2018a) and newer, add API macro.
+  # Add it for unknown versions too, just in case.
+  if(NOT Matlab_VERSION_STRING VERSION_LESS "9.4"
+      OR Matlab_VERSION_STRING STREQUAL "unknown")
     if(${${prefix}_R2018a})
       set(MEX_API_MACRO "MATLAB_DEFAULT_RELEASE=R2018a")
     else()
diff --git a/Modules/FindODBC.cmake b/Modules/FindODBC.cmake
index 3f710db..884653c 100644
--- a/Modules/FindODBC.cmake
+++ b/Modules/FindODBC.cmake
@@ -5,6 +5,8 @@
 FindODBC
 --------
 
+.. versionadded:: 3.12
+
 Find an Open Database Connectivity (ODBC) include directory and library.
 
 On Windows, when building with Visual Studio, this module assumes the ODBC
diff --git a/Modules/FindOpenACC.cmake b/Modules/FindOpenACC.cmake
index 398dcf5..ed52e35 100644
--- a/Modules/FindOpenACC.cmake
+++ b/Modules/FindOpenACC.cmake
@@ -5,6 +5,8 @@
 FindOpenACC
 -----------
 
+.. versionadded:: 3.10
+
 Detect OpenACC support by the compiler.
 
 This module can be used to detect OpenACC support in a compiler.
diff --git a/Modules/FindOpenCL.cmake b/Modules/FindOpenCL.cmake
index 34a203e..b3e5a9f 100644
--- a/Modules/FindOpenCL.cmake
+++ b/Modules/FindOpenCL.cmake
@@ -5,6 +5,8 @@
 FindOpenCL
 ----------
 
+.. versionadded:: 3.1
+
 Finds Open Computing Language (OpenCL)
 
 IMPORTED Targets
diff --git a/Modules/FindOpenGL.cmake b/Modules/FindOpenGL.cmake
index 17ffe85..110e7f9 100644
--- a/Modules/FindOpenGL.cmake
+++ b/Modules/FindOpenGL.cmake
@@ -132,19 +132,7 @@
 
 set(_OpenGL_CACHE_VARS)
 
-if (CYGWIN)
-  find_path(OPENGL_INCLUDE_DIR GL/gl.h )
-  list(APPEND _OpenGL_REQUIRED_VARS OPENGL_INCLUDE_DIR)
-
-  find_library(OPENGL_gl_LIBRARY opengl32 )
-  find_library(OPENGL_glu_LIBRARY glu32 )
-
-  list(APPEND _OpenGL_CACHE_VARS
-    OPENGL_INCLUDE_DIR
-    OPENGL_gl_LIBRARY
-    OPENGL_glu_LIBRARY
-    )
-elseif (WIN32)
+if (WIN32)
 
   if(BORLAND)
     set (OPENGL_gl_LIBRARY import32 CACHE STRING "OpenGL library for win32")
diff --git a/Modules/FindOpenSSL.cmake b/Modules/FindOpenSSL.cmake
index ee40696..9196851 100644
--- a/Modules/FindOpenSSL.cmake
+++ b/Modules/FindOpenSSL.cmake
@@ -27,11 +27,11 @@
   projects under MSVC. This target is available only if found OpenSSL version
   is not less than 0.9.8. By linking this target the above OpenSSL targets can
   be linked even if the project has different MSVC runtime configurations with
-  the above OpenSSL targets. This target has no effect on plaforms other than
+  the above OpenSSL targets. This target has no effect on platforms other than
   MSVC.
 
 NOTE: Due to how ``INTERFACE_SOURCES`` are consumed by the consuming target,
-unless you certainly know what you are doing, it is always prefered to link
+unless you certainly know what you are doing, it is always preferred to link
 ``OpenSSL::applink`` target as ``PRIVATE`` and to make sure that this target is
 linked at most once for the whole dependency graph of any library or
 executable:
diff --git a/Modules/FindPNG.cmake b/Modules/FindPNG.cmake
index f1fe89a..fd0e4e9 100644
--- a/Modules/FindPNG.cmake
+++ b/Modules/FindPNG.cmake
@@ -76,8 +76,8 @@
   # For compatibility with versions prior to this multi-config search, honor
   # any PNG_LIBRARY that is already specified and skip the search.
   if(NOT PNG_LIBRARY)
-    find_library(PNG_LIBRARY_RELEASE NAMES ${PNG_NAMES})
-    find_library(PNG_LIBRARY_DEBUG NAMES ${PNG_NAMES_DEBUG})
+    find_library(PNG_LIBRARY_RELEASE NAMES ${PNG_NAMES} NAMES_PER_DIR)
+    find_library(PNG_LIBRARY_DEBUG NAMES ${PNG_NAMES_DEBUG} NAMES_PER_DIR)
     include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake)
     select_library_configurations(PNG)
     mark_as_advanced(PNG_LIBRARY_RELEASE PNG_LIBRARY_DEBUG)
diff --git a/Modules/FindPatch.cmake b/Modules/FindPatch.cmake
index 4998839..4108651 100644
--- a/Modules/FindPatch.cmake
+++ b/Modules/FindPatch.cmake
@@ -5,6 +5,8 @@
 FindPatch
 ---------
 
+.. versionadded:: 3.10
+
 The module defines the following variables:
 
 ``Patch_EXECUTABLE``
diff --git a/Modules/FindPerlLibs.cmake b/Modules/FindPerlLibs.cmake
index 7e27f31..d576b86 100644
--- a/Modules/FindPerlLibs.cmake
+++ b/Modules/FindPerlLibs.cmake
@@ -108,6 +108,9 @@
   if (NOT PERL_POSSIBLE_LIBRARY_NAMES)
     set(PERL_POSSIBLE_LIBRARY_NAMES perl${PERL_VERSION_STRING} perl)
   endif()
+  if(CMAKE_SYSTEM_NAME MATCHES "CYGWIN")
+    list (APPEND PERL_POSSIBLE_LIBRARY_NAMES perl${PERL_VERSION_STRING})
+  endif()
   if (CMAKE_SYSTEM_NAME MATCHES "MSYS|CYGWIN")
     # on MSYS and CYGWIN environments, current perl -V:libperl gives shared library name
     # rather than the import library. So, extends possible library names
diff --git a/Modules/FindProtobuf.cmake b/Modules/FindProtobuf.cmake
index e09717d..f6d8fe3 100644
--- a/Modules/FindProtobuf.cmake
+++ b/Modules/FindProtobuf.cmake
@@ -376,11 +376,13 @@
   else()
     find_library(${name}_LIBRARY_RELEASE
       NAMES ${filename}
+      NAMES_PER_DIR
       PATHS ${Protobuf_SRC_ROOT_FOLDER}/vsprojects/${_PROTOBUF_ARCH_DIR}Release)
     mark_as_advanced(${name}_LIBRARY_RELEASE)
 
     find_library(${name}_LIBRARY_DEBUG
       NAMES ${filename}d ${filename}
+      NAMES_PER_DIR
       PATHS ${Protobuf_SRC_ROOT_FOLDER}/vsprojects/${_PROTOBUF_ARCH_DIR}Debug)
     mark_as_advanced(${name}_LIBRARY_DEBUG)
 
diff --git a/Modules/FindPython.cmake b/Modules/FindPython.cmake
index 01b82c4..d89029a 100644
--- a/Modules/FindPython.cmake
+++ b/Modules/FindPython.cmake
@@ -5,6 +5,8 @@
 FindPython
 ----------
 
+.. versionadded:: 3.12
+
 Find Python interpreter, compiler and development environment (include
 directories and libraries).
 
@@ -44,7 +46,7 @@
   If components ``Interpreter`` and ``Development`` (or one of its
   sub-components) are both specified, this module search only for interpreter
   with same platform architecture as the one defined by ``CMake``
-  configuration. This contraint does not apply if only ``Interpreter``
+  configuration. This constraint does not apply if only ``Interpreter``
   component is specified.
 
 Imported Targets
@@ -155,7 +157,7 @@
 ``Python_NumPy_FOUND``
   System has the NumPy.
 ``Python_NumPy_INCLUDE_DIRS``
-  The NumPy include directries.
+  The NumPy include directories.
 ``Python_NumPy_VERSION``
   The NumPy version.
 
@@ -189,7 +191,7 @@
 
   * ``ON``: Corresponding flag is selected.
   * ``OFF``: Corresponding flag is not selected.
-  * ``ANY``: The two posibilties (``ON`` and ``OFF``) will be searched.
+  * ``ANY``: The two possibilities (``ON`` and ``OFF``) will be searched.
 
   From this 3-tuple, various ABIs will be searched starting from the most
   specialized to the most general. Moreover, ``debug`` versions will be
@@ -347,7 +349,7 @@
   When an artifact is specified, all ``HINTS`` will be ignored and no search
   will be performed for this artifact.
 
-  If more than one artifact is specified, it is the user's responsability to
+  If more than one artifact is specified, it is the user's responsibility to
   ensure the consistency of the various artifacts.
 
 By default, this module supports multiple calls in different directories of a
@@ -355,7 +357,7 @@
 and consistent results for each call. To support this behavior, ``CMake`` cache
 is not used in the traditional way which can be problematic for interactive
 specification. So, to enable also interactive specification, module behavior
-can be controled with the following variable:
+can be controlled with the following variable:
 
 ``Python_ARTIFACTS_INTERACTIVE``
   Selects the behavior of the module. This is a boolean variable:
diff --git a/Modules/FindPython2.cmake b/Modules/FindPython2.cmake
index 84c0c73..f5ad454 100644
--- a/Modules/FindPython2.cmake
+++ b/Modules/FindPython2.cmake
@@ -5,6 +5,8 @@
 FindPython2
 -----------
 
+.. versionadded:: 3.12
+
 Find Python 2 interpreter, compiler and development environment (include
 directories and libraries).
 
@@ -45,7 +47,7 @@
   If components ``Interpreter`` and ``Development`` (or one of its
   sub-components) are both specified, this module search only for interpreter
   with same platform architecture as the one defined by ``CMake``
-  configuration. This contraint does not apply if only ``Interpreter``
+  configuration. This constraint does not apply if only ``Interpreter``
   component is specified.
 
 Imported Targets
@@ -147,7 +149,7 @@
 ``Python2_NumPy_FOUND``
   System has the NumPy.
 ``Python2_NumPy_INCLUDE_DIRS``
-  The NumPy include directries.
+  The NumPy include directories.
 ``Python2_NumPy_VERSION``
   The NumPy version.
 
@@ -294,7 +296,7 @@
   When an artifact is specified, all ``HINTS`` will be ignored and no search
   will be performed for this artifact.
 
-  If more than one artifact is specified, it is the user's responsability to
+  If more than one artifact is specified, it is the user's responsibility to
   ensure the consistency of the various artifacts.
 
 By default, this module supports multiple calls in different directories of a
@@ -302,7 +304,7 @@
 and consistent results for each call. To support this behavior, ``CMake`` cache
 is not used in the traditional way which can be problematic for interactive
 specification. So, to enable also interactive specification, module behavior
-can be controled with the following variable:
+can be controlled with the following variable:
 
 ``Python2_ARTIFACTS_INTERACTIVE``
   Selects the behavior of the module. This is a boolean variable:
diff --git a/Modules/FindPython3.cmake b/Modules/FindPython3.cmake
index f142c07..bacdc42 100644
--- a/Modules/FindPython3.cmake
+++ b/Modules/FindPython3.cmake
@@ -5,6 +5,8 @@
 FindPython3
 -----------
 
+.. versionadded:: 3.12
+
 Find Python 3 interpreter, compiler and development environment (include
 directories and libraries).
 
@@ -45,7 +47,7 @@
   If components ``Interpreter`` and ``Development`` (or one of its
   sub-components) are both specified, this module search only for interpreter
   with same platform architecture as the one defined by ``CMake``
-  configuration. This contraint does not apply if only ``Interpreter``
+  configuration. This constraint does not apply if only ``Interpreter``
   component is specified.
 
 Imported Targets
@@ -156,7 +158,7 @@
 ``Python3_NumPy_FOUND``
   System has the NumPy.
 ``Python3_NumPy_INCLUDE_DIRS``
-  The NumPy include directries.
+  The NumPy include directories.
 ``Python3_NumPy_VERSION``
   The NumPy version.
 
@@ -186,7 +188,7 @@
 
   * ``ON``: Corresponding flag is selected.
   * ``OFF``: Corresponding flag is not selected.
-  * ``ANY``: The two posibilties (``ON`` and ``OFF``) will be searched.
+  * ``ANY``: The two possibilities (``ON`` and ``OFF``) will be searched.
 
   From this 3-tuple, various ABIs will be searched starting from the most
   specialized to the most general. Moreover, ``debug`` versions will be
@@ -344,7 +346,7 @@
   When an artifact is specified, all ``HINTS`` will be ignored and no search
   will be performed for this artifact.
 
-  If more than one artifact is specified, it is the user's responsability to
+  If more than one artifact is specified, it is the user's responsibility to
   ensure the consistency of the various artifacts.
 
 By default, this module supports multiple calls in different directories of a
@@ -352,7 +354,7 @@
 and consistent results for each call. To support this behavior, ``CMake`` cache
 is not used in the traditional way which can be problematic for interactive
 specification. So, to enable also interactive specification, module behavior
-can be controled with the following variable:
+can be controlled with the following variable:
 
 ``Python3_ARTIFACTS_INTERACTIVE``
   Selects the behavior of the module. This is a boolean variable:
diff --git a/Modules/FindQt4.cmake b/Modules/FindQt4.cmake
index 2e3da74..ec0f453 100644
--- a/Modules/FindQt4.cmake
+++ b/Modules/FindQt4.cmake
@@ -147,7 +147,7 @@
         in:  directories sources ts_files
         options: flags to pass to lupdate, such as -extensions to specify
         extensions for a directory scan.
-        generates commands to create .ts (vie lupdate) and .qm
+        generates commands to create .ts (via lupdate) and .qm
         (via lrelease) - files from directories and/or sources. The ts files are
         created and/or updated in the source tree (unless given with full paths).
         The qm files are generated in the build tree.
diff --git a/Modules/FindSDL.cmake b/Modules/FindSDL.cmake
index 8d793a9..59eddbb 100644
--- a/Modules/FindSDL.cmake
+++ b/Modules/FindSDL.cmake
@@ -5,24 +5,54 @@
 FindSDL
 -------
 
-Locate SDL library
-
-This module defines
-
-::
-
-  SDL_LIBRARY, the name of the library to link against
-  SDL_FOUND, if false, do not try to link to SDL
-  SDL_INCLUDE_DIR, where to find SDL.h
-  SDL_VERSION_STRING, human-readable string containing the version of SDL
+Locate the SDL library
 
 
+Imported targets
+^^^^^^^^^^^^^^^^
+
+This module defines the following :prop_tgt:`IMPORTED` target:
+
+``SDL::SDL``
+  The SDL library, if found
+
+Result variables
+^^^^^^^^^^^^^^^^
+
+This module will set the following variables in your project:
+
+``SDL_INCLUDE_DIRS``
+  where to find SDL.h
+``SDL_LIBRARIES``
+  the name of the library to link against
+``SDL_FOUND``
+  if false, do not try to link to SDL
+``SDL_VERSION``
+  the human-readable string containing the version of SDL if found
+``SDL_VERSION_MAJOR``
+  SDL major version
+``SDL_VERSION_MINOR``
+  SDL minor version
+``SDL_VERSION_PATCH``
+  SDL patch version
+
+Cache variables
+^^^^^^^^^^^^^^^
+
+These variables may optionally be set to help this module find the correct files:
+
+``SDL_INCLUDE_DIR``
+  where to find SDL.h
+``SDL_LIBRARY``
+  the name of the library to link against
+
+
+Variables for locating SDL
+^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 This module responds to the flag:
 
-::
-
-  SDL_BUILDING_LIBRARY
+``SDL_BUILDING_LIBRARY``
     If this is defined, then no SDL_main will be linked in because
     only applications need main().
     Otherwise, it is assumed you are building an application and this
@@ -30,6 +60,15 @@
     as part of the returned SDL_LIBRARY variable.
 
 
+Obsolete variables
+^^^^^^^^^^^^^^^^^^
+
+These variables are obsolete and provided for backwards compatibility:
+
+``SDL_VERSION_STRING``
+  the human-readable string containing the version of SDL if found.
+  Identical to SDL_VERSION
+
 
 Don't forget to include SDLmain.h and SDLmain.m your project for the
 OS X framework based version.  (Other versions link to -lSDLmain which
@@ -52,15 +91,6 @@
 $SDLDIR is an environment variable that would correspond to the
 ./configure --prefix=$SDLDIR used in building SDL.  l.e.galup 9-20-02
 
-Modified by Eric Wing.  Added code to assist with automated building
-by using environmental variables and providing a more
-controlled/consistent search behavior.  Added new modifications to
-recognize OS X frameworks and additional Unix paths (FreeBSD, etc).
-Also corrected the header search path to follow "proper" SDL
-guidelines.  Added a search for SDLmain which is needed by some
-platforms.  Added a search for threads which is needed by some
-platforms.  Added needed compile switches for MinGW.
-
 On OSX, this will prefer the Framework version (if found) over others.
 People will have to manually change the cache values of SDL_LIBRARY to
 override this selection or set the CMake environment
@@ -174,13 +204,11 @@
   string(REGEX REPLACE "^#define[ \t]+SDL_MAJOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL_VERSION_MAJOR "${SDL_VERSION_MAJOR_LINE}")
   string(REGEX REPLACE "^#define[ \t]+SDL_MINOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL_VERSION_MINOR "${SDL_VERSION_MINOR_LINE}")
   string(REGEX REPLACE "^#define[ \t]+SDL_PATCHLEVEL[ \t]+([0-9]+)$" "\\1" SDL_VERSION_PATCH "${SDL_VERSION_PATCH_LINE}")
-  set(SDL_VERSION_STRING ${SDL_VERSION_MAJOR}.${SDL_VERSION_MINOR}.${SDL_VERSION_PATCH})
   unset(SDL_VERSION_MAJOR_LINE)
   unset(SDL_VERSION_MINOR_LINE)
   unset(SDL_VERSION_PATCH_LINE)
-  unset(SDL_VERSION_MAJOR)
-  unset(SDL_VERSION_MINOR)
-  unset(SDL_VERSION_PATCH)
+  set(SDL_VERSION ${SDL_VERSION_MAJOR}.${SDL_VERSION_MINOR}.${SDL_VERSION_PATCH})
+  set(SDL_VERSION_STRING ${SDL_VERSION})
 endif()
 
 include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
@@ -188,3 +216,14 @@
 FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL
                                   REQUIRED_VARS SDL_LIBRARY SDL_INCLUDE_DIR
                                   VERSION_VAR SDL_VERSION_STRING)
+
+if(SDL_FOUND)
+  set(SDL_LIBRARIES ${SDL_LIBRARY})
+  set(SDL_INCLUDE_DIRS ${SDL_INCLUDE_DIR})
+  if(NOT TARGET SDL::SDL)
+    add_library(SDL::SDL INTERFACE IMPORTED)
+    set_target_properties(SDL::SDL PROPERTIES
+      INTERFACE_INCLUDE_DIRECTORIES "${SDL_INCLUDE_DIR}"
+      INTERFACE_LINK_LIBRARIES "${SDL_LIBRARY}")
+  endif()
+endif()
diff --git a/Modules/FindSQLite3.cmake b/Modules/FindSQLite3.cmake
index 374d7af..88c7dd2 100644
--- a/Modules/FindSQLite3.cmake
+++ b/Modules/FindSQLite3.cmake
@@ -5,6 +5,8 @@
 FindSQLite3
 -----------
 
+.. versionadded:: 3.14
+
 Find the SQLite libraries, v3
 
 IMPORTED targets
diff --git a/Modules/FindTIFF.cmake b/Modules/FindTIFF.cmake
index 00a3a41..3b74c94 100644
--- a/Modules/FindTIFF.cmake
+++ b/Modules/FindTIFF.cmake
@@ -5,7 +5,14 @@
 FindTIFF
 --------
 
-Find the TIFF library (``libtiff``).
+Find the TIFF library (``libtiff``, https://libtiff.gitlab.io/libtiff/).
+
+Optional COMPONENTS
+^^^^^^^^^^^^^^^^^^^
+
+This module supports the optional component `CXX`, for use with the COMPONENTS
+argument of the :command:`find_package` command. This component has an associated
+imported target, as described below.
 
 Imported targets
 ^^^^^^^^^^^^^^^^
@@ -15,6 +22,11 @@
 ``TIFF::TIFF``
   The TIFF library, if found.
 
+``TIFF::CXX``
+  The C++ wrapper libtiffxx, if requested by the `COMPONENTS CXX` option,
+  if the compiler is not MSVC (which includes the C++ wrapper in libtiff),
+  and if found.
+
 Result variables
 ^^^^^^^^^^^^^^^^
 
@@ -36,10 +48,19 @@
 
 ``TIFF_INCLUDE_DIR``
   the directory containing the TIFF headers
-``TIFF_LIBRARY``
-  the path to the TIFF library
+``TIFF_LIBRARY_RELEASE``
+  the path to the TIFF library for release configurations
+``TIFF_LIBRARY_DEBUG``
+  the path to the TIFF library for debug configurations
+``TIFFXX_LIBRARY_RELEASE``
+  the path to the TIFFXX library for release configurations
+``TIFFXX_LIBRARY_DEBUG``
+  the path to the TIFFXX library for debug configurations
 #]=======================================================================]
 
+cmake_policy(PUSH)
+cmake_policy(SET CMP0057 NEW)
+
 find_path(TIFF_INCLUDE_DIR tiff.h)
 
 set(TIFF_NAMES ${TIFF_NAMES} tiff libtiff tiff3 libtiff3)
@@ -54,8 +75,6 @@
   select_library_configurations(TIFF)
   mark_as_advanced(TIFF_LIBRARY_RELEASE TIFF_LIBRARY_DEBUG)
 endif()
-unset(TIFF_NAMES)
-unset(TIFF_NAMES_DEBUG)
 
 if(TIFF_INCLUDE_DIR AND EXISTS "${TIFF_INCLUDE_DIR}/tiffvers.h")
     file(STRINGS "${TIFF_INCLUDE_DIR}/tiffvers.h" tiff_version_str
@@ -66,13 +85,46 @@
     unset(tiff_version_str)
 endif()
 
+foreach(_comp IN LISTS TIFF_FIND_COMPONENTS)
+  if(_comp STREQUAL "CXX")
+    if(MSVC)
+      # C++ bindings are built into the main tiff library.
+      set(TIFF_CXX_FOUND 1)
+    else()
+      foreach(name ${TIFF_NAMES})
+        list(APPEND TIFFXX_NAMES "${name}xx")
+        list(APPEND TIFFXX_NAMES_DEBUG "${name}xxd")
+      endforeach()
+      find_library(TIFFXX_LIBRARY_RELEASE NAMES ${TIFFXX_NAMES})
+      find_library(TIFFXX_LIBRARY_DEBUG NAMES ${TIFFXX_NAMES_DEBUG})
+      include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake)
+      select_library_configurations(TIFFXX)
+      mark_as_advanced(TIFFXX_LIBRARY_RELEASE TIFFXX_LIBRARY_DEBUG)
+      unset(TIFFXX_NAMES)
+      unset(TIFFXX_NAMES_DEBUG)
+      if(TIFFXX_LIBRARY)
+        set(TIFF_CXX_FOUND 1)
+      endif()
+    endif()
+  endif()
+endforeach()
+unset(_comp)
+
+unset(TIFF_NAMES)
+unset(TIFF_NAMES_DEBUG)
+
 include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
 FIND_PACKAGE_HANDLE_STANDARD_ARGS(TIFF
+                                  HANDLE_COMPONENTS
                                   REQUIRED_VARS TIFF_LIBRARY TIFF_INCLUDE_DIR
                                   VERSION_VAR TIFF_VERSION_STRING)
 
 if(TIFF_FOUND)
   set(TIFF_LIBRARIES ${TIFF_LIBRARY})
+  if("CXX" IN_LIST TIFF_FIND_COMPONENTS AND NOT MSVC)
+    list(APPEND TIFF_LIBRARIES ${TIFFXX_LIBRARY})
+  endif()
+
   set(TIFF_INCLUDE_DIRS "${TIFF_INCLUDE_DIR}")
 
   if(NOT TARGET TIFF::TIFF)
@@ -101,6 +153,41 @@
         IMPORTED_LOCATION_DEBUG "${TIFF_LIBRARY_DEBUG}")
     endif()
   endif()
+
+  if(NOT TARGET TIFF::CXX)
+    if(MSVC)
+      add_library(TIFF::CXX INTERFACE IMPORTED)
+      set_property(TARGET TIFF::CXX PROPERTY INTERFACE_LINK_LIBRARIES TIFF::TIFF)
+    else()
+      add_library(TIFF::CXX UNKNOWN IMPORTED)
+      set_property(TARGET TIFF::CXX PROPERTY INTERFACE_LINK_LIBRARIES TIFF::TIFF)
+      if(TIFF_INCLUDE_DIRS)
+        set_target_properties(TIFF::CXX PROPERTIES
+          INTERFACE_INCLUDE_DIRECTORIES "${TIFF_INCLUDE_DIRS}")
+      endif()
+      if(EXISTS "${TIFFXX_LIBRARY}")
+        set_target_properties(TIFF::CXX PROPERTIES
+          IMPORTED_LINK_INTERFACE_LANGUAGES "CXX"
+          IMPORTED_LOCATION "${TIFFXX_LIBRARY}")
+      endif()
+      if(EXISTS "${TIFFXX_LIBRARY_RELEASE}")
+        set_property(TARGET TIFF::CXX APPEND PROPERTY
+          IMPORTED_CONFIGURATIONS RELEASE)
+        set_target_properties(TIFF::CXX PROPERTIES
+          IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "CXX"
+          IMPORTED_LOCATION_RELEASE "${TIFFXX_LIBRARY_RELEASE}")
+      endif()
+      if(EXISTS "${TIFFXX_LIBRARY_DEBUG}")
+        set_property(TARGET TIFF::CXX APPEND PROPERTY
+          IMPORTED_CONFIGURATIONS DEBUG)
+        set_target_properties(TIFF::CXX PROPERTIES
+          IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "CXX"
+          IMPORTED_LOCATION_DEBUG "${TIFFXX_LIBRARY_DEBUG}")
+      endif()
+    endif()
+  endif()
+
 endif()
 
-mark_as_advanced(TIFF_INCLUDE_DIR TIFF_LIBRARY)
+mark_as_advanced(TIFF_INCLUDE_DIR)
+cmake_policy(POP)
diff --git a/Modules/FindTclsh.cmake b/Modules/FindTclsh.cmake
index 5555d59..594d0ec 100644
--- a/Modules/FindTclsh.cmake
+++ b/Modules/FindTclsh.cmake
@@ -15,15 +15,8 @@
 
   TCLSH_FOUND = TRUE if tclsh has been found
   TCL_TCLSH = the path to the tclsh executable
-
-In cygwin, look for the cygwin version first.  Don't look for it later
-to avoid finding the cygwin version on a Win32 build.
 #]=======================================================================]
 
-if(CYGWIN)
-  find_program(TCL_TCLSH NAMES cygtclsh83 cygtclsh80)
-endif()
-
 get_filename_component(TK_WISH_PATH "${TK_WISH}" PATH)
 get_filename_component(TK_WISH_PATH_PARENT "${TK_WISH_PATH}" PATH)
 string(REGEX REPLACE
diff --git a/Modules/FindVulkan.cmake b/Modules/FindVulkan.cmake
index 4b999b6..0ec6013 100644
--- a/Modules/FindVulkan.cmake
+++ b/Modules/FindVulkan.cmake
@@ -5,6 +5,8 @@
 FindVulkan
 ----------
 
+.. versionadded:: 3.7
+
 Find Vulkan, which is a low-overhead, cross-platform 3D graphics
 and computing API.
 
@@ -14,6 +16,9 @@
 This module defines :prop_tgt:`IMPORTED` target ``Vulkan::Vulkan``, if
 Vulkan has been found.
 
+This module defines :prop_tgt:`IMPORTED` target ``Vulkan::glslc``, if
+Vulkan and the GLSLC SPIR-V compiler has been found.
+
 Result Variables
 ^^^^^^^^^^^^^^^^
 
@@ -23,10 +28,11 @@
   Vulkan_INCLUDE_DIRS   - include directories for Vulkan
   Vulkan_LIBRARIES      - link against this library to use Vulkan
 
-The module will also define two cache variables::
+The module will also define three cache variables::
 
-  Vulkan_INCLUDE_DIR    - the Vulkan include directory
-  Vulkan_LIBRARY        - the path to the Vulkan library
+  Vulkan_INCLUDE_DIR        - the Vulkan include directory
+  Vulkan_LIBRARY            - the path to the Vulkan library
+  Vulkan_GLSLC_EXECUTABLE   - the path to the GLSL SPIR-V compiler
 
 Hints
 ^^^^^
@@ -53,6 +59,11 @@
         "$ENV{VULKAN_SDK}/Lib"
         "$ENV{VULKAN_SDK}/Bin"
       )
+    find_program(Vulkan_GLSLC_EXECUTABLE
+      NAMES glslc
+      HINTS
+        "$ENV{VULKAN_SDK}/Bin"
+      )
   elseif(CMAKE_SIZEOF_VOID_P EQUAL 4)
     find_library(Vulkan_LIBRARY
       NAMES vulkan-1
@@ -60,6 +71,11 @@
         "$ENV{VULKAN_SDK}/Lib32"
         "$ENV{VULKAN_SDK}/Bin32"
       )
+    find_program(Vulkan_GLSLC_EXECUTABLE
+      NAMES glslc
+      HINTS
+        "$ENV{VULKAN_SDK}/Bin32"
+      )
   endif()
 else()
   find_path(Vulkan_INCLUDE_DIR
@@ -68,6 +84,9 @@
   find_library(Vulkan_LIBRARY
     NAMES vulkan
     HINTS "$ENV{VULKAN_SDK}/lib")
+  find_program(Vulkan_GLSLC_EXECUTABLE
+    NAMES glslc
+    HINTS "$ENV{VULKAN_SDK}/bin")
 endif()
 
 set(Vulkan_LIBRARIES ${Vulkan_LIBRARY})
@@ -78,7 +97,7 @@
   DEFAULT_MSG
   Vulkan_LIBRARY Vulkan_INCLUDE_DIR)
 
-mark_as_advanced(Vulkan_INCLUDE_DIR Vulkan_LIBRARY)
+mark_as_advanced(Vulkan_INCLUDE_DIR Vulkan_LIBRARY Vulkan_GLSLC_EXECUTABLE)
 
 if(Vulkan_FOUND AND NOT TARGET Vulkan::Vulkan)
   add_library(Vulkan::Vulkan UNKNOWN IMPORTED)
@@ -86,3 +105,8 @@
     IMPORTED_LOCATION "${Vulkan_LIBRARIES}"
     INTERFACE_INCLUDE_DIRECTORIES "${Vulkan_INCLUDE_DIRS}")
 endif()
+
+if(Vulkan_FOUND AND Vulkan_GLSLC_EXECUTABLE AND NOT TARGET Vulkan::glslc)
+  add_executable(Vulkan::glslc IMPORTED)
+  set_property(TARGET Vulkan::glslc PROPERTY IMPORTED_LOCATION "${Vulkan_GLSLC_EXECUTABLE}")
+endif()
diff --git a/Modules/FindX11.cmake b/Modules/FindX11.cmake
index ccd0252..778da9b 100644
--- a/Modules/FindX11.cmake
+++ b/Modules/FindX11.cmake
@@ -59,6 +59,7 @@
   X11_XShm_INCLUDE_PATH,         (in X11_Xext_LIB),  X11_XShm_FOUND
   X11_Xshape_INCLUDE_PATH,       (in X11_Xext_LIB),  X11_Xshape_FOUND
   X11_XSync_INCLUDE_PATH,        (in X11_Xext_LIB),  X11_XSync_FOUND
+  X11_Xaw_INCLUDE_PATH,          X11_Xaw_LIB         X11_Xaw_FOUND         X11::Xaw
 #]=======================================================================]
 
 if (UNIX)
@@ -100,6 +101,7 @@
   find_path(X11_Xaccessrules_INCLUDE_PATH X11/extensions/XKBrules.h  ${X11_INC_SEARCH_PATH})
   find_path(X11_Xaccessstr_INCLUDE_PATH X11/extensions/XKBstr.h      ${X11_INC_SEARCH_PATH})
   find_path(X11_Xau_INCLUDE_PATH X11/Xauth.h                         ${X11_INC_SEARCH_PATH})
+  find_path(X11_Xaw_INCLUDE_PATH X11/Xaw/Intrinsic.h                 ${X11_INC_SEARCH_PATH})
   find_path(X11_xcb_INCLUDE_PATH xcb/xcb.h                           ${X11_INC_SEARCH_PATH})
   find_path(X11_X11_xcb_INCLUDE_PATH X11/Xlib-xcb.h                  ${X11_INC_SEARCH_PATH})
   find_path(X11_xcb_icccm_INCLUDE_PATH xcb/xcb_icccm.h               ${X11_INC_SEARCH_PATH})
@@ -134,6 +136,8 @@
   find_path(X11_Xv_INCLUDE_PATH X11/extensions/Xvlib.h               ${X11_INC_SEARCH_PATH})
   find_path(X11_XSync_INCLUDE_PATH X11/extensions/sync.h             ${X11_INC_SEARCH_PATH})
 
+
+
   # Backwards compatibility.
   set(X11_Xinput_INCLUDE_PATH "${X11_Xi_INCLUDE_PATH}")
   set(X11_xf86misc_INCLUDE_PATH "${X11_Xxf86misc_INCLUDE_PATH}")
@@ -148,6 +152,7 @@
   find_library(X11_ICE_LIB ICE               ${X11_LIB_SEARCH_PATH})
   find_library(X11_SM_LIB SM                 ${X11_LIB_SEARCH_PATH})
   find_library(X11_Xau_LIB Xau               ${X11_LIB_SEARCH_PATH})
+  find_library(X11_Xaw_LIB Xaw               ${X11_LIB_SEARCH_PATH})
   find_library(X11_xcb_LIB xcb               ${X11_LIB_SEARCH_PATH})
   find_library(X11_X11_xcb_LIB X11-xcb       ${X11_LIB_SEARCH_PATH})
   find_library(X11_xcb_icccm_LIB xcb-icccm   ${X11_LIB_SEARCH_PATH})
@@ -392,6 +397,10 @@
      set(X11_SM_FOUND TRUE)
   endif()
 
+  if(X11_Xaw_LIB AND X11_Xaw_INCLUDE_PATH)
+      set(X11_Xaw_FOUND TRUE)
+  endif()
+
   # Most of the X11 headers will be in the same directories, avoid
   # creating a huge list of duplicates.
   if (X11_INCLUDE_DIR)
@@ -527,6 +536,14 @@
       INTERFACE_INCLUDE_DIRECTORIES "${X11_Xau_INCLUDE_PATH}")
   endif ()
 
+  if (X11_Xaw_FOUND AND NOT TARGET X11::Xaw)
+    add_library(X11::Xaw UNKNOWN IMPORTED)
+    set_target_properties(X11::Xaw PROPERTIES
+      IMPORTED_LOCATION "${X11_Xaw_LIB}"
+      INTERFACE_INCLUDE_DIRECTORIES "${X11_Xaw_INCLUDE_PATH}"
+      INTERFACE_LINK_LIBRARIES "X11::Xext;X11::Xmu;X11::Xt;X11::Xpm;X11::X11")
+  endif ()
+
   if (X11_xcb_FOUND AND NOT TARGET X11::xcb)
     add_library(X11::xcb UNKNOWN IMPORTED)
     set_target_properties(X11::xcb PROPERTIES
@@ -825,6 +842,8 @@
     X11_SM_LIB
     X11_SM_INCLUDE_PATH
     X11_XSync_INCLUDE_PATH
+    X11_Xaw_LIB
+    X11_Xaw_INCLUDE_PATH
   )
   set(CMAKE_FIND_FRAMEWORK ${CMAKE_FIND_FRAMEWORK_SAVE})
   set(CMAKE_REQUIRED_QUIET ${CMAKE_REQUIRED_QUIET_SAVE})
diff --git a/Modules/FindXCTest.cmake b/Modules/FindXCTest.cmake
index 15721e1..1f6e825 100644
--- a/Modules/FindXCTest.cmake
+++ b/Modules/FindXCTest.cmake
@@ -5,6 +5,8 @@
 FindXCTest
 ----------
 
+.. versionadded:: 3.3
+
 Functions to help creating and executing XCTest bundles.
 
 An XCTest bundle is a CFBundle with a special product-type
diff --git a/Modules/FindXalanC.cmake b/Modules/FindXalanC.cmake
index 54783e3..a7fb766 100644
--- a/Modules/FindXalanC.cmake
+++ b/Modules/FindXalanC.cmake
@@ -5,6 +5,8 @@
 FindXalanC
 -----------
 
+.. versionadded:: 3.5
+
 Find the Apache Xalan-C++ XSL transform processor headers and libraries.
 
 Imported targets
diff --git a/Modules/FindXercesC.cmake b/Modules/FindXercesC.cmake
index db78b61..abe18c0 100644
--- a/Modules/FindXercesC.cmake
+++ b/Modules/FindXercesC.cmake
@@ -5,6 +5,8 @@
 FindXercesC
 -----------
 
+.. versionadded:: 3.1
+
 Find the Apache Xerces-C++ validating XML parser headers and libraries.
 
 Imported targets
diff --git a/Modules/FindwxWindows.cmake b/Modules/FindwxWindows.cmake
index 35840f5..07fbc1b 100644
--- a/Modules/FindwxWindows.cmake
+++ b/Modules/FindwxWindows.cmake
@@ -307,7 +307,7 @@
   else ()
     ## WX is built as multiple small pieces libraries instead of monolithic
 
-    ## DEPECATED (jw) replaced by more general WXWINDOWS_USE_MONOLITHIC ON/OFF
+    ## DEPRECATED (jw) replaced by more general WXWINDOWS_USE_MONOLITHIC ON/OFF
     # option(WXWINDOWS_SEPARATE_LIBS_BUILD "Is wxWindows build with separate libs?" OFF)
 
     ## HACK: This is very dirty.
diff --git a/Modules/GetPrerequisites.cmake b/Modules/GetPrerequisites.cmake
index 5c8c196..c99c772 100644
--- a/Modules/GetPrerequisites.cmake
+++ b/Modules/GetPrerequisites.cmake
@@ -61,7 +61,7 @@
 exclude "system" prerequisites.  If <recurse> is set to 1 all
 prerequisites will be found recursively, if set to 0 only direct
 prerequisites are listed.  <exepath> is the path to the top level
-executable used for @executable_path replacment on the Mac.  <dirs> is
+executable used for @executable_path replacement on the Mac.  <dirs> is
 a list of paths where libraries might be found: these paths are
 searched first when a target without any path info is given.  Then
 standard system locations are also searched: PATH, Framework
diff --git a/Modules/GoogleTest.cmake b/Modules/GoogleTest.cmake
index b210a77..057b29d 100644
--- a/Modules/GoogleTest.cmake
+++ b/Modules/GoogleTest.cmake
@@ -5,6 +5,8 @@
 GoogleTest
 ----------
 
+.. versionadded:: 3.9
+
 This module defines functions to help use the Google Test infrastructure.  Two
 mechanisms for adding tests are provided. :command:`gtest_add_tests` has been
 around for some time, originally via ``find_package(GTest)``.
@@ -493,7 +495,7 @@
     string(CONCAT ctest_include_content
       "if(EXISTS \"$<TARGET_FILE:${TARGET}>\")"                                    "\n"
       "  if(\"$<TARGET_FILE:${TARGET}>\" IS_NEWER_THAN \"${ctest_tests_file}\")"   "\n"
-      "    include(GoogleTestAddTests)"                                            "\n"
+      "    include(\"${_GOOGLETEST_DISCOVER_TESTS_SCRIPT}\")"                      "\n"
       "    gtest_discover_tests_impl("                                             "\n"
       "      TEST_EXECUTABLE"        " [==[" "$<TARGET_FILE:${TARGET}>"   "]==]"   "\n"
       "      TEST_EXECUTOR"          " [==[" "${crosscompiling_emulator}" "]==]"   "\n"
diff --git a/Modules/Internal/CPack/CPackDeb.cmake b/Modules/Internal/CPack/CPackDeb.cmake
index db35e3a..431b074 100644
--- a/Modules/Internal/CPack/CPackDeb.cmake
+++ b/Modules/Internal/CPack/CPackDeb.cmake
@@ -547,8 +547,8 @@
       message(FATAL_ERROR _description_failure_message)
     endif()
 
-  # Ok, description has set. According to the `Debian Policy Manual`_ the frist
-  # line is a pacakge summary.  Try to get it as well...
+  # Ok, description has set. According to the `Debian Policy Manual`_ the first
+  # line is a package summary.  Try to get it as well...
   # See also: https://www.debian.org/doc/debian-policy/ch-controlfields.html#description
   elseif(CPACK_PACKAGE_DESCRIPTION_SUMMARY AND
          NOT CPACK_PACKAGE_DESCRIPTION_SUMMARY STREQUAL CPACK_DEFAULT_PACKAGE_DESCRIPTION_SUMMARY)
diff --git a/Modules/Platform/Android-Clang.cmake b/Modules/Platform/Android-Clang.cmake
index 759448b..160eada 100644
--- a/Modules/Platform/Android-Clang.cmake
+++ b/Modules/Platform/Android-Clang.cmake
@@ -53,4 +53,7 @@
     endif()
     list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "--target=${CMAKE_${lang}_COMPILER_TARGET}")
   endif()
+  if(CMAKE_GENERATOR MATCHES "Visual Studio")
+    set(_ANDROID_STL_NOSTDLIBXX 1)
+  endif()
 endmacro()
diff --git a/Modules/Platform/Android-Determine.cmake b/Modules/Platform/Android-Determine.cmake
index 2225897..11a0504 100644
--- a/Modules/Platform/Android-Determine.cmake
+++ b/Modules/Platform/Android-Determine.cmake
@@ -7,8 +7,8 @@
 
 # Support for NVIDIA Nsight Tegra Visual Studio Edition was previously
 # implemented in the CMake VS IDE generators.  Avoid interfering with
-# that functionality for now.  Later we may try to integrate this.
-if(CMAKE_GENERATOR MATCHES "Visual Studio")
+# that functionality for now.
+if(CMAKE_GENERATOR_PLATFORM STREQUAL "Tegra-Android")
   return()
 endif()
 
@@ -27,6 +27,63 @@
 cmake_policy(PUSH)
 cmake_policy(SET CMP0057 NEW) # if IN_LIST
 
+# If using Android tools for Visual Studio, compile a sample project to get the
+# sysroot.
+if(CMAKE_GENERATOR MATCHES "Visual Studio")
+  if(NOT CMAKE_SYSROOT)
+    set(vcx_platform ${CMAKE_GENERATOR_PLATFORM})
+    if(CMAKE_GENERATOR MATCHES "Visual Studio 1[45]")
+      set(vcx_sysroot_var "Sysroot")
+    else()
+      set(vcx_sysroot_var "SysrootLink")
+    endif()
+    if(CMAKE_GENERATOR MATCHES "Visual Studio 14")
+      set(vcx_revision "2.0")
+    elseif(CMAKE_GENERATOR MATCHES "Visual Studio 1[56]")
+      set(vcx_revision "3.0")
+    else()
+      set(vcx_revision "")
+    endif()
+    configure_file(${CMAKE_ROOT}/Modules/Platform/Android/VCXProjInspect.vcxproj.in
+      ${CMAKE_PLATFORM_INFO_DIR}/VCXProjInspect.vcxproj @ONLY)
+    execute_process(
+      COMMAND "${CMAKE_VS_MSBUILD_COMMAND}" "VCXProjInspect.vcxproj"
+        "/p:Configuration=Debug" "/p:Platform=${vcx_platform}"
+      WORKING_DIRECTORY ${CMAKE_PLATFORM_INFO_DIR}
+      OUTPUT_VARIABLE VCXPROJ_INSPECT_OUTPUT
+      ERROR_VARIABLE VCXPROJ_INSPECT_OUTPUT
+      RESULT_VARIABLE VCXPROJ_INSPECT_RESULT
+      )
+    if(NOT CMAKE_SYSROOT AND VCXPROJ_INSPECT_OUTPUT MATCHES "CMAKE_SYSROOT=([^%\r\n]+)[\r\n]")
+      # Strip VS diagnostic output from the end of the line.
+      string(REGEX REPLACE " \\(TaskId:[0-9]*\\)$" "" _sysroot "${CMAKE_MATCH_1}")
+      if(EXISTS "${_sysroot}")
+        file(TO_CMAKE_PATH "${_sysroot}" CMAKE_SYSROOT)
+      endif()
+    endif()
+    if(VCXPROJ_INSPECT_RESULT)
+      file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+        "Determining the sysroot for the Android NDK failed.
+The output was:
+${VCXPROJ_INSPECT_RESULT}
+${VCXPROJ_INSPECT_OUTPUT}
+
+")
+    else()
+      file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+        "Determining the sysroot for the Android NDK succeeded.
+The output was:
+${VCXPROJ_INSPECT_RESULT}
+${VCXPROJ_INSPECT_OUTPUT}
+
+")
+    endif()
+  endif()
+  if(NOT CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION)
+    set(CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION "clang")
+  endif()
+endif()
+
 # If the user provided CMAKE_SYSROOT for us, extract information from it.
 set(_ANDROID_SYSROOT_NDK "")
 set(_ANDROID_SYSROOT_API "")
diff --git a/Modules/Platform/Android-Initialize.cmake b/Modules/Platform/Android-Initialize.cmake
index b90dd7a..5019c28 100644
--- a/Modules/Platform/Android-Initialize.cmake
+++ b/Modules/Platform/Android-Initialize.cmake
@@ -6,7 +6,7 @@
 
 # Support for NVIDIA Nsight Tegra Visual Studio Edition was previously
 # implemented in the CMake VS IDE generators.  Avoid interfering with
-# that functionality for now.  Later we may try to integrate this.
+# that functionality for now.
 if(CMAKE_VS_PLATFORM_NAME STREQUAL "Tegra-Android")
   return()
 endif()
diff --git a/Modules/Platform/Android/Determine-Compiler-NDK.cmake b/Modules/Platform/Android/Determine-Compiler-NDK.cmake
index f56e1d5..a4d67c4 100644
--- a/Modules/Platform/Android/Determine-Compiler-NDK.cmake
+++ b/Modules/Platform/Android/Determine-Compiler-NDK.cmake
@@ -184,7 +184,7 @@
       # We just matched the gcc toolchain name without version number.  Save it for later.
       set(_ANDROID_TOOL_NAME_ONLY "${CMAKE_MATCH_1}")
     elseif(line MATCHES [[^TOOLCHAIN_PREFIX +:= +.*/bin/(\$\(TOOLCHAIN_NAME\)-) *$]])
-      # We just matched the toolchain prefix with a name placholder, so substitute it.
+      # We just matched the toolchain prefix with a name placeholder, so substitute it.
       # The gcc toolchain name will have already been extracted without version number from a TOOLCHAIN_NAME line.
       string(REPLACE "$(TOOLCHAIN_NAME)" "${_ANDROID_TOOL_NAME_ONLY}" _ANDROID_TOOL_PREFIX "${CMAKE_MATCH_1}")
     elseif(line MATCHES [[^LLVM_VERSION +:= +([0-9.]+)$]])
diff --git a/Modules/Platform/Android/VCXProjInspect.vcxproj.in b/Modules/Platform/Android/VCXProjInspect.vcxproj.in
new file mode 100644
index 0000000..6919d2c
--- /dev/null
+++ b/Modules/Platform/Android/VCXProjInspect.vcxproj.in
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|@vcx_platform@">
+      <Configuration>Debug</Configuration>
+      <Platform>@vcx_platform@</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{14D44772-ECF7-47BD-9E29-BC62FAF940A5}</ProjectGuid>
+    <RootNamespace>VCXProjInspect</RootNamespace>
+    <Keyword>Android</Keyword>
+    <ApplicationType>Android</ApplicationType>
+    <ApplicationTypeRevision>@vcx_revision@</ApplicationTypeRevision>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|@vcx_platform@'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <PropertyGroup>
+    <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|@vcx_platform@'">false</LinkIncremental>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|@vcx_platform@'">
+    <PostBuildEvent>
+      <Command>%40echo CMAKE_SYSROOT=$(@vcx_sysroot_var@)</Command>
+    </PostBuildEvent>
+  </ItemDefinitionGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
diff --git a/Modules/Platform/Darwin-Initialize.cmake b/Modules/Platform/Darwin-Initialize.cmake
index 80e9a40..d087412 100644
--- a/Modules/Platform/Darwin-Initialize.cmake
+++ b/Modules/Platform/Darwin-Initialize.cmake
@@ -62,45 +62,36 @@
   # Find installed SDKs in either Xcode-4.3+ or pre-4.3 SDKs directory.
   set(_CMAKE_OSX_SDKS_DIR "")
   if(OSX_DEVELOPER_ROOT)
-    foreach(d Platforms/MacOSX.platform/Developer/SDKs SDKs)
-      file(GLOB _CMAKE_OSX_SDKS ${OSX_DEVELOPER_ROOT}/${d}/*)
+    foreach(_d Platforms/MacOSX.platform/Developer/SDKs SDKs)
+      file(GLOB _CMAKE_OSX_SDKS ${OSX_DEVELOPER_ROOT}/${_d}/*)
       if(_CMAKE_OSX_SDKS)
-        set(_CMAKE_OSX_SDKS_DIR ${OSX_DEVELOPER_ROOT}/${d})
+        set(_CMAKE_OSX_SDKS_DIR ${OSX_DEVELOPER_ROOT}/${_d})
         break()
       endif()
     endforeach()
   endif()
 
   if(_CMAKE_OSX_SDKS_DIR)
-    # Select SDK for current OSX version accounting for the known
-    # specially named SDKs.
-    set(_CMAKE_OSX_SDKS_VER_SUFFIX_10.4 "u")
-    set(_CMAKE_OSX_SDKS_VER_SUFFIX_10.3 ".9")
-
-    # find the latest SDK
+    # Find the latest SDK as recommended by Apple (Technical Q&A QA1806)
     set(_CMAKE_OSX_LATEST_SDK_VERSION "0.0")
     file(GLOB _CMAKE_OSX_SDKS RELATIVE "${_CMAKE_OSX_SDKS_DIR}" "${_CMAKE_OSX_SDKS_DIR}/MacOSX*.sdk")
     foreach(_SDK ${_CMAKE_OSX_SDKS})
-      if(_SDK MATCHES "MacOSX([0-9]+\\.[0-9]+)[^/]*\\.sdk" AND CMAKE_MATCH_1 VERSION_GREATER ${_CMAKE_OSX_LATEST_SDK_VERSION})
+      if(IS_DIRECTORY "${_CMAKE_OSX_SDKS_DIR}/${_SDK}"
+         AND _SDK MATCHES "MacOSX([0-9]+\\.[0-9]+)[^/]*\\.sdk"
+         AND CMAKE_MATCH_1 VERSION_GREATER ${_CMAKE_OSX_LATEST_SDK_VERSION})
         set(_CMAKE_OSX_LATEST_SDK_VERSION "${CMAKE_MATCH_1}")
       endif()
     endforeach()
 
-    # pick an SDK that works
-    set(_CMAKE_OSX_SYSROOT_DEFAULT)
-    foreach(ver ${CMAKE_OSX_DEPLOYMENT_TARGET}
-                ${_CURRENT_OSX_VERSION}
-                ${_CMAKE_OSX_LATEST_SDK_VERSION})
-      set(_CMAKE_OSX_DEPLOYMENT_TARGET ${ver})
-      set(_CMAKE_OSX_SDKS_VER ${_CMAKE_OSX_DEPLOYMENT_TARGET}${_CMAKE_OSX_SDKS_VER_SUFFIX_${_CMAKE_OSX_DEPLOYMENT_TARGET}})
-      set(_CMAKE_OSX_SYSROOT_CHECK "${_CMAKE_OSX_SDKS_DIR}/MacOSX${_CMAKE_OSX_SDKS_VER}.sdk")
-      if(IS_DIRECTORY "${_CMAKE_OSX_SYSROOT_CHECK}")
-        set(_CMAKE_OSX_SYSROOT_DEFAULT "${_CMAKE_OSX_SYSROOT_CHECK}")
-        break()
-      endif()
-    endforeach()
+    if(NOT _CMAKE_OSX_LATEST_SDK_VERSION STREQUAL "0.0")
+      set(_CMAKE_OSX_SYSROOT_DEFAULT "${_CMAKE_OSX_SDKS_DIR}/MacOSX${_CMAKE_OSX_LATEST_SDK_VERSION}.sdk")
+    else()
+      message(WARNING "Could not find any valid SDKs in ${_CMAKE_OSX_SDKS_DIR}")
+    endif()
 
-    if(NOT CMAKE_CROSSCOMPILING AND NOT CMAKE_OSX_DEPLOYMENT_TARGET AND _CURRENT_OSX_VERSION VERSION_LESS _CMAKE_OSX_DEPLOYMENT_TARGET)
+    if(NOT CMAKE_CROSSCOMPILING AND NOT CMAKE_OSX_DEPLOYMENT_TARGET
+       AND (_CURRENT_OSX_VERSION VERSION_LESS _CMAKE_OSX_LATEST_SDK_VERSION
+            OR _CMAKE_OSX_LATEST_SDK_VERSION STREQUAL "0.0"))
       set(CMAKE_OSX_DEPLOYMENT_TARGET ${_CURRENT_OSX_VERSION} CACHE STRING
         "Minimum OS X version to target for deployment (at runtime); newer APIs weak linked. Set to empty string for default value." FORCE)
     endif()
@@ -113,8 +104,8 @@
 # Set cache variable - end user may change this during ccmake or cmake-gui configure.
 # Choose the type based on the current value.
 set(_CMAKE_OSX_SYSROOT_TYPE STRING)
-foreach(v CMAKE_OSX_SYSROOT _CMAKE_OSX_SYSROOT_DEFAULT)
-  if("x${${v}}" MATCHES "/")
+foreach(_v CMAKE_OSX_SYSROOT _CMAKE_OSX_SYSROOT_DEFAULT)
+  if("x${${_v}}" MATCHES "/")
     set(_CMAKE_OSX_SYSROOT_TYPE PATH)
     break()
   endif()
diff --git a/Modules/Platform/HP-UX.cmake b/Modules/Platform/HP-UX.cmake
index 9572a7e..425a13f 100644
--- a/Modules/Platform/HP-UX.cmake
+++ b/Modules/Platform/HP-UX.cmake
@@ -22,7 +22,7 @@
 # set flags for gcc support
 include(Platform/UnixPaths)
 
-# Look in both 32-bit and 64-bit implict link directories, but tell
+# Look in both 32-bit and 64-bit implicit link directories, but tell
 # CMake not to pass the paths to the linker.  The linker will find the
 # library for the proper architecture.  In the future we should detect
 # which path will be used by the linker.  Since the pointer type size
diff --git a/Modules/Platform/Windows-Clang.cmake b/Modules/Platform/Windows-Clang.cmake
index dff8166..05dff9d 100644
--- a/Modules/Platform/Windows-Clang.cmake
+++ b/Modules/Platform/Windows-Clang.cmake
@@ -142,7 +142,7 @@
       endif()
       if(DEFINED CMAKE_RC_PREPROCESSOR)
         set(CMAKE_DEPFILE_FLAGS_RC "-clang:-MD -clang:-MF -clang:<DEPFILE>")
-        set(CMAKE_RC_COMPILE_OBJECT "${CMAKE_COMMAND} -E cmake_llvm_rc <SOURCE> <OBJECT>.pp <${CMAKE_RC_PREPROCESSOR}> <DEFINES> -DRC_INVOKED <INCLUDES> <FLAGS> -E <SOURCE> -- <CMAKE_RC_COMPILER> <DEFINES> -I <SOURCE_DIR> <INCLUDES> /fo <OBJECT> <OBJECT>.pp")
+        set(CMAKE_RC_COMPILE_OBJECT "${CMAKE_COMMAND} -E cmake_llvm_rc <SOURCE> <OBJECT>.pp <${CMAKE_RC_PREPROCESSOR}> <DEFINES> -DRC_INVOKED <INCLUDES> <FLAGS> -E -- <SOURCE> ++ <CMAKE_RC_COMPILER> <DEFINES> -I <SOURCE_DIR> <INCLUDES> /fo <OBJECT> <OBJECT>.pp")
         if(CMAKE_GENERATOR STREQUAL "Ninja")
           set(CMAKE_NINJA_CMCLDEPS_RC 0)
           set(CMAKE_NINJA_DEP_TYPE_RC gcc)
diff --git a/Modules/Platform/Windows-MSVC.cmake b/Modules/Platform/Windows-MSVC.cmake
index 2476a33..173ef40 100644
--- a/Modules/Platform/Windows-MSVC.cmake
+++ b/Modules/Platform/Windows-MSVC.cmake
@@ -333,6 +333,14 @@
   set(CMAKE_LINK_PCH ON)
   if (CMAKE_${lang}_COMPILER_ID STREQUAL "Clang")
     set(CMAKE_PCH_PROLOGUE "#pragma clang system_header")
+
+    # macOS paths usually start with /Users/*. Unfortunately, clang-cl interprets
+    # paths starting with /U as macro undefines, so we need to put a -- before the
+    # input file path to force it to be treated as a path.
+    string(REPLACE "-c <SOURCE>" "-c -- <SOURCE>" CMAKE_${lang}_COMPILE_OBJECT "${CMAKE_${lang}_COMPILE_OBJECT}")
+    string(REPLACE "-c <SOURCE>" "-c -- <SOURCE>" CMAKE_${lang}_CREATE_PREPROCESSED_SOURCE "${CMAKE_${lang}_COMPILE_OBJECT}")
+    string(REPLACE "-c <SOURCE>" "-c -- <SOURCE>" CMAKE_${lang}_CREATE_ASSEMBLY_SOURCE "${CMAKE_${lang}_COMPILE_OBJECT}")
+
   elseif(MSVC_VERSION GREATER_EQUAL 1913)
     # At least MSVC toolet 14.13 from VS 2017 15.6
     set(CMAKE_PCH_PROLOGUE "#pragma system_header")
@@ -356,6 +364,11 @@
     set(_CMAKE_${lang}_IPO_SUPPORTED_BY_CMAKE YES)
     set(_CMAKE_${lang}_IPO_MAY_BE_SUPPORTED_BY_COMPILER YES)
 
+    if(CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 3.4.0)
+      set(CMAKE_${lang}_COMPILE_OPTIONS_TARGET "-target ")
+    else()
+      set(CMAKE_${lang}_COMPILE_OPTIONS_TARGET "--target=")
+    endif()
     # '-flto=thin' available since Clang 3.9 and Xcode 8
     # * http://clang.llvm.org/docs/ThinLTO.html#clang-llvm
     # * https://trac.macports.org/wiki/XcodeVersionInfo
diff --git a/Modules/UseSWIG.cmake b/Modules/UseSWIG.cmake
index a60e05e..b75eb5e 100644
--- a/Modules/UseSWIG.cmake
+++ b/Modules/UseSWIG.cmake
@@ -83,7 +83,7 @@
   ``SOURCES``
     List of sources for the library. Files with extension ``.i`` will be
     identified as sources for the ``SWIG`` tool. Other files will be handled in
-    the standard way. This behavior can be overriden by specifying the variable
+    the standard way. This behavior can be overridden by specifying the variable
     ``SWIG_SOURCE_FILE_EXTENSIONS``.
 
   .. note::
diff --git a/Modules/UseSWIG/ManageSupportFiles.cmake b/Modules/UseSWIG/ManageSupportFiles.cmake
index 4a03900..6618fd5 100644
--- a/Modules/UseSWIG/ManageSupportFiles.cmake
+++ b/Modules/UseSWIG/ManageSupportFiles.cmake
@@ -4,7 +4,7 @@
 
 if (ACTION STREQUAL "CLEAN")
   # Collect current list of generated files
-  file (GLOB files LIST_DIRECTORIES FALSE RELATIVE "${SUPPORT_FILES_WORKING_DIRECTORY}" "${SUPPORT_FILES_WORKING_DIRECTORY}/*")
+  file (GLOB_RECURSE files LIST_DIRECTORIES TRUE RELATIVE "${SUPPORT_FILES_WORKING_DIRECTORY}" "${SUPPORT_FILES_WORKING_DIRECTORY}/*")
 
   if (files)
     # clean-up the output directory
@@ -22,7 +22,7 @@
 
 if (ACTION STREQUAL "COPY")
   # Collect current list of generated files
-  file (GLOB files LIST_DIRECTORIES FALSE "${SUPPORT_FILES_WORKING_DIRECTORY}/*")
+  file (GLOB files LIST_DIRECTORIES TRUE "${SUPPORT_FILES_WORKING_DIRECTORY}/*")
 
   if (files)
     # copy files to the output directory
diff --git a/Modules/WriteCompilerDetectionHeader.cmake b/Modules/WriteCompilerDetectionHeader.cmake
index 23d81b5..5100035 100644
--- a/Modules/WriteCompilerDetectionHeader.cmake
+++ b/Modules/WriteCompilerDetectionHeader.cmake
@@ -5,6 +5,8 @@
 WriteCompilerDetectionHeader
 ----------------------------
 
+.. versionadded:: 3.1
+
 This module provides the function ``write_compiler_detection_header()``.
 
 This function can be used to generate a file suitable for preprocessor
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index 1b6bb00..ee8767f 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -412,6 +412,8 @@
   cmSourceFileLocationKind.h
   cmSourceGroup.cxx
   cmSourceGroup.h
+  cmStandardLevelResolver.cxx
+  cmStandardLevelResolver.h
   cmState.cxx
   cmState.h
   cmStateDirectory.cxx
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index cdadbe7..c82a659 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,7 +1,7 @@
 # CMake version number components.
 set(CMake_VERSION_MAJOR 3)
 set(CMake_VERSION_MINOR 18)
-set(CMake_VERSION_PATCH 1)
+set(CMake_VERSION_PATCH 20200811)
 #set(CMake_VERSION_RC 0)
 set(CMake_VERSION_IS_DIRTY 0)
 
diff --git a/Source/CPack/cmCPackDebGenerator.cxx b/Source/CPack/cmCPackDebGenerator.cxx
index 3d5fe6b..560e5c1 100644
--- a/Source/CPack/cmCPackDebGenerator.cxx
+++ b/Source/CPack/cmCPackDebGenerator.cxx
@@ -696,57 +696,57 @@
 
   const char* debian_pkg_source =
     this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_SOURCE");
-  if (debian_pkg_source && *debian_pkg_source) {
+  if (cmNonempty(debian_pkg_source)) {
     controlValues["Source"] = debian_pkg_source;
   }
   const char* debian_pkg_dep =
     this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_DEPENDS");
-  if (debian_pkg_dep && *debian_pkg_dep) {
+  if (cmNonempty(debian_pkg_dep)) {
     controlValues["Depends"] = debian_pkg_dep;
   }
   const char* debian_pkg_rec =
     this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_RECOMMENDS");
-  if (debian_pkg_rec && *debian_pkg_rec) {
+  if (cmNonempty(debian_pkg_rec)) {
     controlValues["Recommends"] = debian_pkg_rec;
   }
   const char* debian_pkg_sug =
     this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_SUGGESTS");
-  if (debian_pkg_sug && *debian_pkg_sug) {
+  if (cmNonempty(debian_pkg_sug)) {
     controlValues["Suggests"] = debian_pkg_sug;
   }
   const char* debian_pkg_url =
     this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_HOMEPAGE");
-  if (debian_pkg_url && *debian_pkg_url) {
+  if (cmNonempty(debian_pkg_url)) {
     controlValues["Homepage"] = debian_pkg_url;
   }
   const char* debian_pkg_predep =
     this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_PREDEPENDS");
-  if (debian_pkg_predep && *debian_pkg_predep) {
+  if (cmNonempty(debian_pkg_predep)) {
     controlValues["Pre-Depends"] = debian_pkg_predep;
   }
   const char* debian_pkg_enhances =
     this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_ENHANCES");
-  if (debian_pkg_enhances && *debian_pkg_enhances) {
+  if (cmNonempty(debian_pkg_enhances)) {
     controlValues["Enhances"] = debian_pkg_enhances;
   }
   const char* debian_pkg_breaks =
     this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_BREAKS");
-  if (debian_pkg_breaks && *debian_pkg_breaks) {
+  if (cmNonempty(debian_pkg_breaks)) {
     controlValues["Breaks"] = debian_pkg_breaks;
   }
   const char* debian_pkg_conflicts =
     this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_CONFLICTS");
-  if (debian_pkg_conflicts && *debian_pkg_conflicts) {
+  if (cmNonempty(debian_pkg_conflicts)) {
     controlValues["Conflicts"] = debian_pkg_conflicts;
   }
   const char* debian_pkg_provides =
     this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_PROVIDES");
-  if (debian_pkg_provides && *debian_pkg_provides) {
+  if (cmNonempty(debian_pkg_provides)) {
     controlValues["Provides"] = debian_pkg_provides;
   }
   const char* debian_pkg_replaces =
     this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_REPLACES");
-  if (debian_pkg_replaces && *debian_pkg_replaces) {
+  if (cmNonempty(debian_pkg_replaces)) {
     controlValues["Replaces"] = debian_pkg_replaces;
   }
 
@@ -756,7 +756,7 @@
   const char* debian_pkg_shlibs =
     this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_SHLIBS");
   const bool gen_shibs = this->IsOn("CPACK_DEBIAN_PACKAGE_GENERATE_SHLIBS") &&
-    debian_pkg_shlibs && *debian_pkg_shlibs;
+    cmNonempty(debian_pkg_shlibs);
   if (gen_shibs) {
     cmGeneratedFileStream out;
     out.Open(shlibsfilename, false, true);
@@ -832,11 +832,11 @@
 
   const char* debian_pkg_source =
     this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_SOURCE");
-  if (debian_pkg_source && *debian_pkg_source) {
+  if (cmNonempty(debian_pkg_source)) {
     controlValues["Source"] = debian_pkg_source;
   }
   const char* debian_build_ids = this->GetOption("GEN_BUILD_IDS");
-  if (debian_build_ids && *debian_build_ids) {
+  if (cmNonempty(debian_build_ids)) {
     controlValues["Build-Ids"] = debian_build_ids;
   }
 
diff --git a/Source/CPack/cmCPackDragNDropGenerator.cxx b/Source/CPack/cmCPackDragNDropGenerator.cxx
index fe7abf4..cefb906 100644
--- a/Source/CPack/cmCPackDragNDropGenerator.cxx
+++ b/Source/CPack/cmCPackDragNDropGenerator.cxx
@@ -8,7 +8,9 @@
 #include <map>
 
 #include <CoreFoundation/CoreFoundation.h>
+#include <cm3p/kwiml/abi.h>
 
+#include "cmsys/Base64.h"
 #include "cmsys/FStream.hxx"
 #include "cmsys/RegularExpression.hxx"
 
@@ -18,6 +20,7 @@
 #include "cmGeneratedFileStream.h"
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
+#include "cmXMLWriter.h"
 
 #ifdef HAVE_CoreServices
 // For the old LocaleStringToLangAndRegionCodes() function, to convert
@@ -26,36 +29,28 @@
 #  include <CoreServices/CoreServices.h>
 #endif
 
-static const char* SLAHeader =
-  "data 'LPic' (5000) {\n"
-  "    $\"0002 0011 0003 0001 0000 0000 0002 0000\"\n"
-  "    $\"0008 0003 0000 0001 0004 0000 0004 0005\"\n"
-  "    $\"0000 000E 0006 0001 0005 0007 0000 0007\"\n"
-  "    $\"0008 0000 0047 0009 0000 0034 000A 0001\"\n"
-  "    $\"0035 000B 0001 0020 000C 0000 0011 000D\"\n"
-  "    $\"0000 005B 0004 0000 0033 000F 0001 000C\"\n"
-  "    $\"0010 0000 000B 000E 0000\"\n"
-  "};\n"
-  "\n";
+static const uint16_t DefaultLpic[] = {
+  /* clang-format off */
+  0x0002, 0x0011, 0x0003, 0x0001, 0x0000, 0x0000, 0x0002, 0x0000,
+  0x0008, 0x0003, 0x0000, 0x0001, 0x0004, 0x0000, 0x0004, 0x0005,
+  0x0000, 0x000E, 0x0006, 0x0001, 0x0005, 0x0007, 0x0000, 0x0007,
+  0x0008, 0x0000, 0x0047, 0x0009, 0x0000, 0x0034, 0x000A, 0x0001,
+  0x0035, 0x000B, 0x0001, 0x0020, 0x000C, 0x0000, 0x0011, 0x000D,
+  0x0000, 0x005B, 0x0004, 0x0000, 0x0033, 0x000F, 0x0001, 0x000C,
+  0x0010, 0x0000, 0x000B, 0x000E, 0x0000
+  /* clang-format on */
+};
 
-static const char* SLASTREnglish =
-  "resource 'STR#' (5002, \"English\") {\n"
-  "    {\n"
-  "        \"English\",\n"
-  "        \"Agree\",\n"
-  "        \"Disagree\",\n"
-  "        \"Print\",\n"
-  "        \"Save...\",\n"
-  "        \"You agree to the License Agreement terms when you click \"\n"
-  "        \"the \\\"Agree\\\" button.\",\n"
-  "        \"Software License Agreement\",\n"
-  "        \"This text cannot be saved.  This disk may be full or locked, "
-  "or the \"\n"
-  "        \"file may be locked.\",\n"
-  "        \"Unable to print.  Make sure you have selected a printer.\"\n"
-  "    }\n"
-  "};\n"
-  "\n";
+static const std::vector<std::string> DefaultMenu = {
+  { "English", "Agree", "Disagree", "Print", "Save...",
+    // NOLINTNEXTLINE(bugprone-suspicious-missing-comma)
+    "You agree to the License Agreement terms when "
+    "you click the \"Agree\" button.",
+    "Software License Agreement",
+    "This text cannot be saved.  "
+    "This disk may be full or locked, or the file may be locked.",
+    "Unable to print.  Make sure you have selected a printer." }
+};
 
 cmCPackDragNDropGenerator::cmCPackDragNDropGenerator()
   : singleLicense(false)
@@ -523,22 +518,43 @@
     }
   }
 
+  // Create the final compressed read-only disk image ...
+  std::ostringstream final_image_command;
+  final_image_command << this->GetOption("CPACK_COMMAND_HDIUTIL");
+  final_image_command << " convert \"" << temp_image << "\"";
+  final_image_command << " -format ";
+  final_image_command << cpack_dmg_format;
+  final_image_command << " -imagekey";
+  final_image_command << " zlib-level=9";
+  final_image_command << " -o \"" << output_file << "\"";
+
+  std::string convert_error;
+
+  if (!this->RunCommand(final_image_command, &convert_error)) {
+    cmCPackLogger(cmCPackLog::LOG_ERROR,
+                  "Error compressing disk image." << std::endl
+                                                  << convert_error
+                                                  << std::endl);
+
+    return 0;
+  }
+
   if (!cpack_license_file.empty() || !slaDirectory.empty()) {
     // Use old hardcoded style if sla_dir is not set
     bool oldStyle = slaDirectory.empty();
-    std::string sla_r =
-      cmStrCat(this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), "/sla.r");
+    std::string sla_xml =
+      cmStrCat(this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), "/sla.xml");
 
     std::vector<std::string> languages;
     if (!oldStyle) {
       cmExpandList(cpack_dmg_languages, languages);
     }
 
-    cmGeneratedFileStream ofs(sla_r);
-    ofs << "#include <CoreServices/CoreServices.r>\n\n";
+    std::vector<uint16_t> header_data;
     if (oldStyle) {
-      ofs << SLAHeader;
-      ofs << "\n";
+      header_data = std::vector<uint16_t>(
+        DefaultLpic,
+        DefaultLpic + (sizeof(DefaultLpic) / sizeof(*DefaultLpic)));
     } else {
       /*
        * LPic Layout
@@ -558,8 +574,6 @@
        * }
        */
 
-      // Create vector first for readability, then iterate to write to ofs
-      std::vector<uint16_t> header_data;
       header_data.push_back(0);
       header_data.push_back(languages.size());
       for (size_t i = 0; i < languages.size(); ++i) {
@@ -596,52 +610,50 @@
         header_data.push_back(0);
 #endif
       }
-      ofs << "data 'LPic' (5000) {\n";
-      ofs << std::hex << std::uppercase << std::setfill('0');
+    }
 
-      for (size_t i = 0; i < header_data.size(); ++i) {
-        if (i % 8 == 0) {
-          ofs << "    $\"";
-        }
+    RezDoc rez;
 
-        ofs << std::setw(4) << header_data[i];
-
-        if (i % 8 == 7 || i == header_data.size() - 1) {
-          ofs << "\"\n";
-        } else {
-          ofs << " ";
-        }
+    {
+      RezDict lpic = { {}, 5000, {} };
+      lpic.Data.reserve(header_data.size() * sizeof(header_data[0]));
+      for (uint16_t x : header_data) {
+        // LPic header is big-endian.
+        char* d = reinterpret_cast<char*>(&x);
+#if KWIML_ABI_ENDIAN_ID == KWIML_ABI_ENDIAN_ID_LITTLE
+        lpic.Data.push_back(d[1]);
+        lpic.Data.push_back(d[0]);
+#else
+        lpic.Data.push_back(d[0]);
+        lpic.Data.push_back(d[1]);
+#endif
       }
-      ofs << "};\n\n";
-      // Reset ofs options
-      ofs << std::dec << std::nouppercase << std::setfill(' ');
+      rez.LPic.Entries.emplace_back(std::move(lpic));
     }
 
     bool have_write_license_error = false;
     std::string error;
 
     if (oldStyle) {
-      if (!this->WriteLicense(ofs, 0, "", cpack_license_file, &error)) {
+      if (!this->WriteLicense(rez, 0, "", cpack_license_file, &error)) {
         have_write_license_error = true;
       }
     } else {
       for (size_t i = 0; i < languages.size() && !have_write_license_error;
            ++i) {
         if (singleLicense) {
-          if (!this->WriteLicense(ofs, i + 5000, languages[i],
+          if (!this->WriteLicense(rez, i + 5000, languages[i],
                                   cpack_license_file, &error)) {
             have_write_license_error = true;
           }
         } else {
-          if (!this->WriteLicense(ofs, i + 5000, languages[i], "", &error)) {
+          if (!this->WriteLicense(rez, i + 5000, languages[i], "", &error)) {
             have_write_license_error = true;
           }
         }
       }
     }
 
-    ofs.Close();
-
     if (have_write_license_error) {
       cmCPackLogger(cmCPackLog::LOG_ERROR,
                     "Error writing license file to SLA." << std::endl
@@ -650,94 +662,25 @@
       return 0;
     }
 
-    if (temp_image_format != "UDZO") {
-      temp_image_format = "UDZO";
-      // convert to UDZO to enable unflatten/flatten
-      std::string temp_udzo = cmStrCat(
-        this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), "/temp-udzo.dmg");
+    this->WriteRezXML(sla_xml, rez);
 
-      std::ostringstream udco_image_command;
-      udco_image_command << this->GetOption("CPACK_COMMAND_HDIUTIL");
-      udco_image_command << " convert \"" << temp_image << "\"";
-      udco_image_command << " -format UDZO";
-      udco_image_command << " -ov -o \"" << temp_udzo << "\"";
-
-      if (!this->RunCommand(udco_image_command, &error)) {
-        cmCPackLogger(cmCPackLog::LOG_ERROR,
-                      "Error converting to UDCO dmg for adding SLA."
-                        << std::endl
-                        << error << std::endl);
-        return 0;
-      }
-      temp_image = temp_udzo;
-    }
-
-    // unflatten dmg
-    std::ostringstream unflatten_command;
-    unflatten_command << this->GetOption("CPACK_COMMAND_HDIUTIL");
-    unflatten_command << " unflatten ";
-    unflatten_command << "\"" << temp_image << "\"";
-
-    if (!this->RunCommand(unflatten_command, &error)) {
-      cmCPackLogger(cmCPackLog::LOG_ERROR,
-                    "Error unflattening dmg for adding SLA." << std::endl
-                                                             << error
-                                                             << std::endl);
-      return 0;
-    }
-
-    // Rez the SLA
+    // Create the final compressed read-only disk image ...
     std::ostringstream embed_sla_command;
-    embed_sla_command << this->GetOption("CPACK_COMMAND_REZ");
-    const char* sysroot = this->GetOption("CPACK_OSX_SYSROOT");
-    if (sysroot && sysroot[0] != '\0') {
-      embed_sla_command << " -isysroot \"" << sysroot << "\"";
-    }
-    embed_sla_command << " \"" << sla_r << "\"";
-    embed_sla_command << " -a -o ";
-    embed_sla_command << "\"" << temp_image << "\"";
-
-    if (!this->RunCommand(embed_sla_command, &error)) {
+    embed_sla_command << this->GetOption("CPACK_COMMAND_HDIUTIL");
+    embed_sla_command << " udifrez";
+    embed_sla_command << " -xml";
+    embed_sla_command << " \"" << sla_xml << "\"";
+    embed_sla_command << " FIXME_WHY_IS_THIS_ARGUMENT_NEEDED";
+    embed_sla_command << " \"" << output_file << "\"";
+    std::string embed_error;
+    if (!this->RunCommand(embed_sla_command, &embed_error)) {
       cmCPackLogger(cmCPackLog::LOG_ERROR,
-                    "Error adding SLA." << std::endl
-                                        << error << std::endl);
+                    "Error compressing disk image." << std::endl
+                                                    << embed_error
+                                                    << std::endl);
+
       return 0;
     }
-
-    // flatten dmg
-    std::ostringstream flatten_command;
-    flatten_command << this->GetOption("CPACK_COMMAND_HDIUTIL");
-    flatten_command << " flatten ";
-    flatten_command << "\"" << temp_image << "\"";
-
-    if (!this->RunCommand(flatten_command, &error)) {
-      cmCPackLogger(cmCPackLog::LOG_ERROR,
-                    "Error flattening dmg for adding SLA." << std::endl
-                                                           << error
-                                                           << std::endl);
-      return 0;
-    }
-  }
-
-  // Create the final compressed read-only disk image ...
-  std::ostringstream final_image_command;
-  final_image_command << this->GetOption("CPACK_COMMAND_HDIUTIL");
-  final_image_command << " convert \"" << temp_image << "\"";
-  final_image_command << " -format ";
-  final_image_command << cpack_dmg_format;
-  final_image_command << " -imagekey";
-  final_image_command << " zlib-level=9";
-  final_image_command << " -o \"" << output_file << "\"";
-
-  std::string convert_error;
-
-  if (!this->RunCommand(final_image_command, &convert_error)) {
-    cmCPackLogger(cmCPackLog::LOG_ERROR,
-                  "Error compressing disk image." << std::endl
-                                                  << convert_error
-                                                  << std::endl);
-
-    return 0;
   }
 
   return 1;
@@ -788,10 +731,67 @@
   return GetComponentPackageFileName(package_file_name, componentName, false);
 }
 
-bool cmCPackDragNDropGenerator::WriteLicense(
-  cmGeneratedFileStream& outputStream, int licenseNumber,
-  std::string licenseLanguage, const std::string& licenseFile,
-  std::string* error)
+void cmCPackDragNDropGenerator::WriteRezXML(std::string const& file,
+                                            RezDoc const& rez)
+{
+  cmGeneratedFileStream fxml(file);
+  cmXMLWriter xml(fxml);
+  xml.StartDocument();
+  xml.StartElement("plist");
+  xml.Attribute("version", "1.0");
+  xml.StartElement("dict");
+  this->WriteRezArray(xml, rez.LPic);
+  this->WriteRezArray(xml, rez.Menu);
+  this->WriteRezArray(xml, rez.Text);
+  this->WriteRezArray(xml, rez.RTF);
+  xml.EndElement(); // dict
+  xml.EndElement(); // plist
+  xml.EndDocument();
+  fxml.Close();
+}
+
+void cmCPackDragNDropGenerator::WriteRezArray(cmXMLWriter& xml,
+                                              RezArray const& array)
+{
+  if (array.Entries.empty()) {
+    return;
+  }
+  xml.StartElement("key");
+  xml.Content(array.Key);
+  xml.EndElement(); // key
+  xml.StartElement("array");
+  for (RezDict const& dict : array.Entries) {
+    this->WriteRezDict(xml, dict);
+  }
+  xml.EndElement(); // array
+}
+
+void cmCPackDragNDropGenerator::WriteRezDict(cmXMLWriter& xml,
+                                             RezDict const& dict)
+{
+  std::vector<char> base64buf(dict.Data.size() * 3 / 2 + 5);
+  size_t base64len =
+    cmsysBase64_Encode(dict.Data.data(), dict.Data.size(),
+                       reinterpret_cast<unsigned char*>(base64buf.data()), 0);
+  std::string base64data(base64buf.data(), base64len);
+  /* clang-format off */
+  xml.StartElement("dict");
+  xml.StartElement("key");    xml.Content("Attributes"); xml.EndElement();
+  xml.StartElement("string"); xml.Content("0x0000");     xml.EndElement();
+  xml.StartElement("key");    xml.Content("Data");       xml.EndElement();
+  xml.StartElement("data");   xml.Content(base64data);   xml.EndElement();
+  xml.StartElement("key");    xml.Content("ID");         xml.EndElement();
+  xml.StartElement("string"); xml.Content(dict.ID);      xml.EndElement();
+  xml.StartElement("key");    xml.Content("Name");       xml.EndElement();
+  xml.StartElement("string"); xml.Content(dict.Name);    xml.EndElement();
+  xml.EndElement(); // dict
+  /* clang-format on */
+}
+
+bool cmCPackDragNDropGenerator::WriteLicense(RezDoc& rez, size_t licenseNumber,
+                                             std::string licenseLanguage,
+                                             const std::string& licenseFile,
+                                             std::string* error)
 {
   if (!licenseFile.empty() && !singleLicense) {
     licenseNumber = 5002;
@@ -799,11 +799,11 @@
   }
 
   // License file
-  std::string license_format = "TEXT";
+  RezArray* licenseArray = &rez.Text;
   std::string actual_license;
   if (!licenseFile.empty()) {
     if (cmHasLiteralSuffix(licenseFile, ".rtf")) {
-      license_format = "RTF ";
+      licenseArray = &rez.RTF;
     }
     actual_license = licenseFile;
   } else {
@@ -812,93 +812,94 @@
     if (cmSystemTools::FileExists(license_wo_ext + ".txt")) {
       actual_license = license_wo_ext + ".txt";
     } else {
-      license_format = "RTF ";
+      licenseArray = &rez.RTF;
       actual_license = license_wo_ext + ".rtf";
     }
   }
 
-  // License header
-  outputStream << "data '" << license_format << "' (" << licenseNumber
-               << ", \"" << licenseLanguage << "\") {\n";
   // License body
-  cmsys::ifstream license_ifs;
-  license_ifs.open(actual_license.c_str());
-  if (license_ifs.is_open()) {
-    while (license_ifs.good()) {
-      std::string line;
-      std::getline(license_ifs, line);
-      if (!line.empty()) {
-        EscapeQuotesAndBackslashes(line);
-        std::vector<std::string> lines;
-        if (!this->BreakLongLine(line, lines, error)) {
-          return false;
-        }
-        for (auto const& l : lines) {
-          outputStream << "        \"" << l << "\"\n";
-        }
-      }
-      outputStream << "        \"\\n\"\n";
+  {
+    RezDict license = { licenseLanguage, licenseNumber, {} };
+    std::vector<std::string> lines;
+    if (!this->ReadFile(actual_license, lines, error)) {
+      return false;
     }
-    license_ifs.close();
+    this->EncodeLicense(license, lines);
+    licenseArray->Entries.emplace_back(std::move(license));
   }
 
-  // End of License
-  outputStream << "};\n\n";
-  if (!licenseFile.empty() && !singleLicense) {
-    outputStream << SLASTREnglish;
-  } else {
-    // Menu header
-    outputStream << "resource 'STR#' (" << licenseNumber << ", \""
-                 << licenseLanguage << "\") {\n";
-    outputStream << "    {\n";
-
-    // Menu body
-    cmsys::ifstream menu_ifs;
-    menu_ifs.open(
-      (slaDirectory + "/" + licenseLanguage + ".menu.txt").c_str());
-    if (menu_ifs.is_open()) {
-      size_t lines_written = 0;
-      while (menu_ifs.good()) {
-        // Lines written from original file, not from broken up lines
-        std::string line;
-        std::getline(menu_ifs, line);
-        if (!line.empty()) {
-          EscapeQuotesAndBackslashes(line);
-          std::vector<std::string> lines;
-          if (!this->BreakLongLine(line, lines, error)) {
-            return false;
-          }
-          for (size_t i = 0; i < lines.size(); ++i) {
-            std::string comma;
-            // We need a comma after every complete string,
-            // but not on the very last line
-            if (lines_written != 8 && i == lines.size() - 1) {
-              comma = ",";
-            } else {
-              comma = "";
-            }
-            outputStream << "        \"" << lines[i] << "\"" << comma << "\n";
-          }
-          ++lines_written;
-        }
+  // Menu body
+  {
+    RezDict menu = { licenseLanguage, licenseNumber, {} };
+    if (!licenseFile.empty() && !singleLicense) {
+      this->EncodeMenu(menu, DefaultMenu);
+    } else {
+      std::vector<std::string> lines;
+      std::string actual_menu =
+        slaDirectory + "/" + licenseLanguage + ".menu.txt";
+      if (!this->ReadFile(actual_menu, lines, error)) {
+        return false;
       }
-      menu_ifs.close();
+      this->EncodeMenu(menu, lines);
     }
-
-    // End of menu
-    outputStream << "    }\n";
-    outputStream << "};\n";
-    outputStream << "\n";
+    rez.Menu.Entries.emplace_back(std::move(menu));
   }
 
   return true;
 }
 
+void cmCPackDragNDropGenerator::EncodeLicense(
+  RezDict& dict, std::vector<std::string> const& lines)
+{
+  // License text uses CR newlines.
+  for (std::string const& l : lines) {
+    dict.Data.insert(dict.Data.end(), l.begin(), l.end());
+    dict.Data.push_back('\r');
+  }
+  dict.Data.push_back('\r');
+}
+
+void cmCPackDragNDropGenerator::EncodeMenu(
+  RezDict& dict, std::vector<std::string> const& lines)
+{
+  // Menu resources start with a big-endian uint16_t for number of lines:
+  {
+    uint16_t numLines = static_cast<uint16_t>(lines.size());
+    char* d = reinterpret_cast<char*>(&numLines);
+#if KWIML_ABI_ENDIAN_ID == KWIML_ABI_ENDIAN_ID_LITTLE
+    dict.Data.push_back(d[1]);
+    dict.Data.push_back(d[0]);
+#else
+    dict.Data.push_back(d[0]);
+    dict.Data.push_back(d[1]);
+#endif
+  }
+  // Each line starts with a uint8_t length, plus the bytes themselves:
+  for (std::string const& l : lines) {
+    dict.Data.push_back(static_cast<unsigned char>(l.length()));
+    dict.Data.insert(dict.Data.end(), l.begin(), l.end());
+  }
+}
+
+bool cmCPackDragNDropGenerator::ReadFile(std::string const& file,
+                                         std::vector<std::string>& lines,
+                                         std::string* error)
+{
+  cmsys::ifstream ifs(file);
+  std::string line;
+  while (std::getline(ifs, line)) {
+    if (!this->BreakLongLine(line, lines, error)) {
+      return false;
+    }
+  }
+  return true;
+}
+
 bool cmCPackDragNDropGenerator::BreakLongLine(const std::string& line,
                                               std::vector<std::string>& lines,
                                               std::string* error)
 {
-  const size_t max_line_length = 512;
+  const size_t max_line_length = 255;
   size_t line_length = max_line_length;
   for (size_t i = 0; i < line.size(); i += line_length) {
     line_length = max_line_length;
@@ -913,25 +914,10 @@
     if (line_length == 0) {
       *error = "Please make sure there are no words "
                "(or character sequences not broken up by spaces or newlines) "
-               "in your license file which are more than 512 characters long.";
+               "in your license file which are more than 255 characters long.";
       return false;
     }
     lines.push_back(line.substr(i, line_length));
   }
   return true;
 }
-
-void cmCPackDragNDropGenerator::EscapeQuotesAndBackslashes(std::string& line)
-{
-  std::string::size_type backslash_pos = line.find('\\');
-  while (backslash_pos != std::string::npos) {
-    line.replace(backslash_pos, 1, "\\\\");
-    backslash_pos = line.find('\\', backslash_pos + 2);
-  }
-
-  std::string::size_type quote_pos = line.find('\"');
-  while (quote_pos != std::string::npos) {
-    line.replace(quote_pos, 1, "\\\"");
-    quote_pos = line.find('\"', quote_pos + 2);
-  }
-}
diff --git a/Source/CPack/cmCPackDragNDropGenerator.h b/Source/CPack/cmCPackDragNDropGenerator.h
index f8c86c0..dbd190c 100644
--- a/Source/CPack/cmCPackDragNDropGenerator.h
+++ b/Source/CPack/cmCPackDragNDropGenerator.h
@@ -14,6 +14,7 @@
 #include "cmCPackGenerator.h"
 
 class cmGeneratedFileStream;
+class cmXMLWriter;
 
 /** \class cmCPackDragNDropGenerator
  * \brief A generator for OSX drag-n-drop installs
@@ -45,12 +46,40 @@
   std::string slaDirectory;
   bool singleLicense;
 
-  bool WriteLicense(cmGeneratedFileStream& outputStream, int licenseNumber,
+  struct RezDict
+  {
+    std::string Name;
+    size_t ID;
+    std::vector<unsigned char> Data;
+  };
+
+  struct RezArray
+  {
+    std::string Key;
+    std::vector<RezDict> Entries;
+  };
+
+  struct RezDoc
+  {
+    RezArray LPic = { "LPic", {} };
+    RezArray Menu = { "STR#", {} };
+    RezArray Text = { "TEXT", {} };
+    RezArray RTF = { "RTF ", {} };
+  };
+
+  void WriteRezXML(std::string const& file, RezDoc const& rez);
+  void WriteRezArray(cmXMLWriter& xml, RezArray const& array);
+  void WriteRezDict(cmXMLWriter& xml, RezDict const& dict);
+
+  bool WriteLicense(RezDoc& rez, size_t licenseNumber,
                     std::string licenseLanguage,
                     const std::string& licenseFile, std::string* error);
+  void EncodeLicense(RezDict& dict, std::vector<std::string> const& lines);
+  void EncodeMenu(RezDict& dict, std::vector<std::string> const& lines);
+  bool ReadFile(std::string const& file, std::vector<std::string>& lines,
+                std::string* error);
   bool BreakLongLine(const std::string& line, std::vector<std::string>& lines,
                      std::string* error);
-  void EscapeQuotesAndBackslashes(std::string& line);
 };
 
 #endif
diff --git a/Source/CPack/cmCPackExternalGenerator.cxx b/Source/CPack/cmCPackExternalGenerator.cxx
index 11e1aec..0bc8456 100644
--- a/Source/CPack/cmCPackExternalGenerator.cxx
+++ b/Source/CPack/cmCPackExternalGenerator.cxx
@@ -61,7 +61,7 @@
   }
 
   const char* packageScript = this->GetOption("CPACK_EXTERNAL_PACKAGE_SCRIPT");
-  if (packageScript && *packageScript) {
+  if (cmNonempty(packageScript)) {
     if (!cmSystemTools::FileIsFullPath(packageScript)) {
       cmCPackLogger(
         cmCPackLog::LOG_ERROR,
@@ -75,6 +75,12 @@
     if (cmSystemTools::GetErrorOccuredFlag() || !res) {
       return 0;
     }
+
+    const char* builtPackagesStr =
+      this->GetOption("CPACK_EXTERNAL_BUILT_PACKAGES");
+    if (builtPackagesStr) {
+      cmExpandList(builtPackagesStr, this->packageFileNames, false);
+    }
   }
 
   return 1;
@@ -205,7 +211,7 @@
 
   const char* defaultDirectoryPermissions =
     this->Parent->GetOption("CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS");
-  if (defaultDirectoryPermissions && *defaultDirectoryPermissions) {
+  if (cmNonempty(defaultDirectoryPermissions)) {
     root["defaultDirectoryPermissions"] = defaultDirectoryPermissions;
   }
   if (cmIsInternallyOn(this->Parent->GetOption("CPACK_SET_DESTDIR"))) {
diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx
index 288dc58..3880f65 100644
--- a/Source/CPack/cmCPackGenerator.cxx
+++ b/Source/CPack/cmCPackGenerator.cxx
@@ -216,7 +216,7 @@
   mode_t* default_dir_mode = nullptr;
   const char* default_dir_install_permissions =
     this->GetOption("CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS");
-  if (default_dir_install_permissions && *default_dir_install_permissions) {
+  if (cmNonempty(default_dir_install_permissions)) {
     std::vector<std::string> items =
       cmExpandedList(default_dir_install_permissions);
     for (const auto& arg : items) {
@@ -264,6 +264,23 @@
     return 0;
   }
 
+  // Run pre-build actions
+  const char* preBuildScripts = this->GetOption("CPACK_PRE_BUILD_SCRIPTS");
+  if (preBuildScripts) {
+    const auto scripts = cmExpandedList(preBuildScripts, false);
+    for (const auto& script : scripts) {
+      cmCPackLogger(cmCPackLog::LOG_OUTPUT,
+                    "Executing pre-build script: " << script << std::endl);
+
+      if (!this->MakefileMap->ReadListFile(script)) {
+        cmCPackLogger(cmCPackLog::LOG_ERROR,
+                      "The pre-build script not found: " << script
+                                                         << std::endl);
+        return 0;
+      }
+    }
+  }
+
   if (setDestDir) {
     cmSystemTools::PutEnv("DESTDIR=");
   }
@@ -276,7 +293,7 @@
 {
   (void)setDestDir;
   const char* installCommands = this->GetOption("CPACK_INSTALL_COMMANDS");
-  if (installCommands && *installCommands) {
+  if (cmNonempty(installCommands)) {
     std::string tempInstallDirectoryEnv =
       cmStrCat("CMAKE_INSTALL_PREFIX=", tempInstallDirectory);
     cmSystemTools::PutEnv(tempInstallDirectoryEnv);
@@ -327,13 +344,14 @@
   }
   const char* installDirectories =
     this->GetOption("CPACK_INSTALLED_DIRECTORIES");
-  if (installDirectories && *installDirectories) {
+  if (cmNonempty(installDirectories)) {
     std::vector<std::string> installDirectoriesVector =
       cmExpandedList(installDirectories);
     if (installDirectoriesVector.size() % 2 != 0) {
       cmCPackLogger(
         cmCPackLog::LOG_ERROR,
-        "CPACK_INSTALLED_DIRECTORIES should contain pairs of <directory> and "
+        "CPACK_INSTALLED_DIRECTORIES should contain pairs of <directory> "
+        "and "
         "<subdirectory>. The <subdirectory> can be '.' to be installed in "
         "the toplevel directory of installation."
           << std::endl);
@@ -475,10 +493,10 @@
                     "- Install script: " << installScript << std::endl);
 
       if (setDestDir) {
-        // For DESTDIR based packaging, use the *project* CMAKE_INSTALL_PREFIX
-        // underneath the tempInstallDirectory. The value of the project's
-        // CMAKE_INSTALL_PREFIX is sent in here as the value of the
-        // CPACK_INSTALL_PREFIX variable.
+        // For DESTDIR based packaging, use the *project*
+        // CMAKE_INSTALL_PREFIX underneath the tempInstallDirectory. The
+        // value of the project's CMAKE_INSTALL_PREFIX is sent in here as the
+        // value of the CPACK_INSTALL_PREFIX variable.
 
         std::string dir;
         if (this->GetOption("CPACK_INSTALL_PREFIX")) {
@@ -523,7 +541,7 @@
   const char* cmakeProjects = this->GetOption("CPACK_INSTALL_CMAKE_PROJECTS");
   const char* cmakeGenerator = this->GetOption("CPACK_CMAKE_GENERATOR");
   std::string absoluteDestFiles;
-  if (cmakeProjects && *cmakeProjects) {
+  if (cmNonempty(cmakeProjects)) {
     if (!cmakeGenerator) {
       cmCPackLogger(cmCPackLog::LOG_ERROR,
                     "CPACK_INSTALL_CMAKE_PROJECTS is specified, but "
@@ -576,7 +594,7 @@
         std::string installTypesVar = "CPACK_" +
           cmSystemTools::UpperCase(project.Component) + "_INSTALL_TYPES";
         const char* installTypes = this->GetOption(installTypesVar);
-        if (installTypes && *installTypes) {
+        if (cmNonempty(installTypes)) {
           std::vector<std::string> installTypesVector =
             cmExpandedList(installTypes);
           for (std::string const& installType : installTypesVector) {
@@ -589,7 +607,7 @@
         std::string componentsVar =
           "CPACK_COMPONENTS_" + cmSystemTools::UpperCase(project.Component);
         const char* components = this->GetOption(componentsVar);
-        if (components && *components) {
+        if (cmNonempty(components)) {
           cmExpandList(components, componentsVector);
           for (std::string const& comp : componentsVector) {
             project.Components.push_back(
@@ -753,7 +771,7 @@
 
   const char* default_dir_inst_permissions =
     this->GetOption("CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS");
-  if (default_dir_inst_permissions && *default_dir_inst_permissions) {
+  if (cmNonempty(default_dir_inst_permissions)) {
     mf.AddDefinition("CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS",
                      default_dir_inst_permissions);
   }
@@ -811,7 +829,7 @@
      *     - Because it was already used for component install
      *       in order to put things in subdirs...
      */
-    cmSystemTools::PutEnv(std::string("DESTDIR=") + tempInstallDirectory);
+    cmSystemTools::PutEnv("DESTDIR=" + tempInstallDirectory);
     cmCPackLogger(cmCPackLog::LOG_DEBUG,
                   "- Creating directory: '" << dir << "'" << std::endl);
 
@@ -965,7 +983,7 @@
                                          const char* value)
 {
   const char* def = this->MakefileMap->GetDefinition(op);
-  if (def && *def) {
+  if (cmNonempty(def)) {
     return;
   }
   this->SetOption(op, value);
@@ -1076,6 +1094,25 @@
       return 0;
     }
   }
+  // Run post-build actions
+  const char* postBuildScripts = this->GetOption("CPACK_POST_BUILD_SCRIPTS");
+  if (postBuildScripts) {
+    this->MakefileMap->AddDefinition("CPACK_PACKAGE_FILES",
+                                     cmJoin(this->packageFileNames, ";"));
+
+    const auto scripts = cmExpandedList(postBuildScripts, false);
+    for (const auto& script : scripts) {
+      cmCPackLogger(cmCPackLog::LOG_OUTPUT,
+                    "Executing post-build script: " << script << std::endl);
+
+      if (!this->MakefileMap->ReadListFile(script)) {
+        cmCPackLogger(cmCPackLog::LOG_ERROR,
+                      "The post-build script not found: " << script
+                                                          << std::endl);
+        return 0;
+      }
+    }
+  }
 
   /* Prepare checksum algorithm*/
   const char* algo = this->GetOption("CPACK_PACKAGE_CHECKSUM");
@@ -1178,7 +1215,7 @@
 bool cmCPackGenerator::IsSetToOff(const std::string& op) const
 {
   const char* ret = this->MakefileMap->GetDefinition(op);
-  if (ret && *ret) {
+  if (cmNonempty(ret)) {
     return cmIsOff(ret);
   }
   return false;
@@ -1289,7 +1326,7 @@
                                      bool copyOnly /* = false */)
 {
   return this->MakefileMap->ConfigureFile(inName, outName, copyOnly, true,
-                                          false) == 1;
+                                          false, true) == 1;
 }
 
 int cmCPackGenerator::CleanTemporaryDirectory()
@@ -1378,7 +1415,8 @@
           << std::endl);
   }
 
-  // if user specified packaging method, override the default packaging method
+  // if user specified packaging method, override the default packaging
+  // method
   if (method != UNKNOWN_COMPONENT_PACKAGE_METHOD) {
     componentPackageMethod = method;
   }
@@ -1471,7 +1509,7 @@
     installType->Name = name;
 
     const char* displayName = this->GetOption(macroPrefix + "_DISPLAY_NAME");
-    if (displayName && *displayName) {
+    if (cmNonempty(displayName)) {
       installType->DisplayName = displayName;
     } else {
       installType->DisplayName = installType->Name;
@@ -1493,7 +1531,7 @@
       "CPACK_COMPONENT_" + cmsys::SystemTools::UpperCase(name);
     component->Name = name;
     const char* displayName = this->GetOption(macroPrefix + "_DISPLAY_NAME");
-    if (displayName && *displayName) {
+    if (cmNonempty(displayName)) {
       component->DisplayName = displayName;
     } else {
       component->DisplayName = component->Name;
@@ -1505,17 +1543,17 @@
       cmIsOn(this->GetOption("CPACK_DOWNLOAD_ALL"));
 
     const char* archiveFile = this->GetOption(macroPrefix + "_ARCHIVE_FILE");
-    if (archiveFile && *archiveFile) {
+    if (cmNonempty(archiveFile)) {
       component->ArchiveFile = archiveFile;
     }
 
     const char* plist = this->GetOption(macroPrefix + "_PLIST");
-    if (plist && *plist) {
+    if (cmNonempty(plist)) {
       component->Plist = plist;
     }
 
     const char* groupName = this->GetOption(macroPrefix + "_GROUP");
-    if (groupName && *groupName) {
+    if (cmNonempty(groupName)) {
       component->Group = GetComponentGroup(projectName, groupName);
       component->Group->Components.push_back(component);
     } else {
@@ -1523,13 +1561,13 @@
     }
 
     const char* description = this->GetOption(macroPrefix + "_DESCRIPTION");
-    if (description && *description) {
+    if (cmNonempty(description)) {
       component->Description = description;
     }
 
     // Determine the installation types.
     const char* installTypes = this->GetOption(macroPrefix + "_INSTALL_TYPES");
-    if (installTypes && *installTypes) {
+    if (cmNonempty(installTypes)) {
       std::vector<std::string> installTypesVector =
         cmExpandedList(installTypes);
       for (std::string const& installType : installTypesVector) {
@@ -1540,7 +1578,7 @@
 
     // Determine the component dependencies.
     const char* depends = this->GetOption(macroPrefix + "_DEPENDS");
-    if (depends && *depends) {
+    if (cmNonempty(depends)) {
       std::vector<std::string> dependsVector = cmExpandedList(depends);
       for (std::string const& depend : dependsVector) {
         cmCPackComponent* child = GetComponent(projectName, depend);
@@ -1564,21 +1602,21 @@
     // Define the group
     group->Name = name;
     const char* displayName = this->GetOption(macroPrefix + "_DISPLAY_NAME");
-    if (displayName && *displayName) {
+    if (cmNonempty(displayName)) {
       group->DisplayName = displayName;
     } else {
       group->DisplayName = group->Name;
     }
 
     const char* description = this->GetOption(macroPrefix + "_DESCRIPTION");
-    if (description && *description) {
+    if (cmNonempty(description)) {
       group->Description = description;
     }
     group->IsBold = this->IsOn(macroPrefix + "_BOLD_TITLE");
     group->IsExpandedByDefault = this->IsOn(macroPrefix + "_EXPANDED");
     const char* parentGroupName =
       this->GetOption(macroPrefix + "_PARENT_GROUP");
-    if (parentGroupName && *parentGroupName) {
+    if (cmNonempty(parentGroupName)) {
       group->ParentGroup = GetComponentGroup(projectName, parentGroupName);
       group->ParentGroup->Subgroups.push_back(group);
     } else {
diff --git a/Source/CPack/cmCPackNSISGenerator.cxx b/Source/CPack/cmCPackNSISGenerator.cxx
index 058b090..2109b4e 100644
--- a/Source/CPack/cmCPackNSISGenerator.cxx
+++ b/Source/CPack/cmCPackNSISGenerator.cxx
@@ -696,7 +696,7 @@
     const char* userUploadDirectory =
       this->GetOption("CPACK_UPLOAD_DIRECTORY");
     std::string uploadDirectory;
-    if (userUploadDirectory && *userUploadDirectory) {
+    if (cmNonempty(userUploadDirectory)) {
       uploadDirectory = userUploadDirectory;
     } else {
       uploadDirectory =
diff --git a/Source/CTest/cmCTestBuildAndTestHandler.cxx b/Source/CTest/cmCTestBuildAndTestHandler.cxx
index db426b2..a18cbb4 100644
--- a/Source/CTest/cmCTestBuildAndTestHandler.cxx
+++ b/Source/CTest/cmCTestBuildAndTestHandler.cxx
@@ -182,10 +182,9 @@
     std::vector<std::string> extraPaths;
     std::vector<std::string> failed;
     fullPath = cmCTestTestHandler::FindExecutable(
-      this->CTest, this->ConfigSample.c_str(), resultingConfig, extraPaths,
-      failed);
+      this->CTest, this->ConfigSample, resultingConfig, extraPaths, failed);
     if (!fullPath.empty() && !resultingConfig.empty()) {
-      this->CTest->SetConfigType(resultingConfig.c_str());
+      this->CTest->SetConfigType(resultingConfig);
     }
     out << "Using config sample with results: " << fullPath << " and "
         << resultingConfig << std::endl;
@@ -296,9 +295,8 @@
     extraPaths.push_back(tempPath);
   }
   std::vector<std::string> failed;
-  fullPath =
-    cmCTestTestHandler::FindExecutable(this->CTest, this->TestCommand.c_str(),
-                                       resultingConfig, extraPaths, failed);
+  fullPath = cmCTestTestHandler::FindExecutable(
+    this->CTest, this->TestCommand, resultingConfig, extraPaths, failed);
 
   if (!cmSystemTools::FileExists(fullPath)) {
     out << "Could not find path to executable, perhaps it was not built: "
diff --git a/Source/CTest/cmCTestBuildCommand.cxx b/Source/CTest/cmCTestBuildCommand.cxx
index 44fdc29..8aab167 100644
--- a/Source/CTest/cmCTestBuildCommand.cxx
+++ b/Source/CTest/cmCTestBuildCommand.cxx
@@ -12,6 +12,7 @@
 #include "cmGlobalGenerator.h"
 #include "cmMakefile.h"
 #include "cmMessageType.h"
+#include "cmProperty.h"
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
 #include "cmake.h"
@@ -38,10 +39,9 @@
 
   this->Handler = handler;
 
-  const char* ctestBuildCommand =
-    this->Makefile->GetDefinition("CTEST_BUILD_COMMAND");
-  if (ctestBuildCommand && *ctestBuildCommand) {
-    this->CTest->SetCTestConfiguration("MakeCommand", ctestBuildCommand,
+  cmProp ctestBuildCommand = this->Makefile->GetDef("CTEST_BUILD_COMMAND");
+  if (cmNonempty(ctestBuildCommand)) {
+    this->CTest->SetCTestConfiguration("MakeCommand", *ctestBuildCommand,
                                        this->Quiet);
   } else {
     const char* cmakeGeneratorName =
@@ -56,7 +56,7 @@
       this->Makefile->GetDefinition("CTEST_BUILD_CONFIGURATION");
     const char* cmakeBuildConfiguration = !this->Configuration.empty()
       ? this->Configuration.c_str()
-      : ((ctestBuildConfiguration && *ctestBuildConfiguration)
+      : (cmNonempty(ctestBuildConfiguration)
            ? ctestBuildConfiguration
            : this->CTest->GetConfigType().c_str());
 
@@ -67,7 +67,7 @@
       ? this->Target.c_str()
       : this->Makefile->GetDefinition("CTEST_BUILD_TARGET");
 
-    if (cmakeGeneratorName && *cmakeGeneratorName) {
+    if (cmNonempty(cmakeGeneratorName)) {
       if (!cmakeBuildConfiguration) {
         cmakeBuildConfiguration = "Release";
       }
@@ -108,7 +108,7 @@
       cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                          "SetMakeCommand:" << buildCommand << "\n",
                          this->Quiet);
-      this->CTest->SetCTestConfiguration("MakeCommand", buildCommand.c_str(),
+      this->CTest->SetCTestConfiguration("MakeCommand", buildCommand,
                                          this->Quiet);
     } else {
       std::ostringstream ostr;
@@ -123,16 +123,15 @@
     }
   }
 
-  if (const char* useLaunchers =
-        this->Makefile->GetDefinition("CTEST_USE_LAUNCHERS")) {
-    this->CTest->SetCTestConfiguration("UseLaunchers", useLaunchers,
+  if (cmProp useLaunchers = this->Makefile->GetDef("CTEST_USE_LAUNCHERS")) {
+    this->CTest->SetCTestConfiguration("UseLaunchers", *useLaunchers,
                                        this->Quiet);
   }
 
-  if (const char* labelsForSubprojects =
-        this->Makefile->GetDefinition("CTEST_LABELS_FOR_SUBPROJECTS")) {
+  if (cmProp labelsForSubprojects =
+        this->Makefile->GetDef("CTEST_LABELS_FOR_SUBPROJECTS")) {
     this->CTest->SetCTestConfiguration("LabelsForSubprojects",
-                                       labelsForSubprojects, this->Quiet);
+                                       *labelsForSubprojects, this->Quiet);
   }
 
   handler->SetQuiet(this->Quiet);
diff --git a/Source/CTest/cmCTestConfigureCommand.cxx b/Source/CTest/cmCTestConfigureCommand.cxx
index f42c3f1..ac57130 100644
--- a/Source/CTest/cmCTestConfigureCommand.cxx
+++ b/Source/CTest/cmCTestConfigureCommand.cxx
@@ -12,6 +12,7 @@
 #include "cmCTestConfigureHandler.h"
 #include "cmGlobalGenerator.h"
 #include "cmMakefile.h"
+#include "cmProperty.h"
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
 #include "cmake.h"
@@ -38,16 +39,16 @@
     return nullptr;
   }
 
-  const char* ctestConfigureCommand =
-    this->Makefile->GetDefinition("CTEST_CONFIGURE_COMMAND");
+  cmProp ctestConfigureCommand =
+    this->Makefile->GetDef("CTEST_CONFIGURE_COMMAND");
 
-  if (ctestConfigureCommand && *ctestConfigureCommand) {
+  if (cmNonempty(ctestConfigureCommand)) {
     this->CTest->SetCTestConfiguration("ConfigureCommand",
-                                       ctestConfigureCommand, this->Quiet);
+                                       *ctestConfigureCommand, this->Quiet);
   } else {
     const char* cmakeGeneratorName =
       this->Makefile->GetDefinition("CTEST_CMAKE_GENERATOR");
-    if (cmakeGeneratorName && *cmakeGeneratorName) {
+    if (cmNonempty(cmakeGeneratorName)) {
       const std::string& source_dir =
         this->CTest->GetCTestConfiguration("SourceDirectory");
       if (source_dir.empty()) {
@@ -107,7 +108,7 @@
 
       const char* cmakeGeneratorPlatform =
         this->Makefile->GetDefinition("CTEST_CMAKE_GENERATOR_PLATFORM");
-      if (cmakeGeneratorPlatform && *cmakeGeneratorPlatform) {
+      if (cmNonempty(cmakeGeneratorPlatform)) {
         cmakeConfigureCommand += " \"-A";
         cmakeConfigureCommand += cmakeGeneratorPlatform;
         cmakeConfigureCommand += "\"";
@@ -115,7 +116,7 @@
 
       const char* cmakeGeneratorToolset =
         this->Makefile->GetDefinition("CTEST_CMAKE_GENERATOR_TOOLSET");
-      if (cmakeGeneratorToolset && *cmakeGeneratorToolset) {
+      if (cmNonempty(cmakeGeneratorToolset)) {
         cmakeConfigureCommand += " \"-T";
         cmakeConfigureCommand += cmakeGeneratorToolset;
         cmakeConfigureCommand += "\"";
@@ -125,8 +126,8 @@
       cmakeConfigureCommand += source_dir;
       cmakeConfigureCommand += "\"";
 
-      this->CTest->SetCTestConfiguration(
-        "ConfigureCommand", cmakeConfigureCommand.c_str(), this->Quiet);
+      this->CTest->SetCTestConfiguration("ConfigureCommand",
+                                         cmakeConfigureCommand, this->Quiet);
     } else {
       this->SetError(
         "Configure command is not specified. If this is a "
@@ -136,10 +137,10 @@
     }
   }
 
-  if (const char* labelsForSubprojects =
-        this->Makefile->GetDefinition("CTEST_LABELS_FOR_SUBPROJECTS")) {
+  if (cmProp labelsForSubprojects =
+        this->Makefile->GetDef("CTEST_LABELS_FOR_SUBPROJECTS")) {
     this->CTest->SetCTestConfiguration("LabelsForSubprojects",
-                                       labelsForSubprojects, this->Quiet);
+                                       *labelsForSubprojects, this->Quiet);
   }
 
   cmCTestConfigureHandler* handler = this->CTest->GetConfigureHandler();
diff --git a/Source/CTest/cmCTestCoverageHandler.cxx b/Source/CTest/cmCTestCoverageHandler.cxx
index b839c10..093b2d1 100644
--- a/Source/CTest/cmCTestCoverageHandler.cxx
+++ b/Source/CTest/cmCTestCoverageHandler.cxx
@@ -469,8 +469,8 @@
     }
 
     const std::string fileName = cmSystemTools::GetFilenameName(fullFileName);
-    std::string shortFileName =
-      this->CTest->GetShortPathToFile(fullFileName.c_str());
+    const std::string shortFileName =
+      this->CTest->GetShortPathToFile(fullFileName);
     const cmCTestCoverageHandlerContainer::SingleFileCoverageVector& fcov =
       file.second;
     covLogXML.StartElement("File");
@@ -538,7 +538,7 @@
     covSumXML.StartElement("File");
     covSumXML.Attribute("Name", fileName);
     covSumXML.Attribute("FullPath",
-                        this->CTest->GetShortPathToFile(fullFileName.c_str()));
+                        this->CTest->GetShortPathToFile(fullFileName));
     covSumXML.Attribute("Covered", tested + untested > 0 ? "true" : "false");
     covSumXML.Element("LOCTested", tested);
     covSumXML.Element("LOCUnTested", untested);
@@ -1887,8 +1887,8 @@
         // start the file output
         covLogXML.StartElement("File");
         covLogXML.Attribute("Name", i->first);
-        covLogXML.Attribute(
-          "FullPath", this->CTest->GetShortPathToFile(i->second.c_str()));
+        covLogXML.Attribute("FullPath",
+                            this->CTest->GetShortPathToFile(i->second));
         covLogXML.StartElement("Report");
         // write the bullseye header
         line = 0;
@@ -2064,8 +2064,7 @@
       total_untested += (totalFunctions - functionsCalled);
 
       std::string fileName = cmSystemTools::GetFilenameName(file);
-      std::string shortFileName =
-        this->CTest->GetShortPathToFile(file.c_str());
+      std::string shortFileName = this->CTest->GetShortPathToFile(file);
 
       float cper = static_cast<float>(percentBranch + percentFunction);
       if (totalBranches > 0) {
@@ -2266,7 +2265,7 @@
       // is the end of the target-wide labels.
       inTarget = false;
 
-      source = this->CTest->GetShortPathToFile(line.c_str());
+      source = this->CTest->GetShortPathToFile(line);
 
       // Label the source with the target labels.
       LabelSet& labelSet = this->SourceLabels[source];
@@ -2320,7 +2319,7 @@
 
   // The source is filtered out if it does not have any labels in
   // common with the filter set.
-  std::string shortSrc = this->CTest->GetShortPathToFile(source.c_str());
+  std::string shortSrc = this->CTest->GetShortPathToFile(source);
   auto li = this->SourceLabels.find(shortSrc);
   if (li != this->SourceLabels.end()) {
     return !this->IntersectsFilter(li->second);
@@ -2342,14 +2341,14 @@
     std::vector<std::string> files = gl.GetFiles();
     for (std::string const& f : files) {
       if (this->ShouldIDoCoverage(f, cont->SourceDir, cont->BinaryDir)) {
-        extraMatches.insert(this->CTest->GetShortPathToFile(f.c_str()));
+        extraMatches.insert(this->CTest->GetShortPathToFile(f));
       }
     }
   }
 
   if (!extraMatches.empty()) {
     for (auto const& i : cont->TotalCoverage) {
-      std::string shortPath = this->CTest->GetShortPathToFile(i.first.c_str());
+      std::string shortPath = this->CTest->GetShortPathToFile(i.first);
       extraMatches.erase(shortPath);
     }
   }
diff --git a/Source/CTest/cmCTestGenericHandler.cxx b/Source/CTest/cmCTestGenericHandler.cxx
index cc0b4ed..a71f550 100644
--- a/Source/CTest/cmCTestGenericHandler.cxx
+++ b/Source/CTest/cmCTestGenericHandler.cxx
@@ -100,7 +100,7 @@
                                                     << std::endl);
     return false;
   }
-  this->CTest->AddSubmitFile(part, ostr.str().c_str());
+  this->CTest->AddSubmitFile(part, ostr.str());
   return true;
 }
 
diff --git a/Source/CTest/cmCTestHandlerCommand.cxx b/Source/CTest/cmCTestHandlerCommand.cxx
index a755632..03b7173 100644
--- a/Source/CTest/cmCTestHandlerCommand.cxx
+++ b/Source/CTest/cmCTestHandlerCommand.cxx
@@ -14,6 +14,7 @@
 #include "cmExecutionStatus.h"
 #include "cmMakefile.h"
 #include "cmMessageType.h"
+#include "cmProperty.h"
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
 #include "cmWorkingDirectory.h"
@@ -125,23 +126,21 @@
   // CTEST_CONFIGURATION_TYPE script variable if it is defined.
   // The current script value trumps the -C argument on the command
   // line.
-  const char* ctestConfigType =
-    this->Makefile->GetDefinition("CTEST_CONFIGURATION_TYPE");
+  cmProp ctestConfigType = this->Makefile->GetDef("CTEST_CONFIGURATION_TYPE");
   if (ctestConfigType) {
-    this->CTest->SetConfigType(ctestConfigType);
+    this->CTest->SetConfigType(*ctestConfigType);
   }
 
   if (!this->Build.empty()) {
     this->CTest->SetCTestConfiguration(
-      "BuildDirectory", cmSystemTools::CollapseFullPath(this->Build).c_str(),
+      "BuildDirectory", cmSystemTools::CollapseFullPath(this->Build),
       this->Quiet);
   } else {
     std::string const& bdir =
       this->Makefile->GetSafeDefinition("CTEST_BINARY_DIRECTORY");
     if (!bdir.empty()) {
       this->CTest->SetCTestConfiguration(
-        "BuildDirectory", cmSystemTools::CollapseFullPath(bdir).c_str(),
-        this->Quiet);
+        "BuildDirectory", cmSystemTools::CollapseFullPath(bdir), this->Quiet);
     } else {
       cmCTestLog(this->CTest, ERROR_MESSAGE,
                  "CTEST_BINARY_DIRECTORY not set" << std::endl;);
@@ -151,20 +150,18 @@
     cmCTestLog(this->CTest, DEBUG,
                "Set source directory to: " << this->Source << std::endl);
     this->CTest->SetCTestConfiguration(
-      "SourceDirectory", cmSystemTools::CollapseFullPath(this->Source).c_str(),
+      "SourceDirectory", cmSystemTools::CollapseFullPath(this->Source),
       this->Quiet);
   } else {
     this->CTest->SetCTestConfiguration(
       "SourceDirectory",
       cmSystemTools::CollapseFullPath(
-        this->Makefile->GetSafeDefinition("CTEST_SOURCE_DIRECTORY"))
-        .c_str(),
+        this->Makefile->GetSafeDefinition("CTEST_SOURCE_DIRECTORY")),
       this->Quiet);
   }
 
-  if (const char* changeId =
-        this->Makefile->GetDefinition("CTEST_CHANGE_ID")) {
-    this->CTest->SetCTestConfiguration("ChangeId", changeId, this->Quiet);
+  if (cmProp changeId = this->Makefile->GetDef("CTEST_CHANGE_ID")) {
+    this->CTest->SetCTestConfiguration("ChangeId", *changeId, this->Quiet);
   }
 
   cmCTestLog(this->CTest, DEBUG, "Initialize handler" << std::endl;);
diff --git a/Source/CTest/cmCTestMemCheckHandler.cxx b/Source/CTest/cmCTestMemCheckHandler.cxx
index 85b8ab1..8b31e4b 100644
--- a/Source/CTest/cmCTestMemCheckHandler.cxx
+++ b/Source/CTest/cmCTestMemCheckHandler.cxx
@@ -326,6 +326,9 @@
     case cmCTestMemCheckHandler::BOUNDS_CHECKER:
       xml.Attribute("Checker", "BoundsChecker");
       break;
+    case cmCTestMemCheckHandler::CUDA_MEMCHECK:
+      xml.Attribute("Checker", "CudaMemcheck");
+      break;
     case cmCTestMemCheckHandler::ADDRESS_SANITIZER:
       xml.Attribute("Checker", "AddressSanitizer");
       break;
@@ -351,7 +354,7 @@
   cmCTestMemCheckHandler::TestResultsVector::size_type cc;
   for (cmCTestTestResult const& result : this->TestResults) {
     std::string testPath = result.Path + "/" + result.Name;
-    xml.Element("Test", this->CTest->GetShortPathToFile(testPath.c_str()));
+    xml.Element("Test", this->CTest->GetShortPathToFile(testPath));
   }
   xml.EndElement(); // TestList
   cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
@@ -465,6 +468,8 @@
       this->MemoryTesterStyle = cmCTestMemCheckHandler::PURIFY;
     } else if (testerName.find("BC") != std::string::npos) {
       this->MemoryTesterStyle = cmCTestMemCheckHandler::BOUNDS_CHECKER;
+    } else if (testerName.find("cuda-memcheck") != std::string::npos) {
+      this->MemoryTesterStyle = cmCTestMemCheckHandler::CUDA_MEMCHECK;
     } else {
       this->MemoryTesterStyle = cmCTestMemCheckHandler::UNKNOWN;
     }
@@ -485,6 +490,11 @@
     this->MemoryTester =
       this->CTest->GetCTestConfiguration("BoundsCheckerCommand");
     this->MemoryTesterStyle = cmCTestMemCheckHandler::BOUNDS_CHECKER;
+  } else if (cmSystemTools::FileExists(
+               this->CTest->GetCTestConfiguration("CudaMemcheckCommand"))) {
+    this->MemoryTester =
+      this->CTest->GetCTestConfiguration("CudaMemcheckCommand");
+    this->MemoryTesterStyle = cmCTestMemCheckHandler::CUDA_MEMCHECK;
   }
   if (this->CTest->GetCTestConfiguration("MemoryCheckType") ==
       "AddressSanitizer") {
@@ -528,6 +538,8 @@
       this->MemoryTesterStyle = cmCTestMemCheckHandler::VALGRIND;
     } else if (checkType == "DrMemory") {
       this->MemoryTesterStyle = cmCTestMemCheckHandler::DRMEMORY;
+    } else if (checkType == "CudaMemcheck") {
+      this->MemoryTesterStyle = cmCTestMemCheckHandler::CUDA_MEMCHECK;
     }
   }
   if (this->MemoryTester.empty()) {
@@ -553,6 +565,10 @@
                 .empty()) {
     memoryTesterOptions =
       this->CTest->GetCTestConfiguration("DrMemoryCommandOptions");
+  } else if (!this->CTest->GetCTestConfiguration("CudaMemcheckCommandOptions")
+                .empty()) {
+    memoryTesterOptions =
+      this->CTest->GetCTestConfiguration("CudaMemcheckCommandOptions");
   }
   this->MemoryTesterOptions =
     cmSystemTools::ParseArguments(memoryTesterOptions);
@@ -686,6 +702,18 @@
       this->MemoryTesterOptions.emplace_back("/M");
       break;
     }
+    case cmCTestMemCheckHandler::CUDA_MEMCHECK: {
+      // cuda-memcheck separates flags from arguments by spaces
+      if (this->MemoryTesterOptions.empty()) {
+        this->MemoryTesterOptions.emplace_back("--tool");
+        this->MemoryTesterOptions.emplace_back("memcheck");
+        this->MemoryTesterOptions.emplace_back("--leak-check");
+        this->MemoryTesterOptions.emplace_back("full");
+      }
+      this->MemoryTesterDynamicOptions.emplace_back("--log-file");
+      this->MemoryTesterDynamicOptions.push_back(this->MemoryTesterOutputFile);
+      break;
+    }
     // these are almost the same but the env var used is different
     case cmCTestMemCheckHandler::ADDRESS_SANITIZER:
     case cmCTestMemCheckHandler::LEAK_SANITIZER:
@@ -771,6 +799,8 @@
       return this->ProcessMemCheckSanitizerOutput(str, log, results);
     case cmCTestMemCheckHandler::BOUNDS_CHECKER:
       return this->ProcessMemCheckBoundsCheckerOutput(str, log, results);
+    case cmCTestMemCheckHandler::CUDA_MEMCHECK:
+      return this->ProcessMemCheckCudaOutput(str, log, results);
     default:
       log.append("\nMemory checking style used was: ");
       log.append("None that I know");
@@ -1103,6 +1133,119 @@
   return defects == 0;
 }
 
+bool cmCTestMemCheckHandler::ProcessMemCheckCudaOutput(
+  const std::string& str, std::string& log, std::vector<int>& results)
+{
+  std::vector<std::string> lines;
+  cmsys::SystemTools::Split(str, lines);
+  bool unlimitedOutput = false;
+  if (str.find("CTEST_FULL_OUTPUT") != std::string::npos ||
+      this->CustomMaximumFailedTestOutputSize == 0) {
+    unlimitedOutput = true;
+  }
+
+  std::string::size_type cc;
+
+  std::ostringstream ostr;
+  log.clear();
+
+  int defects = 0;
+
+  cmsys::RegularExpression memcheckLine("^========");
+
+  cmsys::RegularExpression leakExpr("== Leaked [0-9,]+ bytes at");
+
+  // list of matchers for output messages that contain variable content
+  // (addresses, sizes, ...) or can be shortened in general. the first match is
+  // used as a error name.
+  std::vector<cmsys::RegularExpression> matchers{
+    // API errors
+    "== Malloc/Free error encountered: (.*)",
+    "== Program hit error ([^ ]*).* on CUDA API call to",
+    "== Program hit ([^ ]*).* on CUDA API call to",
+    // memcheck
+    "== (Invalid .*) of size [0-9,]+", "== (Fatal UVM [CG]PU fault)",
+    // racecheck
+    "== .* (Potential .* hazard detected)", "== .* (Race reported)",
+    // synccheck
+    "== (Barrier error)",
+    // initcheck
+    "== (Uninitialized .* memory read)", "== (Unused memory)",
+    "== (Host API memory access error)",
+    // generic error: ignore ERROR SUMMARY, CUDA-MEMCHECK and others
+    "== ([A-Z][a-z].*)"
+  };
+
+  std::vector<std::string::size_type> nonMemcheckOutput;
+  auto sttime = std::chrono::steady_clock::now();
+  cmCTestOptionalLog(this->CTest, DEBUG,
+                     "Start test: " << lines.size() << std::endl, this->Quiet);
+  std::string::size_type totalOutputSize = 0;
+  for (cc = 0; cc < lines.size(); cc++) {
+    cmCTestOptionalLog(this->CTest, DEBUG,
+                       "test line " << lines[cc] << std::endl, this->Quiet);
+
+    if (memcheckLine.find(lines[cc])) {
+      cmCTestOptionalLog(this->CTest, DEBUG,
+                         "cuda-memcheck line " << lines[cc] << std::endl,
+                         this->Quiet);
+      int failure = -1;
+      auto& line = lines[cc];
+      if (leakExpr.find(line)) {
+        failure = static_cast<int>(this->FindOrAddWarning("Memory leak"));
+      } else {
+        for (auto& matcher : matchers) {
+          if (matcher.find(line)) {
+            failure =
+              static_cast<int>(this->FindOrAddWarning(matcher.match(1)));
+            break;
+          }
+        }
+      }
+
+      if (failure >= 0) {
+        ostr << "<b>" << this->ResultStrings[failure] << "</b> ";
+        if (results.empty() || unsigned(failure) > results.size() - 1) {
+          results.push_back(1);
+        } else {
+          results[failure]++;
+        }
+        defects++;
+      }
+      totalOutputSize += lines[cc].size();
+      ostr << lines[cc] << std::endl;
+    } else {
+      nonMemcheckOutput.push_back(cc);
+    }
+  }
+  // Now put all all the non cuda-memcheck output into the test output
+  // This should be last in case it gets truncated by the output
+  // limiting code
+  for (std::string::size_type i : nonMemcheckOutput) {
+    totalOutputSize += lines[i].size();
+    ostr << lines[i] << std::endl;
+    if (!unlimitedOutput &&
+        totalOutputSize >
+          static_cast<size_t>(this->CustomMaximumFailedTestOutputSize)) {
+      ostr << "....\n";
+      ostr << "Test Output for this test has been truncated see testing"
+              " machine logs for full output,\n";
+      ostr << "or put CTEST_FULL_OUTPUT in the output of "
+              "this test program.\n";
+      break; // stop the copy of output if we are full
+    }
+  }
+  cmCTestOptionalLog(this->CTest, DEBUG,
+                     "End test (elapsed: "
+                       << cmDurationTo<unsigned int>(
+                            std::chrono::steady_clock::now() - sttime)
+                       << "s)" << std::endl,
+                     this->Quiet);
+  log = ostr.str();
+  this->DefectCount += defects;
+  return defects == 0;
+}
+
 // PostProcessTest memcheck results
 void cmCTestMemCheckHandler::PostProcessTest(cmCTestTestResult& res, int test)
 {
diff --git a/Source/CTest/cmCTestMemCheckHandler.h b/Source/CTest/cmCTestMemCheckHandler.h
index 52667f8..63ab573 100644
--- a/Source/CTest/cmCTestMemCheckHandler.h
+++ b/Source/CTest/cmCTestMemCheckHandler.h
@@ -46,6 +46,7 @@
     DRMEMORY,
     BOUNDS_CHECKER,
     // checkers after here do not use the standard error list
+    CUDA_MEMCHECK,
     ADDRESS_SANITIZER,
     LEAK_SANITIZER,
     THREAD_SANITIZER,
@@ -137,6 +138,8 @@
                                      std::vector<int>& results);
   bool ProcessMemCheckPurifyOutput(const std::string& str, std::string& log,
                                    std::vector<int>& results);
+  bool ProcessMemCheckCudaOutput(const std::string& str, std::string& log,
+                                 std::vector<int>& results);
   bool ProcessMemCheckSanitizerOutput(const std::string& str, std::string& log,
                                       std::vector<int>& results);
   bool ProcessMemCheckBoundsCheckerOutput(const std::string& str,
diff --git a/Source/CTest/cmCTestReadCustomFilesCommand.cxx b/Source/CTest/cmCTestReadCustomFilesCommand.cxx
index ed14d06..a25cca4 100644
--- a/Source/CTest/cmCTestReadCustomFilesCommand.cxx
+++ b/Source/CTest/cmCTestReadCustomFilesCommand.cxx
@@ -15,7 +15,7 @@
   }
 
   for (std::string const& arg : args) {
-    this->CTest->ReadCustomConfigurationFileTree(arg.c_str(), this->Makefile);
+    this->CTest->ReadCustomConfigurationFileTree(arg, this->Makefile);
   }
 
   return true;
diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx
index 2c8e385..4d65c9b 100644
--- a/Source/CTest/cmCTestRunTest.cxx
+++ b/Source/CTest/cmCTestRunTest.cxx
@@ -619,11 +619,11 @@
     cmCTestMemCheckHandler* handler =
       static_cast<cmCTestMemCheckHandler*>(this->TestHandler);
     this->ActualCommand = handler->MemoryTester;
-    this->TestProperties->Args[1] = this->TestHandler->FindTheExecutable(
-      this->TestProperties->Args[1].c_str());
+    this->TestProperties->Args[1] =
+      this->TestHandler->FindTheExecutable(this->TestProperties->Args[1]);
   } else {
-    this->ActualCommand = this->TestHandler->FindTheExecutable(
-      this->TestProperties->Args[1].c_str());
+    this->ActualCommand =
+      this->TestHandler->FindTheExecutable(this->TestProperties->Args[1]);
     ++j; // skip the executable (it will be actualCommand)
   }
   std::string testCommand =
diff --git a/Source/CTest/cmCTestStartCommand.cxx b/Source/CTest/cmCTestStartCommand.cxx
index fe68406..6398d66 100644
--- a/Source/CTest/cmCTestStartCommand.cxx
+++ b/Source/CTest/cmCTestStartCommand.cxx
@@ -94,10 +94,9 @@
 
   std::string sourceDir = cmSystemTools::CollapseFullPath(src_dir);
   std::string binaryDir = cmSystemTools::CollapseFullPath(bld_dir);
-  this->CTest->SetCTestConfiguration("SourceDirectory", sourceDir.c_str(),
+  this->CTest->SetCTestConfiguration("SourceDirectory", sourceDir,
                                      this->Quiet);
-  this->CTest->SetCTestConfiguration("BuildDirectory", binaryDir.c_str(),
-                                     this->Quiet);
+  this->CTest->SetCTestConfiguration("BuildDirectory", binaryDir, this->Quiet);
 
   if (smodel) {
     cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
diff --git a/Source/CTest/cmCTestSubmitCommand.cxx b/Source/CTest/cmCTestSubmitCommand.cxx
index 279216e..026e98f 100644
--- a/Source/CTest/cmCTestSubmitCommand.cxx
+++ b/Source/CTest/cmCTestSubmitCommand.cxx
@@ -35,12 +35,12 @@
 
 cmCTestGenericHandler* cmCTestSubmitCommand::InitializeHandler()
 {
-  const char* submitURL = !this->SubmitURL.empty()
-    ? this->SubmitURL.c_str()
-    : this->Makefile->GetDefinition("CTEST_SUBMIT_URL");
+  const std::string* submitURL = !this->SubmitURL.empty()
+    ? &this->SubmitURL
+    : this->Makefile->GetDef("CTEST_SUBMIT_URL");
 
   if (submitURL) {
-    this->CTest->SetCTestConfiguration("SubmitURL", submitURL, this->Quiet);
+    this->CTest->SetCTestConfiguration("SubmitURL", *submitURL, this->Quiet);
   } else {
     this->CTest->SetCTestConfigurationFromCMakeVariable(
       this->Makefile, "DropMethod", "CTEST_DROP_METHOD", this->Quiet);
@@ -108,7 +108,7 @@
   if (this->PartsMentioned) {
     auto parts =
       cmMakeRange(this->Parts).transform([this](std::string const& arg) {
-        return this->CTest->GetPartFromName(arg.c_str());
+        return this->CTest->GetPartFromName(arg);
       });
     handler->SelectParts(std::set<cmCTest::Part>(parts.begin(), parts.end()));
   }
@@ -177,7 +177,7 @@
     !this->Files.empty() || cm::contains(keywords, "FILES");
 
   cm::erase_if(this->Parts, [this](std::string const& arg) -> bool {
-    cmCTest::Part p = this->CTest->GetPartFromName(arg.c_str());
+    cmCTest::Part p = this->CTest->GetPartFromName(arg);
     if (p == cmCTest::PartCount) {
       std::ostringstream e;
       e << "Part name \"" << arg << "\" is invalid.";
diff --git a/Source/CTest/cmCTestSubmitHandler.cxx b/Source/CTest/cmCTestSubmitHandler.cxx
index ea36df5..5b54573 100644
--- a/Source/CTest/cmCTestSubmitHandler.cxx
+++ b/Source/CTest/cmCTestSubmitHandler.cxx
@@ -797,7 +797,7 @@
         gfile = gfile.substr(glen);
         cmCTestOptionalLog(this->CTest, DEBUG,
                            "Glob file: " << gfile << std::endl, this->Quiet);
-        this->CTest->AddSubmitFile(cmCTest::PartCoverage, gfile.c_str());
+        this->CTest->AddSubmitFile(cmCTest::PartCoverage, gfile);
       }
     } else {
       cmCTestLog(this->CTest, ERROR_MESSAGE, "Problem globbing" << std::endl);
diff --git a/Source/CTest/cmCTestTestCommand.cxx b/Source/CTest/cmCTestTestCommand.cxx
index c71b409..cbc3c0c 100644
--- a/Source/CTest/cmCTestTestCommand.cxx
+++ b/Source/CTest/cmCTestTestCommand.cxx
@@ -13,6 +13,7 @@
 #include "cmCTestTestHandler.h"
 #include "cmDuration.h"
 #include "cmMakefile.h"
+#include "cmProperty.h"
 #include "cmStringAlgorithms.h"
 
 void cmCTestTestCommand::BindArguments()
@@ -116,13 +117,13 @@
   unsigned long testLoad;
   const char* ctestTestLoad = this->Makefile->GetDefinition("CTEST_TEST_LOAD");
   if (!this->TestLoad.empty()) {
-    if (!cmStrToULong(this->TestLoad.c_str(), &testLoad)) {
+    if (!cmStrToULong(this->TestLoad, &testLoad)) {
       testLoad = 0;
       cmCTestLog(this->CTest, WARNING,
                  "Invalid value for 'TEST_LOAD' : " << this->TestLoad
                                                     << std::endl);
     }
-  } else if (ctestTestLoad && *ctestTestLoad) {
+  } else if (cmNonempty(ctestTestLoad)) {
     if (!cmStrToULong(ctestTestLoad, &testLoad)) {
       testLoad = 0;
       cmCTestLog(this->CTest, WARNING,
@@ -134,10 +135,10 @@
   }
   handler->SetTestLoad(testLoad);
 
-  if (const char* labelsForSubprojects =
-        this->Makefile->GetDefinition("CTEST_LABELS_FOR_SUBPROJECTS")) {
+  if (cmProp labelsForSubprojects =
+        this->Makefile->GetDef("CTEST_LABELS_FOR_SUBPROJECTS")) {
     this->CTest->SetCTestConfiguration("LabelsForSubprojects",
-                                       labelsForSubprojects, this->Quiet);
+                                       *labelsForSubprojects, this->Quiet);
   }
 
   handler->SetQuiet(this->Quiet);
diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx
index d0dbaae..70e84ee 100644
--- a/Source/CTest/cmCTestTestHandler.cxx
+++ b/Source/CTest/cmCTestTestHandler.cxx
@@ -1374,7 +1374,7 @@
   xml.StartElement("TestList");
   for (cmCTestTestResult const& result : this->TestResults) {
     std::string testPath = result.Path + "/" + result.Name;
-    xml.Element("Test", this->CTest->GetShortPathToFile(testPath.c_str()));
+    xml.Element("Test", this->CTest->GetShortPathToFile(testPath));
   }
   xml.EndElement(); // TestList
   for (cmCTestTestResult& result : this->TestResults) {
@@ -1483,8 +1483,8 @@
   }
   std::string testPath = result.Path + "/" + result.Name;
   xml.Element("Name", result.Name);
-  xml.Element("Path", this->CTest->GetShortPathToFile(result.Path.c_str()));
-  xml.Element("FullName", this->CTest->GetShortPathToFile(testPath.c_str()));
+  xml.Element("Path", this->CTest->GetShortPathToFile(result.Path));
+  xml.Element("FullName", this->CTest->GetShortPathToFile(testPath));
   xml.Element("FullCommandLine", result.FullCommandLine);
 }
 
@@ -1546,12 +1546,12 @@
 }
 
 // Find the appropriate executable to run for a test
-std::string cmCTestTestHandler::FindTheExecutable(const char* exe)
+std::string cmCTestTestHandler::FindTheExecutable(const std::string& exe)
 {
   std::string resConfig;
   std::vector<std::string> extraPaths;
   std::vector<std::string> failedPaths;
-  if (strcmp(exe, "NOT_AVAILABLE") == 0) {
+  if (exe == "NOT_AVAILABLE") {
     return exe;
   }
   return cmCTestTestHandler::FindExecutable(this->CTest, exe, resConfig,
@@ -1607,7 +1607,7 @@
 
 // Find the appropriate executable to run for a test
 std::string cmCTestTestHandler::FindExecutable(
-  cmCTest* ctest, const char* testCommand, std::string& resultingConfig,
+  cmCTest* ctest, const std::string& testCommand, std::string& resultingConfig,
   std::vector<std::string>& extraPaths, std::vector<std::string>& failed)
 {
   // now run the compiled test if we can find it
diff --git a/Source/CTest/cmCTestTestHandler.h b/Source/CTest/cmCTestTestHandler.h
index 0d88c30..b26f8a6 100644
--- a/Source/CTest/cmCTestTestHandler.h
+++ b/Source/CTest/cmCTestTestHandler.h
@@ -198,7 +198,8 @@
                                 std::string filepath, std::string& filename);
 
   // full signature static method to find an executable
-  static std::string FindExecutable(cmCTest* ctest, const char* testCommand,
+  static std::string FindExecutable(cmCTest* ctest,
+                                    const std::string& testCommand,
                                     std::string& resultingConfig,
                                     std::vector<std::string>& extraPaths,
                                     std::vector<std::string>& failed);
@@ -309,7 +310,7 @@
   /**
    * Find the executable for a test
    */
-  std::string FindTheExecutable(const char* exe);
+  std::string FindTheExecutable(const std::string& exe);
 
   std::string GetTestStatus(cmCTestTestResult const&);
   void ExpandTestsToRunInformation(size_t numPossibleTests);
diff --git a/Source/CTest/cmCTestUpdateCommand.cxx b/Source/CTest/cmCTestUpdateCommand.cxx
index 673eb9a..95cae13 100644
--- a/Source/CTest/cmCTestUpdateCommand.cxx
+++ b/Source/CTest/cmCTestUpdateCommand.cxx
@@ -11,14 +11,13 @@
 {
   if (!this->Source.empty()) {
     this->CTest->SetCTestConfiguration(
-      "SourceDirectory", cmSystemTools::CollapseFullPath(this->Source).c_str(),
+      "SourceDirectory", cmSystemTools::CollapseFullPath(this->Source),
       this->Quiet);
   } else {
     this->CTest->SetCTestConfiguration(
       "SourceDirectory",
       cmSystemTools::CollapseFullPath(
-        this->Makefile->GetDefinition("CTEST_SOURCE_DIRECTORY"))
-        .c_str(),
+        this->Makefile->GetDefinition("CTEST_SOURCE_DIRECTORY")),
       this->Quiet);
   }
   std::string source_dir =
diff --git a/Source/CTest/cmProcess.cxx b/Source/CTest/cmProcess.cxx
index a549117..9ee1c17 100644
--- a/Source/CTest/cmProcess.cxx
+++ b/Source/CTest/cmProcess.cxx
@@ -545,17 +545,17 @@
 #  endif
 #  ifdef SIGABRT
     case SIGABRT:
-      exception_str = "Child aborted";
+      exception_str = "Subprocess aborted";
       break;
 #  endif
 #  ifdef SIGKILL
     case SIGKILL:
-      exception_str = "Child killed";
+      exception_str = "Subprocess killed";
       break;
 #  endif
 #  ifdef SIGTERM
     case SIGTERM:
-      exception_str = "Child terminated";
+      exception_str = "Subprocess terminated";
       break;
 #  endif
 #  ifdef SIGHUP
diff --git a/Source/Checks/cm_cxx_features.cmake b/Source/Checks/cm_cxx_features.cmake
index 50ccc7c..e726fc7 100644
--- a/Source/Checks/cm_cxx_features.cmake
+++ b/Source/Checks/cm_cxx_features.cmake
@@ -63,3 +63,8 @@
   set(CMake_HAVE_CXX_UNIQUE_PTR 1)
 endif()
 cm_check_cxx_feature(unique_ptr)
+if (NOT CMAKE_CXX_STANDARD LESS "17")
+  cm_check_cxx_feature(filesystem)
+else()
+  set(CMake_HAVE_CXX_FILESYSTEM FALSE)
+endif()
diff --git a/Source/Checks/cm_cxx_filesystem.cxx b/Source/Checks/cm_cxx_filesystem.cxx
new file mode 100644
index 0000000..e508d1c
--- /dev/null
+++ b/Source/Checks/cm_cxx_filesystem.cxx
@@ -0,0 +1,10 @@
+
+#include <filesystem>
+
+int main()
+{
+  std::filesystem::path p1("/a/b/c");
+  std::filesystem::path p2("/a/b/c");
+
+  return p1 == p2 ? 0 : 1;
+}
diff --git a/Source/CursesDialog/ccmake.cxx b/Source/CursesDialog/ccmake.cxx
index 9a26db5..85e256b 100644
--- a/Source/CursesDialog/ccmake.cxx
+++ b/Source/CursesDialog/ccmake.cxx
@@ -2,11 +2,15 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 
 #include <csignal>
+#include <cstdio>
+#include <cstdlib>
 #include <cstring>
 #include <iostream>
 #include <string>
 #include <vector>
 
+#include <unistd.h>
+
 #include "cmsys/Encoding.hxx"
 
 #include "cmCursesColor.h"
@@ -54,7 +58,12 @@
 {
   if (cmCursesForm::CurrentForm) {
     endwin();
-    initscr();            /* Initialization */
+    if (initscr() == nullptr) {
+      static const char errmsg[] = "Error: ncurses initialization failed\n";
+      auto r = write(STDERR_FILENO, errmsg, sizeof(errmsg) - 1);
+      static_cast<void>(r);
+      exit(1);
+    }
     noecho();             /* Echo off */
     cbreak();             /* nl- or cr not needed */
     keypad(stdscr, true); /* Use key symbols as KEY_DOWN */
@@ -124,7 +133,10 @@
     cmCursesForm::DebugStart();
   }
 
-  initscr();            /* Initialization */
+  if (initscr() == nullptr) {
+    fprintf(stderr, "Error: ncurses initialization failed\n");
+    exit(1);
+  }
   noecho();             /* Echo off */
   cbreak();             /* nl- or cr not needed */
   keypad(stdscr, true); /* Use key symbols as KEY_DOWN */
diff --git a/Source/CursesDialog/form/frm_driver.c b/Source/CursesDialog/form/frm_driver.c
index e4e72aa..112ab08 100644
--- a/Source/CursesDialog/form/frm_driver.c
+++ b/Source/CursesDialog/form/frm_driver.c
@@ -2983,7 +2983,7 @@
 |   Function      :  static FIELD *Upper_Neighbour_Field(FIELD * field)
 |   
 |   Description   :  Because of the row-major nature of sorting the fields,
-|                    its more difficult to define whats the upper neighbour
+|                    its more difficult to define what's the upper neighbour
 |                    field really means. We define that it must be on a
 |                    'previous' line (cyclic order!) and is the rightmost
 |                    field laying on the left side of the given field. If
@@ -3030,7 +3030,7 @@
 |   Function      :  static FIELD *Down_Neighbour_Field(FIELD * field)
 |   
 |   Description   :  Because of the row-major nature of sorting the fields,
-|                    its more difficult to define whats the down neighbour
+|                    its more difficult to define what's the down neighbour
 |                    field really means. We define that it must be on a
 |                    'next' line (cyclic order!) and is the leftmost
 |                    field laying on the right side of the given field. If
diff --git a/Source/QtDialog/CMakeLists.txt b/Source/QtDialog/CMakeLists.txt
index 98dd0e2..e6d6b17 100644
--- a/Source/QtDialog/CMakeLists.txt
+++ b/Source/QtDialog/CMakeLists.txt
@@ -3,111 +3,79 @@
 
 project(QtDialog)
 CMake_OPTIONAL_COMPONENT(cmake-gui)
-find_package(Qt5Widgets QUIET)
-if (Qt5Widgets_FOUND)
-  include_directories(${Qt5Widgets_INCLUDE_DIRS})
-  add_definitions(${Qt5Widgets_DEFINITONS})
-  macro(qt4_wrap_ui)
-    qt5_wrap_ui(${ARGN})
-  endmacro()
-  macro(qt4_wrap_cpp)
-    qt5_wrap_cpp(${ARGN})
-  endmacro()
-  macro(qt4_add_resources)
-    qt5_add_resources(${ARGN})
-  endmacro()
+find_package(Qt5Widgets REQUIRED)
 
-  set(CMake_QT_LIBRARIES ${Qt5Widgets_LIBRARIES})
-  set(QT_QTMAIN_LIBRARY ${Qt5Core_QTMAIN_LIBRARIES})
+set(CMake_QT_EXTRA_LIBRARIES)
 
-  # Try to find the package WinExtras for the task bar progress
-  if(WIN32)
-    find_package(Qt5WinExtras QUIET)
-    if (Qt5WinExtras_FOUND)
-      include_directories(${Qt5WinExtras_INCLUDE_DIRS})
-      add_definitions(-DQT_WINEXTRAS)
-      list(APPEND CMake_QT_LIBRARIES ${Qt5WinExtras_LIBRARIES})
-    endif()
+# Try to find the package WinExtras for the task bar progress
+if(WIN32)
+  find_package(Qt5WinExtras QUIET)
+  if (Qt5WinExtras_FOUND)
+    add_definitions(-DQT_WINEXTRAS)
+    list(APPEND CMake_QT_EXTRA_LIBRARIES Qt5::WinExtras)
   endif()
+endif()
 
-  # Remove this when the minimum version of Qt is 4.6.
-  add_definitions(-DQT_DISABLE_DEPRECATED_BEFORE=0)
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS}")
 
-  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS}")
+if(CMake_QT_STATIC_QXcbIntegrationPlugin_LIBRARIES)
+  list(APPEND CMake_QT_EXTRA_LIBRARIES ${CMake_QT_STATIC_QXcbIntegrationPlugin_LIBRARIES})
+  set_property(SOURCE CMakeSetup.cxx
+    PROPERTY COMPILE_DEFINITIONS USE_QXcbIntegrationPlugin)
+endif()
 
-  if(CMake_QT_STATIC_QXcbIntegrationPlugin_LIBRARIES)
-    list(APPEND CMake_QT_LIBRARIES ${CMake_QT_STATIC_QXcbIntegrationPlugin_LIBRARIES})
-    set_property(SOURCE CMakeSetup.cxx
-      PROPERTY COMPILE_DEFINITIONS USE_QXcbIntegrationPlugin)
-  endif()
+if(CMake_QT_STATIC_QWindowsIntegrationPlugin_LIBRARIES)
+  list(APPEND CMake_QT_EXTRA_LIBRARIES ${CMake_QT_STATIC_QWindowsIntegrationPlugin_LIBRARIES})
+  set_property(SOURCE CMakeSetup.cxx
+    PROPERTY COMPILE_DEFINITIONS USE_QWindowsIntegrationPlugin)
+endif()
 
-  if(CMake_QT_STATIC_QWindowsIntegrationPlugin_LIBRARIES)
-    list(APPEND CMake_QT_LIBRARIES ${CMake_QT_STATIC_QWindowsIntegrationPlugin_LIBRARIES})
-    set_property(SOURCE CMakeSetup.cxx
-      PROPERTY COMPILE_DEFINITIONS USE_QWindowsIntegrationPlugin)
-  endif()
-
-  # We need to install platform plugin and add qt.conf for Qt5 on Mac and Windows.
-  # FIXME: This should be part of Qt5 CMake scripts, but unfortunately
-  # Qt5 support is missing there.
-  if(CMake_INSTALL_DEPENDENCIES AND (APPLE OR WIN32))
-    macro(install_qt5_plugin _qt_plugin_name _qt_plugins_var)
-      get_target_property(_qt_plugin_path "${_qt_plugin_name}" LOCATION)
-      if(EXISTS "${_qt_plugin_path}")
-        get_filename_component(_qt_plugin_file "${_qt_plugin_path}" NAME)
-        get_filename_component(_qt_plugin_type "${_qt_plugin_path}" PATH)
-        get_filename_component(_qt_plugin_type "${_qt_plugin_type}" NAME)
-        if(APPLE)
-          set(_qt_plugin_dir "PlugIns")
-        elseif(WIN32)
-          set(_qt_plugin_dir "plugins")
-        endif()
-        set(_qt_plugin_dest "${_qt_plugin_dir}/${_qt_plugin_type}")
-        install(FILES "${_qt_plugin_path}"
-          DESTINATION "${_qt_plugin_dest}"
-          ${COMPONENT})
-        set(${_qt_plugins_var}
-          "${${_qt_plugins_var}};\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${_qt_plugin_dest}/${_qt_plugin_file}")
-      else()
-        message(FATAL_ERROR "QT plugin ${_qt_plugin_name} not found")
+# We need to install platform plugin and add qt.conf for Qt5 on Mac and Windows.
+# FIXME: This should be part of Qt5 CMake scripts, but unfortunately
+# Qt5 support is missing there.
+if(CMake_INSTALL_DEPENDENCIES AND (APPLE OR WIN32))
+  macro(install_qt5_plugin _qt_plugin_name _qt_plugins_var)
+    get_target_property(_qt_plugin_path "${_qt_plugin_name}" LOCATION)
+    if(EXISTS "${_qt_plugin_path}")
+      get_filename_component(_qt_plugin_file "${_qt_plugin_path}" NAME)
+      get_filename_component(_qt_plugin_type "${_qt_plugin_path}" PATH)
+      get_filename_component(_qt_plugin_type "${_qt_plugin_type}" NAME)
+      if(APPLE)
+        set(_qt_plugin_dir "PlugIns")
+      elseif(WIN32)
+        set(_qt_plugin_dir "plugins")
       endif()
-    endmacro()
-    if(APPLE)
-      install_qt5_plugin("Qt5::QCocoaIntegrationPlugin" QT_PLUGINS)
-      file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
-        "[Paths]\nPlugins = ${_qt_plugin_dir}\n")
-      install(FILES "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
-        DESTINATION "${CMAKE_INSTALL_PREFIX}/Resources"
+      set(_qt_plugin_dest "${_qt_plugin_dir}/${_qt_plugin_type}")
+      install(FILES "${_qt_plugin_path}"
+        DESTINATION "${_qt_plugin_dest}"
         ${COMPONENT})
-    elseif(WIN32 AND NOT CMake_QT_STATIC_QWindowsIntegrationPlugin_LIBRARIES)
-      install_qt5_plugin("Qt5::QWindowsIntegrationPlugin" QT_PLUGINS)
-      file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
-        "[Paths]\nPlugins = ../${_qt_plugin_dir}\n")
-      install(FILES "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
-        DESTINATION bin
-        ${COMPONENT})
+      set(${_qt_plugins_var}
+        "${${_qt_plugins_var}};\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${_qt_plugin_dest}/${_qt_plugin_file}")
+    else()
+      message(FATAL_ERROR "QT plugin ${_qt_plugin_name} not found")
     endif()
+  endmacro()
+  if(APPLE)
+    install_qt5_plugin("Qt5::QCocoaIntegrationPlugin" QT_PLUGINS)
+    file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
+      "[Paths]\nPlugins = ${_qt_plugin_dir}\n")
+    install(FILES "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
+      DESTINATION "${CMAKE_INSTALL_PREFIX}/Resources"
+      ${COMPONENT})
+  elseif(WIN32 AND NOT CMake_QT_STATIC_QWindowsIntegrationPlugin_LIBRARIES)
+    install_qt5_plugin("Qt5::QWindowsIntegrationPlugin" QT_PLUGINS)
+    file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
+      "[Paths]\nPlugins = ../${_qt_plugin_dir}\n")
+    install(FILES "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
+      DESTINATION bin
+      ${COMPONENT})
   endif()
+endif()
 
-  if(TARGET Qt5::Core)
-    get_property(_Qt5_Core_LOCATION TARGET Qt5::Core PROPERTY LOCATION)
-    get_filename_component(Qt_BIN_DIR "${_Qt5_Core_LOCATION}" PATH)
-    if(APPLE)
-      get_filename_component(Qt_BIN_DIR "${Qt_BIN_DIR}" PATH)
-    endif()
-  endif()
-else()
-  set(QT_MIN_VERSION "4.4.0")
-  find_package(Qt4 REQUIRED)
-  if(NOT QT4_FOUND)
-    message(SEND_ERROR "Failed to find Qt 4.4 or greater.")
-    return()
-  endif()
-
-  include(${QT_USE_FILE})
-
-  set(CMake_QT_LIBRARIES ${QT_LIBRARIES})
-
+get_property(_Qt5_Core_LOCATION TARGET Qt5::Core PROPERTY LOCATION)
+get_filename_component(Qt_BIN_DIR "${_Qt5_Core_LOCATION}" PATH)
+if(APPLE)
+  get_filename_component(Qt_BIN_DIR "${Qt_BIN_DIR}" PATH)
 endif()
 
 set(SRCS
@@ -116,6 +84,7 @@
   CMakeSetup.cxx
   CMakeSetupDialog.cxx
   CMakeSetupDialog.h
+  Compilers.h
   FirstConfigure.cxx
   FirstConfigure.h
   QCMake.cxx
@@ -129,7 +98,7 @@
   WarningMessagesDialog.cxx
   WarningMessagesDialog.h
   )
-QT4_WRAP_UI(UI_SRCS
+qt5_wrap_ui(UI_SRCS
   CMakeSetupDialog.ui
   Compilers.ui
   CrossCompiler.ui
@@ -137,7 +106,7 @@
   RegexExplorer.ui
   WarningMessagesDialog.ui
   )
-QT4_WRAP_CPP(MOC_SRCS
+qt5_wrap_cpp(MOC_SRCS
   AddCacheEntry.h
   Compilers.h
   CMakeSetupDialog.h
@@ -148,14 +117,24 @@
   RegexExplorer.h
   WarningMessagesDialog.h
   )
-QT4_ADD_RESOURCES(RC_SRCS CMakeSetup.qrc)
+qt5_add_resources(RC_SRCS CMakeSetup.qrc)
 
-set(SRCS ${SRCS} ${UI_SRCS} ${MOC_SRCS} ${RC_SRCS})
+if (FALSE) # CMake's bootstrap binary does not support automoc
+  set(CMAKE_AUTOMOC 1)
+  set(CMAKE_AUTORCC 1)
+  set(CMAKE_AUTOUIC 1)
+else ()
+  list(APPEND SRCS
+    ${UI_SRCS}
+    ${MOC_SRCS}
+    ${RC_SRCS})
+endif ()
+
 if(WIN32)
-  set(SRCS ${SRCS} CMakeSetup.rc)
+  list(APPEND SRCS CMakeSetup.rc)
 endif()
 if(APPLE)
-  set(SRCS ${SRCS} CMakeSetup.icns)
+  list(APPEND SRCS CMakeSetup.icns)
   set(MACOSX_BUNDLE_ICON_FILE CMakeSetup.icns)
   set_source_files_properties(CMakeSetup.icns PROPERTIES
     MACOSX_PACKAGE_LOCATION Resources)
@@ -172,7 +151,7 @@
 set(CMAKE_INCLUDE_CURRENT_DIR ON)
 
 add_executable(cmake-gui WIN32 MACOSX_BUNDLE ${SRCS} ${MANIFEST_FILE})
-target_link_libraries(cmake-gui CMakeLib ${QT_QTMAIN_LIBRARY} ${CMake_QT_LIBRARIES})
+target_link_libraries(cmake-gui CMakeLib Qt5::Core Qt5::Widgets ${CMake_QT_EXTRA_LIBRARIES})
 
 if(WIN32)
   target_sources(cmake-gui PRIVATE $<TARGET_OBJECTS:CMakeVersion>)
diff --git a/Source/QtDialog/CMakeSetup.cxx b/Source/QtDialog/CMakeSetup.cxx
index 9d928b2..7ef5a72 100644
--- a/Source/QtDialog/CMakeSetup.cxx
+++ b/Source/QtDialog/CMakeSetup.cxx
@@ -115,14 +115,6 @@
   QTextCodec* utf8_codec = QTextCodec::codecForName("UTF-8");
   QTextCodec::setCodecForLocale(utf8_codec);
 
-#if QT_VERSION < 0x050000
-  // clean out standard Qt paths for plugins, which we don't use anyway
-  // when creating Mac bundles, it potentially causes problems
-  foreach (QString p, QApplication::libraryPaths()) {
-    QApplication::removeLibraryPath(p);
-  }
-#endif
-
   // tell the cmake library where cmake is
   QDir cmExecDir(QApplication::applicationDirPath());
 #if defined(Q_OS_MAC)
diff --git a/Source/QtDialog/CMakeSetupDialog.cxx b/Source/QtDialog/CMakeSetupDialog.cxx
index 6dbfe11..fcc8408 100644
--- a/Source/QtDialog/CMakeSetupDialog.cxx
+++ b/Source/QtDialog/CMakeSetupDialog.cxx
@@ -152,9 +152,6 @@
   this->WarnUninitializedAction =
     OptionsMenu->addAction(tr("&Warn Uninitialized (--warn-uninitialized)"));
   this->WarnUninitializedAction->setCheckable(true);
-  this->WarnUnusedAction =
-    OptionsMenu->addAction(tr("&Warn Unused (--warn-unused-vars)"));
-  this->WarnUnusedAction->setCheckable(true);
 
   QAction* debugAction = OptionsMenu->addAction(tr("&Debug Output"));
   debugAction->setCheckable(true);
@@ -290,9 +287,6 @@
   QObject::connect(this->WarnUninitializedAction, SIGNAL(triggered(bool)),
                    this->CMakeThread->cmakeInstance(),
                    SLOT(setWarnUninitializedMode(bool)));
-  QObject::connect(this->WarnUnusedAction, SIGNAL(triggered(bool)),
-                   this->CMakeThread->cmakeInstance(),
-                   SLOT(setWarnUnusedMode(bool)));
 
   if (!this->SourceDirectory->text().isEmpty() ||
       !this->BinaryDirectory->lineEdit()->text().isEmpty()) {
diff --git a/Source/QtDialog/CMakeSetupDialog.h b/Source/QtDialog/CMakeSetupDialog.h
index d1e2035..914be12 100644
--- a/Source/QtDialog/CMakeSetupDialog.h
+++ b/Source/QtDialog/CMakeSetupDialog.h
@@ -111,7 +111,6 @@
   QAction* ConfigureAction;
   QAction* GenerateAction;
   QAction* WarnUninitializedAction;
-  QAction* WarnUnusedAction;
   QAction* InstallForCommandLineAction;
   State CurrentState;
 
diff --git a/Source/QtDialog/QCMake.cxx b/Source/QtDialog/QCMake.cxx
index 776af81..6090256 100644
--- a/Source/QtDialog/QCMake.cxx
+++ b/Source/QtDialog/QCMake.cxx
@@ -21,7 +21,6 @@
   : QObject(p)
 {
   this->WarnUninitializedMode = false;
-  this->WarnUnusedMode = false;
   qRegisterMetaType<QCMakeProperty>();
   qRegisterMetaType<QCMakePropertyList>();
 
@@ -170,7 +169,6 @@
   this->CMakeInstance->SetGeneratorToolset(this->Toolset.toLocal8Bit().data());
   this->CMakeInstance->LoadCache();
   this->CMakeInstance->SetWarnUninitialized(this->WarnUninitializedMode);
-  this->CMakeInstance->SetWarnUnused(this->WarnUnusedMode);
   this->CMakeInstance->PreLoadCMakeFiles();
 
   InterruptFlag = 0;
@@ -340,10 +338,10 @@
 
 bool QCMake::interruptCallback()
 {
-#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
-  return this->InterruptFlag;
-#else
+#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
   return this->InterruptFlag.load();
+#else
+  return this->InterruptFlag.loadRelaxed();
 #endif
 }
 
@@ -478,11 +476,6 @@
   this->WarnUninitializedMode = value;
 }
 
-void QCMake::setWarnUnusedMode(bool value)
-{
-  this->WarnUnusedMode = value;
-}
-
 void QCMake::checkOpenPossible()
 {
   std::string data = this->BinaryDirectory.toLocal8Bit().data();
diff --git a/Source/QtDialog/QCMake.h b/Source/QtDialog/QCMake.h
index 110a971..39555d6 100644
--- a/Source/QtDialog/QCMake.h
+++ b/Source/QtDialog/QCMake.h
@@ -114,8 +114,6 @@
   void setDeprecatedWarningsAsErrors(bool value);
   /// set whether to run cmake with warnings about uninitialized variables
   void setWarnUninitializedMode(bool value);
-  /// set whether to run cmake with warnings about unused variables
-  void setWarnUnusedMode(bool value);
   /// check if project IDE open is possible and emit openPossible signal
   void checkOpenPossible();
 
@@ -175,8 +173,6 @@
   void stderrCallback(std::string const& msg);
 
   bool WarnUninitializedMode;
-  bool WarnUnusedMode;
-  bool WarnUnusedAllMode;
   QString SourceDirectory;
   QString BinaryDirectory;
   QString Generator;
diff --git a/Source/QtDialog/QCMakeCacheView.cxx b/Source/QtDialog/QCMakeCacheView.cxx
index 9b24fbd..3bf4409 100644
--- a/Source/QtDialog/QCMakeCacheView.cxx
+++ b/Source/QtDialog/QCMakeCacheView.cxx
@@ -155,11 +155,7 @@
 
 void QCMakeCacheView::setShowAdvanced(bool s)
 {
-#if QT_VERSION >= 040300
-  // new 4.3 API that needs to be called.  what about an older Qt?
   this->SearchFilter->invalidate();
-#endif
-
   this->AdvancedFilter->setShowAdvanced(s);
 }
 
@@ -209,9 +205,7 @@
 
 void QCMakeCacheModel::setProperties(const QCMakePropertyList& props)
 {
-#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
   this->beginResetModel();
-#endif
 
   QSet<QCMakeProperty> newProps;
   QSet<QCMakeProperty> newProps2;
@@ -335,11 +329,7 @@
   }
 
   this->blockSignals(b);
-#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
   this->endResetModel();
-#else
-  this->reset();
-#endif
 }
 
 QCMakeCacheModel::ViewType QCMakeCacheModel::viewType() const
@@ -349,9 +339,7 @@
 
 void QCMakeCacheModel::setViewType(QCMakeCacheModel::ViewType t)
 {
-#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
   this->beginResetModel();
-#endif
 
   this->View = t;
 
@@ -368,11 +356,7 @@
   this->setProperties(oldProps);
   this->setProperties(props);
   this->blockSignals(b);
-#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
   this->endResetModel();
-#else
-  this->reset();
-#endif
 }
 
 void QCMakeCacheModel::setPropertyData(const QModelIndex& idx1,
@@ -498,8 +482,7 @@
       // go to the next in the tree
       while (!idxs.isEmpty() &&
              (
-#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) &&                                \
-  QT_VERSION < QT_VERSION_CHECK(5, 1, 0)
+#if QT_VERSION < QT_VERSION_CHECK(5, 1, 0)
                (idxs.last().row() + 1) >= rowCount(idxs.last().parent()) ||
 #endif
                !idxs.last().sibling(idxs.last().row() + 1, 0).isValid())) {
@@ -659,20 +642,6 @@
   return success;
 }
 
-// Issue 205903 fixed in Qt 4.5.0.
-// Can remove this function and FileDialogFlag when minimum Qt version is 4.5
-bool QCMakeCacheModelDelegate::eventFilter(QObject* object, QEvent* evt)
-{
-  // workaround for what looks like a bug in Qt on macOS
-  // where it doesn't create a QWidget wrapper for the native file dialog
-  // so the Qt library ends up assuming the focus was lost to something else
-
-  if (evt->type() == QEvent::FocusOut && this->FileDialogFlag) {
-    return false;
-  }
-  return QItemDelegate::eventFilter(object, evt);
-}
-
 void QCMakeCacheModelDelegate::setModelData(QWidget* editor,
                                             QAbstractItemModel* model,
                                             const QModelIndex& index) const
diff --git a/Source/QtDialog/QCMakeCacheView.h b/Source/QtDialog/QCMakeCacheView.h
index bea1965..a252708 100644
--- a/Source/QtDialog/QCMakeCacheView.h
+++ b/Source/QtDialog/QCMakeCacheView.h
@@ -144,7 +144,6 @@
   bool editorEvent(QEvent* event, QAbstractItemModel* model,
                    const QStyleOptionViewItem& option,
                    const QModelIndex& index);
-  bool eventFilter(QObject* object, QEvent* event);
   void setModelData(QWidget* editor, QAbstractItemModel* model,
                     const QModelIndex& index) const;
   QSize sizeHint(const QStyleOptionViewItem& option,
diff --git a/Source/QtDialog/QCMakeWidgets.cxx b/Source/QtDialog/QCMakeWidgets.cxx
index 332a770..d16ea58 100644
--- a/Source/QtDialog/QCMakeWidgets.cxx
+++ b/Source/QtDialog/QCMakeWidgets.cxx
@@ -4,9 +4,9 @@
 
 #include <utility>
 
-#include <QDirModel>
 #include <QFileDialog>
 #include <QFileInfo>
+#include <QFileSystemModel>
 #include <QResizeEvent>
 #include <QToolButton>
 
@@ -88,20 +88,20 @@
   }
 }
 
-// use same QDirModel for all completers
-static QDirModel* fileDirModel()
+// use same QFileSystemModel for all completers
+static QFileSystemModel* fileDirModel()
 {
-  static QDirModel* m = nullptr;
+  static QFileSystemModel* m = nullptr;
   if (!m) {
-    m = new QDirModel();
+    m = new QFileSystemModel();
   }
   return m;
 }
-static QDirModel* pathDirModel()
+static QFileSystemModel* pathDirModel()
 {
-  static QDirModel* m = nullptr;
+  static QFileSystemModel* m = nullptr;
   if (!m) {
-    m = new QDirModel();
+    m = new QFileSystemModel();
     m->setFilter(QDir::AllDirs | QDir::Drives | QDir::NoDotAndDotDot);
   }
   return m;
@@ -110,7 +110,7 @@
 QCMakeFileCompleter::QCMakeFileCompleter(QObject* o, bool dirs)
   : QCompleter(o)
 {
-  QDirModel* m = dirs ? pathDirModel() : fileDirModel();
+  QFileSystemModel* m = dirs ? pathDirModel() : fileDirModel();
   this->setModel(m);
 }
 
diff --git a/Source/cmAddLibraryCommand.cxx b/Source/cmAddLibraryCommand.cxx
index 3e5d764..f262fac 100644
--- a/Source/cmAddLibraryCommand.cxx
+++ b/Source/cmAddLibraryCommand.cxx
@@ -2,8 +2,6 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmAddLibraryCommand.h"
 
-#include <cmext/algorithm>
-
 #include "cmExecutionStatus.h"
 #include "cmGeneratorExpression.h"
 #include "cmGlobalGenerator.h"
@@ -111,20 +109,10 @@
           "INTERFACE library specified with conflicting ALIAS type.");
         return false;
       }
-      if (excludeFromAll) {
-        status.SetError(
-          "INTERFACE library may not be used with EXCLUDE_FROM_ALL.");
-        return false;
-      }
       ++s;
       type = cmStateEnums::INTERFACE_LIBRARY;
       haveSpecifiedType = true;
     } else if (*s == "EXCLUDE_FROM_ALL") {
-      if (type == cmStateEnums::INTERFACE_LIBRARY) {
-        status.SetError(
-          "INTERFACE library may not be used with EXCLUDE_FROM_ALL.");
-        return false;
-      }
       ++s;
       excludeFromAll = true;
     } else if (*s == "IMPORTED") {
@@ -143,10 +131,6 @@
   }
 
   if (type == cmStateEnums::INTERFACE_LIBRARY) {
-    if (s != args.end()) {
-      status.SetError("INTERFACE library requires no source arguments.");
-      return false;
-    }
     if (importGlobal && !importTarget) {
       status.SetError(
         "INTERFACE library specified as GLOBAL, but not as IMPORTED.");
@@ -302,8 +286,6 @@
     }
   }
 
-  std::vector<std::string> srclists;
-
   if (type == cmStateEnums::INTERFACE_LIBRARY) {
     if (!cmGeneratorExpression::IsValidTargetName(libName) ||
         libName.find("::") != std::string::npos) {
@@ -311,14 +293,10 @@
         cmStrCat("Invalid name for INTERFACE library target: ", libName));
       return false;
     }
-
-    mf.AddLibrary(libName, type, srclists, excludeFromAll);
-    return true;
   }
 
-  cm::append(srclists, s, args.end());
-
-  mf.AddLibrary(libName, type, srclists, excludeFromAll);
+  std::vector<std::string> srcs(s, args.end());
+  mf.AddLibrary(libName, type, srcs, excludeFromAll);
 
   return true;
 }
diff --git a/Source/cmAuxSourceDirectoryCommand.cxx b/Source/cmAuxSourceDirectoryCommand.cxx
index d6f7500e..53d4cb4 100644
--- a/Source/cmAuxSourceDirectoryCommand.cxx
+++ b/Source/cmAuxSourceDirectoryCommand.cxx
@@ -55,7 +55,7 @@
         auto ext = cm::string_view(file).substr(dotpos + 1);
         // Process only source files
         auto cm = mf.GetCMakeInstance();
-        if (dotpos > 0 && cm->IsSourceExtension(ext)) {
+        if (dotpos > 0 && cm->IsACLikeSourceExtension(ext)) {
           std::string fullname = cmStrCat(templateDirectory, '/', file);
           // add the file as a class file so
           // depends can be done
diff --git a/Source/cmCMakeLanguageCommand.h b/Source/cmCMakeLanguageCommand.h
index 7306515..aeb8f60 100644
--- a/Source/cmCMakeLanguageCommand.h
+++ b/Source/cmCMakeLanguageCommand.h
@@ -11,7 +11,7 @@
 struct cmListFileArgument;
 
 /**
- * \brief Calls a scripted or build-in command
+ * \brief Calls a scripted or built-in command
  *
  */
 bool cmCMakeLanguageCommand(std::vector<cmListFileArgument> const& args,
diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx
index bca7540..a5fde89 100644
--- a/Source/cmCTest.cxx
+++ b/Source/cmCTest.cxx
@@ -394,7 +394,7 @@
   return this->Impl->CompressTestOutput;
 }
 
-cmCTest::Part cmCTest::GetPartFromName(const char* name)
+cmCTest::Part cmCTest::GetPartFromName(const std::string& name)
 {
   // Look up by lower-case to make names case-insensitive.
   std::string lower_name = cmSystemTools::LowerCase(name);
@@ -458,8 +458,7 @@
   cm.GetCurrentSnapshot().SetDefaultDefinitions();
   cmGlobalGenerator gg(&cm);
   cmMakefile mf(&gg, cm.GetCurrentSnapshot());
-  if (!this->ReadCustomConfigurationFileTree(this->Impl->BinaryDir.c_str(),
-                                             &mf)) {
+  if (!this->ReadCustomConfigurationFileTree(this->Impl->BinaryDir, &mf)) {
     cmCTestOptionalLog(
       this, DEBUG, "Cannot find custom configuration file tree" << std::endl,
       quiet);
@@ -523,7 +522,7 @@
         std::string model;
         if (cmSystemTools::GetLineFromStream(tfin, model) &&
             !this->Impl->Parts[PartStart] && !command) {
-          this->Impl->TestModel = GetTestModelFromString(model.c_str());
+          this->Impl->TestModel = GetTestModelFromString(model);
         }
         tfin.close();
       }
@@ -579,7 +578,7 @@
         cmSystemTools::GetLineFromStream(tfin, tag);
         cmSystemTools::GetLineFromStream(tfin, group);
         if (cmSystemTools::GetLineFromStream(tfin, modelStr)) {
-          model = GetTestModelFromString(modelStr.c_str());
+          model = GetTestModelFromString(modelStr);
         }
         tfin.close();
       }
@@ -793,7 +792,7 @@
   return this->Impl->TestModel;
 }
 
-bool cmCTest::SetTest(const char* ttype, bool report)
+bool cmCTest::SetTest(const std::string& ttype, bool report)
 {
   if (cmSystemTools::LowerCase(ttype) == "all") {
     for (Part p = PartStart; p != PartCount; p = Part(p + 1)) {
@@ -841,6 +840,7 @@
     }
   }
   std::string filename = testingDir + "/" + name;
+  stream.SetTempExt("tmp");
   stream.Open(filename);
   if (!stream) {
     cmCTestLog(this, ERROR_MESSAGE,
@@ -855,7 +855,7 @@
   return true;
 }
 
-bool cmCTest::AddIfExists(Part part, const char* file)
+bool cmCTest::AddIfExists(Part part, const std::string& file)
 {
   if (this->CTestFileExists(file)) {
     this->AddSubmitFile(part, file);
@@ -1007,7 +1007,7 @@
   if (this->Impl->Parts[PartNotes]) {
     this->UpdateCTestConfiguration();
     if (!this->Impl->NotesFiles.empty()) {
-      this->GenerateNotesFile(this->Impl->NotesFiles.c_str());
+      this->GenerateNotesFile(this->Impl->NotesFiles);
     }
   }
   if (this->Impl->Parts[PartSubmit]) {
@@ -1036,9 +1036,9 @@
   return "Experimental";
 }
 
-int cmCTest::GetTestModelFromString(const char* str)
+int cmCTest::GetTestModelFromString(const std::string& str)
 {
-  if (!str) {
+  if (str.empty()) {
     return cmCTest::EXPERIMENTAL;
   }
   std::string rstr = cmSystemTools::LowerCase(str);
@@ -1564,9 +1564,9 @@
   return 0;
 }
 
-int cmCTest::GenerateNotesFile(const char* cfiles)
+int cmCTest::GenerateNotesFile(const std::string& cfiles)
 {
-  if (!cfiles) {
+  if (cfiles.empty()) {
     return 1;
   }
 
@@ -1649,14 +1649,14 @@
                                             << std::endl;);
       return false;
     }
-    this->AddSubmitFile(PartExtraFiles, file.c_str());
+    this->AddSubmitFile(PartExtraFiles, file);
   }
   return true;
 }
 
-bool cmCTest::SubmitExtraFiles(const char* cfiles)
+bool cmCTest::SubmitExtraFiles(const std::string& cfiles)
 {
-  if (!cfiles) {
+  if (cfiles.empty()) {
     return true;
   }
 
@@ -1940,7 +1940,7 @@
   else if (this->CheckArgument(arg, "-C"_s, "--build-config") &&
            i < args.size() - 1) {
     i++;
-    this->SetConfigType(args[i].c_str());
+    this->SetConfigType(args[i]);
   }
 
   else if (this->CheckArgument(arg, "--debug"_s)) {
@@ -2015,7 +2015,7 @@
   else if (this->CheckArgument(arg, "-O"_s, "--output-log") &&
            i < args.size() - 1) {
     i++;
-    this->SetOutputLogFileName(args[i].c_str());
+    this->SetOutputLogFileName(args[i]);
   }
 
   else if (this->CheckArgument(arg, "--tomorrow-tag"_s)) {
@@ -2047,7 +2047,7 @@
     this->Impl->ProduceXML = true;
     this->SetTest("Notes");
     i++;
-    this->SetNotesFiles(args[i].c_str());
+    this->SetNotesFiles(args[i]);
     return true;
   }
 
@@ -2304,7 +2304,7 @@
       this->Impl->ProduceXML = true;
       this->SetTest("Submit");
       i++;
-      if (!this->SubmitExtraFiles(args[i].c_str())) {
+      if (!this->SubmitExtraFiles(args[i])) {
         return 0;
       }
     }
@@ -2375,7 +2375,7 @@
       (i < args.size() - 1)) {
     this->Impl->ProduceXML = true;
     i++;
-    if (!this->SetTest(args[i].c_str(), false)) {
+    if (!this->SetTest(args[i], false)) {
       success = false;
       cmCTestLog(this, ERROR_MESSAGE,
                  "CTest -T called with incorrect option: " << args[i]
@@ -2490,11 +2490,8 @@
   return retv;
 }
 
-void cmCTest::SetNotesFiles(const char* notes)
+void cmCTest::SetNotesFiles(const std::string& notes)
 {
-  if (!notes) {
-    return;
-  }
   this->Impl->NotesFiles = notes;
 }
 
@@ -2560,7 +2557,8 @@
   this->Impl->ScheduleType = type;
 }
 
-int cmCTest::ReadCustomConfigurationFileTree(const char* dir, cmMakefile* mf)
+int cmCTest::ReadCustomConfigurationFileTree(const std::string& dir,
+                                             cmMakefile* mf)
 {
   bool found = false;
   cmCTestLog(this, DEBUG,
@@ -2647,7 +2645,7 @@
   val = atoi(dval);
 }
 
-std::string cmCTest::GetShortPathToFile(const char* cfname)
+std::string cmCTest::GetShortPathToFile(const std::string& cfname)
 {
   const std::string& sourceDir = cmSystemTools::CollapseFullPath(
     this->GetCTestConfiguration("SourceDirectory"));
@@ -2711,18 +2709,17 @@
   this->Impl->CTestConfiguration.clear();
 }
 
-void cmCTest::SetCTestConfiguration(const char* name, const char* value,
+void cmCTest::SetCTestConfiguration(const char* name, const std::string& value,
                                     bool suppress)
 {
   cmCTestOptionalLog(this, HANDLER_VERBOSE_OUTPUT,
-                     "SetCTestConfiguration:"
-                       << name << ":" << (value ? value : "(null)") << "\n",
+                     "SetCTestConfiguration:" << name << ":" << value << "\n",
                      suppress);
 
   if (!name) {
     return;
   }
-  if (!value) {
+  if (value.empty()) {
     this->Impl->CTestConfiguration.erase(name);
     return;
   }
@@ -2927,7 +2924,7 @@
   return this->Impl->BuildID;
 }
 
-void cmCTest::AddSubmitFile(Part part, const char* name)
+void cmCTest::AddSubmitFile(Part part, const std::string& name)
 {
   this->Impl->Parts[part].SubmitFiles.emplace_back(name);
 }
@@ -2963,9 +2960,9 @@
   this->Impl->CTestConfigurationOverwrites[key] = value;
 }
 
-void cmCTest::SetConfigType(const char* ct)
+void cmCTest::SetConfigType(const std::string& ct)
 {
-  this->Impl->ConfigType = ct ? ct : "";
+  this->Impl->ConfigType = ct;
   cmSystemTools::ReplaceString(this->Impl->ConfigType, ".\\", "");
   std::string confTypeEnv = "CMAKE_CONFIG_TYPE=" + this->Impl->ConfigType;
   cmSystemTools::PutEnv(confTypeEnv);
@@ -2975,8 +2972,7 @@
   cmMakefile* mf, const char* dconfig, const std::string& cmake_var,
   bool suppress)
 {
-  const char* ctvar;
-  ctvar = mf->GetDefinition(cmake_var);
+  cmProp ctvar = mf->GetDef(cmake_var);
   if (!ctvar) {
     return false;
   }
@@ -2984,7 +2980,7 @@
                      "SetCTestConfigurationFromCMakeVariable:"
                        << dconfig << ":" << cmake_var << std::endl,
                      suppress);
-  this->SetCTestConfiguration(dconfig, ctvar, suppress);
+  this->SetCTestConfiguration(dconfig, *ctvar, suppress);
   return true;
 }
 
@@ -3085,9 +3081,9 @@
   return result;
 }
 
-void cmCTest::SetOutputLogFileName(const char* name)
+void cmCTest::SetOutputLogFileName(const std::string& name)
 {
-  if (name) {
+  if (!name.empty()) {
     this->Impl->OutputLogFile = cm::make_unique<cmGeneratedFileStream>(name);
   } else {
     this->Impl->OutputLogFile.reset();
diff --git a/Source/cmCTest.h b/Source/cmCTest.h
index a39b8fe..1e0fb8c 100644
--- a/Source/cmCTest.h
+++ b/Source/cmCTest.h
@@ -64,7 +64,7 @@
 
   /** Get a testing part id from its string name.  Returns PartCount
       if the string does not name a valid part.  */
-  Part GetPartFromName(const char* name);
+  Part GetPartFromName(const std::string& name);
 
   /** Process Command line arguments */
   int Run(std::vector<std::string>&, std::string* output = nullptr);
@@ -127,12 +127,12 @@
    * Check if CTest file exists
    */
   bool CTestFileExists(const std::string& filename);
-  bool AddIfExists(Part part, const char* file);
+  bool AddIfExists(Part part, const std::string& file);
 
   /**
    * Set the cmake test
    */
-  bool SetTest(const char*, bool report = true);
+  bool SetTest(const std::string&, bool report = true);
 
   /**
    * Set the cmake test mode (experimental, nightly, continuous).
@@ -141,11 +141,11 @@
   int GetTestModel() const;
 
   std::string GetTestModelString();
-  static int GetTestModelFromString(const char* str);
+  static int GetTestModelFromString(const std::string& str);
   static std::string CleanString(const std::string& str,
                                  std::string::size_type spos = 0);
   std::string GetCTestConfiguration(const std::string& name);
-  void SetCTestConfiguration(const char* name, const char* value,
+  void SetCTestConfiguration(const char* name, const std::string& value,
                              bool suppress = false);
   void EmptyCTestConfiguration();
 
@@ -161,7 +161,7 @@
   cmCTest& operator=(const cmCTest&) = delete;
 
   /** Set the notes files to be created. */
-  void SetNotesFiles(const char* notes);
+  void SetNotesFiles(const std::string& notes);
 
   void PopulateCustomVector(cmMakefile* mf, const std::string& definition,
                             std::vector<std::string>& vec);
@@ -272,7 +272,7 @@
    * This means if the file is in binary or
    * source directory, it will become /.../relative/path/to/file
    */
-  std::string GetShortPathToFile(const char* fname);
+  std::string GetShortPathToFile(const std::string& fname);
 
   enum
   {
@@ -354,14 +354,14 @@
   int GenerateDoneFile();
 
   /** Submit extra files to the server */
-  bool SubmitExtraFiles(const char* files);
+  bool SubmitExtraFiles(const std::string& files);
   bool SubmitExtraFiles(std::vector<std::string> const& files);
 
   /** Set the output log file name */
-  void SetOutputLogFileName(const char* name);
+  void SetOutputLogFileName(const std::string& name);
 
   /** Set the visual studio or Xcode config type */
-  void SetConfigType(const char* ct);
+  void SetConfigType(const std::string& ct);
 
   /** Various log types */
   enum
@@ -399,14 +399,14 @@
   std::string GetBuildID() const;
 
   /** Add file to be submitted */
-  void AddSubmitFile(Part part, const char* name);
+  void AddSubmitFile(Part part, const std::string& name);
   std::vector<std::string> const& GetSubmitFiles(Part part) const;
   void ClearSubmitFiles(Part part);
 
   /**
    * Read the custom configuration files and apply them to the current ctest
    */
-  int ReadCustomConfigurationFileTree(const char* dir, cmMakefile* mf);
+  int ReadCustomConfigurationFileTree(const std::string& dir, cmMakefile* mf);
 
   std::vector<std::string>& GetInitialCommandLineArguments();
 
@@ -462,7 +462,7 @@
   void SetRunCurrentScript(bool value);
 
 private:
-  int GenerateNotesFile(const char* files);
+  int GenerateNotesFile(const std::string& files);
 
   void BlockTestErrorDiagnostics();
 
diff --git a/Source/cmCacheManager.cxx b/Source/cmCacheManager.cxx
index 35bd681..95686ea 100644
--- a/Source/cmCacheManager.cxx
+++ b/Source/cmCacheManager.cxx
@@ -578,10 +578,7 @@
 bool cmCacheManager::CacheEntry::GetPropertyAsBool(
   const std::string& prop) const
 {
-  if (cmProp value = this->GetProperty(prop)) {
-    return cmIsOn(*value);
-  }
-  return false;
+  return cmIsOn(this->GetProperty(prop));
 }
 
 void cmCacheManager::CacheEntry::SetProperty(const std::string& prop,
diff --git a/Source/cmCommonTargetGenerator.cxx b/Source/cmCommonTargetGenerator.cxx
index 051eff6..8aee27c 100644
--- a/Source/cmCommonTargetGenerator.cxx
+++ b/Source/cmCommonTargetGenerator.cxx
@@ -41,7 +41,7 @@
 const char* cmCommonTargetGenerator::GetFeature(const std::string& feature,
                                                 const std::string& config)
 {
-  return this->GeneratorTarget->GetFeature(feature, config);
+  return this->GeneratorTarget->GetFeature(feature, config)->c_str();
 }
 
 void cmCommonTargetGenerator::AddModuleDefinitionFlag(
diff --git a/Source/cmComputeComponentGraph.cxx b/Source/cmComputeComponentGraph.cxx
index 81cd878..6591fb1 100644
--- a/Source/cmComputeComponentGraph.cxx
+++ b/Source/cmComputeComponentGraph.cxx
@@ -8,6 +8,12 @@
 cmComputeComponentGraph::cmComputeComponentGraph(Graph const& input)
   : InputGraph(input)
 {
+}
+
+cmComputeComponentGraph::~cmComputeComponentGraph() = default;
+
+void cmComputeComponentGraph::Compute()
+{
   // Identify components.
   this->Tarjan();
 
@@ -17,8 +23,6 @@
   this->TransferEdges();
 }
 
-cmComputeComponentGraph::~cmComputeComponentGraph() = default;
-
 void cmComputeComponentGraph::Tarjan()
 {
   int n = static_cast<int>(this->InputGraph.size());
diff --git a/Source/cmComputeComponentGraph.h b/Source/cmComputeComponentGraph.h
index 202888c..b873131 100644
--- a/Source/cmComputeComponentGraph.h
+++ b/Source/cmComputeComponentGraph.h
@@ -31,6 +31,9 @@
   cmComputeComponentGraph(Graph const& input);
   ~cmComputeComponentGraph();
 
+  /** Run the computation.  */
+  void Compute();
+
   /** Get the adjacency list of the component graph.  */
   Graph const& GetComponentGraph() const { return this->ComponentGraph; }
   EdgeList const& GetComponentGraphEdges(int c) const
diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx
index e9bf5a5..8ca2168 100644
--- a/Source/cmComputeLinkDepends.cxx
+++ b/Source/cmComputeLinkDepends.cxx
@@ -253,13 +253,13 @@
   // Compute the final set of link entries.
   // Iterate in reverse order so we can keep only the last occurrence
   // of a shared library.
-  std::set<int> emmitted;
+  std::set<int> emitted;
   for (int i : cmReverseRange(this->FinalLinkOrder)) {
     LinkEntry const& e = this->EntryList[i];
     cmGeneratorTarget const* t = e.Target;
     // Entries that we know the linker will re-use do not need to be repeated.
     bool uniquify = t && t->GetType() == cmStateEnums::SHARED_LIBRARY;
-    if (!uniquify || emmitted.insert(i).second) {
+    if (!uniquify || emitted.insert(i).second) {
       this->FinalLinkEntries.push_back(e);
     }
   }
@@ -626,6 +626,7 @@
   // constraints disallow it.
   this->CCG =
     cm::make_unique<cmComputeComponentGraph>(this->EntryConstraintGraph);
+  this->CCG->Compute();
 
   // The component graph is guaranteed to be acyclic.  Start a DFS
   // from every entry to compute a topological order for the
diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx
index 4c5f57d..43cceae 100644
--- a/Source/cmComputeLinkInformation.cxx
+++ b/Source/cmComputeLinkInformation.cxx
@@ -515,7 +515,7 @@
   // Restore the target link type so the correct system runtime
   // libraries are found.
   cmProp lss = this->Target->GetProperty("LINK_SEARCH_END_STATIC");
-  if (lss && cmIsOn(*lss)) {
+  if (cmIsOn(lss)) {
     this->SetCurrentLinkType(LinkStatic);
   } else {
     this->SetCurrentLinkType(this->StartLinkType);
@@ -832,8 +832,7 @@
 
   // We can support link type switching only if all needed flags are
   // known.
-  if (static_link_type_flag && *static_link_type_flag &&
-      shared_link_type_flag && *shared_link_type_flag) {
+  if (cmNonempty(static_link_type_flag) && cmNonempty(shared_link_type_flag)) {
     this->LinkTypeEnabled = true;
     this->StaticLinkTypeFlag = static_link_type_flag;
     this->SharedLinkTypeFlag = shared_link_type_flag;
@@ -841,7 +840,7 @@
 
   // Lookup the starting link type from the target (linked statically?).
   cmProp lss = this->Target->GetProperty("LINK_SEARCH_START_STATIC");
-  this->StartLinkType = (lss && cmIsOn(*lss)) ? LinkStatic : LinkShared;
+  this->StartLinkType = cmIsOn(lss) ? LinkStatic : LinkShared;
   this->CurrentLinkType = this->StartLinkType;
 }
 
@@ -849,31 +848,31 @@
 {
   // Get possible library name prefixes.
   cmMakefile* mf = this->Makefile;
-  this->AddLinkPrefix(mf->GetDefinition("CMAKE_STATIC_LIBRARY_PREFIX"));
-  this->AddLinkPrefix(mf->GetDefinition("CMAKE_SHARED_LIBRARY_PREFIX"));
+  this->AddLinkPrefix(mf->GetSafeDefinition("CMAKE_STATIC_LIBRARY_PREFIX"));
+  this->AddLinkPrefix(mf->GetSafeDefinition("CMAKE_SHARED_LIBRARY_PREFIX"));
 
   // Import library names should be matched and treated as shared
   // libraries for the purposes of linking.
-  this->AddLinkExtension(mf->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX"),
+  this->AddLinkExtension(mf->GetSafeDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX"),
                          LinkShared);
-  this->AddLinkExtension(mf->GetDefinition("CMAKE_STATIC_LIBRARY_SUFFIX"),
+  this->AddLinkExtension(mf->GetSafeDefinition("CMAKE_STATIC_LIBRARY_SUFFIX"),
                          LinkStatic);
-  this->AddLinkExtension(mf->GetDefinition("CMAKE_SHARED_LIBRARY_SUFFIX"),
+  this->AddLinkExtension(mf->GetSafeDefinition("CMAKE_SHARED_LIBRARY_SUFFIX"),
                          LinkShared);
-  this->AddLinkExtension(mf->GetDefinition("CMAKE_LINK_LIBRARY_SUFFIX"),
+  this->AddLinkExtension(mf->GetSafeDefinition("CMAKE_LINK_LIBRARY_SUFFIX"),
                          LinkUnknown);
   if (const char* linkSuffixes =
         mf->GetDefinition("CMAKE_EXTRA_LINK_EXTENSIONS")) {
     std::vector<std::string> linkSuffixVec = cmExpandedList(linkSuffixes);
     for (std::string const& i : linkSuffixVec) {
-      this->AddLinkExtension(i.c_str(), LinkUnknown);
+      this->AddLinkExtension(i, LinkUnknown);
     }
   }
   if (const char* sharedSuffixes =
         mf->GetDefinition("CMAKE_EXTRA_SHARED_LIBRARY_SUFFIXES")) {
     std::vector<std::string> sharedSuffixVec = cmExpandedList(sharedSuffixes);
     for (std::string const& i : sharedSuffixVec) {
-      this->AddLinkExtension(i.c_str(), LinkShared);
+      this->AddLinkExtension(i, LinkShared);
     }
   }
 
@@ -903,7 +902,7 @@
 #ifdef CM_COMPUTE_LINK_INFO_DEBUG
   fprintf(stderr, "any regex [%s]\n", reg_any.c_str());
 #endif
-  this->ExtractAnyLibraryName.compile(reg_any.c_str());
+  this->ExtractAnyLibraryName.compile(reg_any);
 
   // Create a regex to match static library names.
   if (!this->StaticLinkExtensions.empty()) {
@@ -912,7 +911,7 @@
 #ifdef CM_COMPUTE_LINK_INFO_DEBUG
     fprintf(stderr, "static regex [%s]\n", reg_static.c_str());
 #endif
-    this->ExtractStaticLibraryName.compile(reg_static.c_str());
+    this->ExtractStaticLibraryName.compile(reg_static);
   }
 
   // Create a regex to match shared library names.
@@ -924,20 +923,21 @@
 #ifdef CM_COMPUTE_LINK_INFO_DEBUG
     fprintf(stderr, "shared regex [%s]\n", reg_shared.c_str());
 #endif
-    this->ExtractSharedLibraryName.compile(reg_shared.c_str());
+    this->ExtractSharedLibraryName.compile(reg_shared);
   }
 }
 
-void cmComputeLinkInformation::AddLinkPrefix(const char* p)
+void cmComputeLinkInformation::AddLinkPrefix(std::string const& p)
 {
-  if (p && *p) {
+  if (!p.empty()) {
     this->LinkPrefixes.insert(p);
   }
 }
 
-void cmComputeLinkInformation::AddLinkExtension(const char* e, LinkType type)
+void cmComputeLinkInformation::AddLinkExtension(std::string const& e,
+                                                LinkType type)
 {
-  if (e && *e) {
+  if (!e.empty()) {
     if (type == LinkStatic) {
       this->StaticLinkExtensions.emplace_back(e);
     }
@@ -962,7 +962,7 @@
     // Store this extension choice with the "." escaped.
     libext += "\\";
 #if defined(_WIN32) && !defined(__CYGWIN__)
-    libext += this->NoCaseExpression(i.c_str());
+    libext += this->NoCaseExpression(i);
 #else
     libext += i;
 #endif
@@ -980,21 +980,19 @@
   return libext;
 }
 
-std::string cmComputeLinkInformation::NoCaseExpression(const char* str)
+std::string cmComputeLinkInformation::NoCaseExpression(std::string const& str)
 {
   std::string ret;
-  ret.reserve(strlen(str) * 4);
-  const char* s = str;
-  while (*s) {
-    if (*s == '.') {
-      ret += *s;
+  ret.reserve(str.size() * 4);
+  for (char c : str) {
+    if (c == '.') {
+      ret += c;
     } else {
       ret += '[';
-      ret += static_cast<char>(tolower(*s));
-      ret += static_cast<char>(toupper(*s));
+      ret += static_cast<char>(tolower(c));
+      ret += static_cast<char>(toupper(c));
       ret += ']';
     }
-    s++;
   }
   return ret;
 }
@@ -1688,7 +1686,7 @@
   }
 }
 
-static void cmCLI_ExpandListUnique(const char* str,
+static void cmCLI_ExpandListUnique(std::string const& str,
                                    std::vector<std::string>& out,
                                    std::set<std::string>& emitted)
 {
@@ -1735,7 +1733,7 @@
   if (use_install_rpath) {
     std::string install_rpath;
     this->Target->GetInstallRPATH(this->Config, install_rpath);
-    cmCLI_ExpandListUnique(install_rpath.c_str(), runtimeDirs, emitted);
+    cmCLI_ExpandListUnique(install_rpath, runtimeDirs, emitted);
   }
   if (use_build_rpath) {
     // Add directories explicitly specified by user
@@ -1743,7 +1741,7 @@
     if (this->Target->GetBuildRPATH(this->Config, build_rpath)) {
       // This will not resolve entries to use $ORIGIN, the user is expected to
       // do that if necessary.
-      cmCLI_ExpandListUnique(build_rpath.c_str(), runtimeDirs, emitted);
+      cmCLI_ExpandListUnique(build_rpath, runtimeDirs, emitted);
     }
   }
   if (use_build_rpath || use_link_rpath) {
@@ -1769,7 +1767,7 @@
         std::string d = ri;
         if (!rootPath.empty() && cmHasPrefix(d, rootPath)) {
           d.erase(0, rootPath.size());
-        } else if (stagePath && *stagePath && cmHasPrefix(d, stagePath)) {
+        } else if (cmNonempty(stagePath) && cmHasPrefix(d, stagePath)) {
           d.erase(0, strlen(stagePath));
           d = cmStrCat(installPrefix, '/', d);
           cmSystemTools::ConvertToUnixSlashes(d);
@@ -1800,7 +1798,7 @@
           std::string d = ri;
           if (!rootPath.empty() && cmHasPrefix(d, rootPath)) {
             d.erase(0, rootPath.size());
-          } else if (stagePath && *stagePath && cmHasPrefix(d, stagePath)) {
+          } else if (cmNonempty(stagePath) && cmHasPrefix(d, stagePath)) {
             d.erase(0, strlen(stagePath));
             d = cmStrCat(installPrefix, '/', d);
             cmSystemTools::ConvertToUnixSlashes(d);
@@ -1823,8 +1821,8 @@
         "CMAKE_" + li + "_USE_IMPLICIT_LINK_DIRECTORIES_IN_RUNTIME_PATH";
       if (this->Makefile->IsOn(useVar)) {
         std::string dirVar = "CMAKE_" + li + "_IMPLICIT_LINK_DIRECTORIES";
-        if (const char* dirs = this->Makefile->GetDefinition(dirVar)) {
-          cmCLI_ExpandListUnique(dirs, runtimeDirs, emitted);
+        if (cmProp dirs = this->Makefile->GetDef(dirVar)) {
+          cmCLI_ExpandListUnique(*dirs, runtimeDirs, emitted);
         }
       }
     }
@@ -1832,7 +1830,7 @@
 
   // Add runtime paths required by the platform to always be
   // present.  This is done even when skipping rpath support.
-  cmCLI_ExpandListUnique(this->RuntimeAlways.c_str(), runtimeDirs, emitted);
+  cmCLI_ExpandListUnique(this->RuntimeAlways, runtimeDirs, emitted);
 }
 
 std::string cmComputeLinkInformation::GetRPathString(bool for_install) const
diff --git a/Source/cmComputeLinkInformation.h b/Source/cmComputeLinkInformation.h
index e50d369..544ff23 100644
--- a/Source/cmComputeLinkInformation.h
+++ b/Source/cmComputeLinkInformation.h
@@ -144,11 +144,11 @@
   cmsys::RegularExpression ExtractSharedLibraryName;
   cmsys::RegularExpression ExtractAnyLibraryName;
   std::string SharedRegexString;
-  void AddLinkPrefix(const char* p);
-  void AddLinkExtension(const char* e, LinkType type);
+  void AddLinkPrefix(std::string const& p);
+  void AddLinkExtension(std::string const& e, LinkType type);
   std::string CreateExtensionRegex(std::vector<std::string> const& exts,
                                    LinkType type);
-  std::string NoCaseExpression(const char* str);
+  std::string NoCaseExpression(std::string const& str);
 
   // Handling of link items.
   void AddTargetItem(BT<std::string> const& item,
diff --git a/Source/cmComputeTargetDepends.cxx b/Source/cmComputeTargetDepends.cxx
index 41f5346..e717f71 100644
--- a/Source/cmComputeTargetDepends.cxx
+++ b/Source/cmComputeTargetDepends.cxx
@@ -118,6 +118,7 @@
 
   // Identify components.
   cmComputeComponentGraph ccg(this->InitialGraph);
+  ccg.Compute();
   if (this->DebugMode) {
     this->DisplayComponents(ccg);
   }
@@ -184,7 +185,7 @@
 {
   // Get the depender.
   cmGeneratorTarget const* depender = this->Targets[depender_index];
-  if (depender->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+  if (!depender->IsInBuildSystem()) {
     return;
   }
 
@@ -196,18 +197,20 @@
     std::set<cmLinkItem> emitted;
 
     std::vector<std::string> const& configs =
-      depender->Makefile->GetGeneratorConfigs();
+      depender->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
     for (std::string const& it : configs) {
-      cmLinkImplementation const* impl = depender->GetLinkImplementation(it);
-
       // A target should not depend on itself.
       emitted.insert(cmLinkItem(depender, false, cmListFileBacktrace()));
       emitted.insert(cmLinkItem(depender, true, cmListFileBacktrace()));
-      for (cmLinkImplItem const& lib : impl->Libraries) {
-        // Don't emit the same library twice for this target.
-        if (emitted.insert(lib).second) {
-          this->AddTargetDepend(depender_index, lib, true, false);
-          this->AddInterfaceDepends(depender_index, lib, it, emitted);
+
+      if (cmLinkImplementation const* impl =
+            depender->GetLinkImplementation(it)) {
+        for (cmLinkImplItem const& lib : impl->Libraries) {
+          // Don't emit the same library twice for this target.
+          if (emitted.insert(lib).second) {
+            this->AddTargetDepend(depender_index, lib, true, false);
+            this->AddInterfaceDepends(depender_index, lib, it, emitted);
+          }
         }
       }
 
@@ -356,10 +359,9 @@
   int depender_index, cmGeneratorTarget const* dependee,
   cmListFileBacktrace const& dependee_backtrace, bool linking, bool cross)
 {
-  if (dependee->IsImported() ||
-      dependee->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
-    // Skip IMPORTED and INTERFACE targets but follow their utility
-    // dependencies.
+  if (!dependee->IsInBuildSystem()) {
+    // Skip targets that are not in the buildsystem but follow their
+    // utility dependencies.
     std::set<cmLinkItem> const& utils = dependee->GetUtilityItems();
     for (cmLinkItem const& i : utils) {
       if (cmGeneratorTarget const* transitive_dependee = i.Target) {
diff --git a/Source/cmConfigure.cmake.h.in b/Source/cmConfigure.cmake.h.in
index 4de1c5d..97e7856 100644
--- a/Source/cmConfigure.cmake.h.in
+++ b/Source/cmConfigure.cmake.h.in
@@ -19,7 +19,6 @@
 #cmakedefine HAVE_UNSETENV
 #cmakedefine CMAKE_USE_ELF_PARSER
 #cmakedefine CMAKE_USE_MACH_PARSER
-#cmakedefine CMake_HAVE_CXX_MAKE_UNIQUE
 #define CMake_DEFAULT_RECURSION_LIMIT @CMake_DEFAULT_RECURSION_LIMIT@
 #define CMAKE_BIN_DIR "/@CMAKE_BIN_DIR@"
 #define CMAKE_DATA_DIR "/@CMAKE_DATA_DIR@"
diff --git a/Source/cmConfigureFileCommand.cxx b/Source/cmConfigureFileCommand.cxx
index 5b3045d..68322cc 100644
--- a/Source/cmConfigureFileCommand.cxx
+++ b/Source/cmConfigureFileCommand.cxx
@@ -60,6 +60,7 @@
   }
   bool copyOnly = false;
   bool escapeQuotes = false;
+  bool use_source_permissions = true;
 
   static std::set<cm::string_view> noopOptions = {
     /* Legacy.  */
@@ -87,6 +88,8 @@
       escapeQuotes = true;
     } else if (args[i] == "@ONLY") {
       atOnly = true;
+    } else if (args[i] == "NO_SOURCE_PERMISSIONS") {
+      use_source_permissions = false;
     } else if (noopOptions.find(args[i]) != noopOptions.end()) {
       /* Ignore no-op options.  */
     } else {
@@ -102,7 +105,8 @@
   }
 
   if (!status.GetMakefile().ConfigureFile(
-        inputFile, outputFile, copyOnly, atOnly, escapeQuotes, newLineStyle)) {
+        inputFile, outputFile, copyOnly, atOnly, escapeQuotes,
+        use_source_permissions, newLineStyle)) {
     status.SetError("Problem configuring file");
     return false;
   }
diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx
index 8550d04..63c1484 100644
--- a/Source/cmCoreTryCompile.cxx
+++ b/Source/cmCoreTryCompile.cxx
@@ -18,6 +18,7 @@
 #include "cmMessageType.h"
 #include "cmOutputConverter.h"
 #include "cmPolicies.h"
+#include "cmProperty.h"
 #include "cmState.h"
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
@@ -25,77 +26,205 @@
 #include "cmVersion.h"
 #include "cmake.h"
 
-static std::string const kCMAKE_C_COMPILER_EXTERNAL_TOOLCHAIN =
-  "CMAKE_C_COMPILER_EXTERNAL_TOOLCHAIN";
-static std::string const kCMAKE_C_COMPILER_TARGET = "CMAKE_C_COMPILER_TARGET";
-static std::string const kCMAKE_C_LINK_NO_PIE_SUPPORTED =
-  "CMAKE_C_LINK_NO_PIE_SUPPORTED";
-static std::string const kCMAKE_C_LINK_PIE_SUPPORTED =
-  "CMAKE_C_LINK_PIE_SUPPORTED";
-static std::string const kCMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN =
-  "CMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN";
-static std::string const kCMAKE_CXX_COMPILER_TARGET =
-  "CMAKE_CXX_COMPILER_TARGET";
-static std::string const kCMAKE_CXX_LINK_NO_PIE_SUPPORTED =
-  "CMAKE_CXX_LINK_NO_PIE_SUPPORTED";
-static std::string const kCMAKE_CXX_LINK_PIE_SUPPORTED =
-  "CMAKE_CXX_LINK_PIE_SUPPORTED";
-static std::string const kCMAKE_CUDA_ARCHITECTURES =
-  "CMAKE_CUDA_ARCHITECTURES";
-static std::string const kCMAKE_CUDA_COMPILER_TARGET =
-  "CMAKE_CUDA_COMPILER_TARGET";
-static std::string const kCMAKE_CUDA_RUNTIME_LIBRARY =
-  "CMAKE_CUDA_RUNTIME_LIBRARY";
-static std::string const kCMAKE_ENABLE_EXPORTS = "CMAKE_ENABLE_EXPORTS";
-static std::string const kCMAKE_LINK_SEARCH_END_STATIC =
+namespace {
+class LanguageStandardState
+{
+public:
+  LanguageStandardState(std::string&& lang)
+    : IsEnabled(false)
+    , DidStandard(false)
+    , DidStandardRequired(false)
+    , DidExtensions(false)
+    , StandardFlag(lang + "_STANDARD")
+    , RequiredFlag(lang + "_STANDARD_REQUIRED")
+    , ExtensionFlag(lang + "_EXTENSIONS")
+  {
+  }
+
+  void Enabled(bool isEnabled) { this->IsEnabled = isEnabled; }
+
+  bool UpdateIfMatches(std::vector<std::string> const& argv, size_t& index)
+  {
+    bool updated = false;
+    if (argv[index] == this->StandardFlag) {
+      this->DidStandard = true;
+      this->StandardValue = argv[++index];
+      updated = true;
+    } else if (argv[index] == this->RequiredFlag) {
+      this->DidStandardRequired = true;
+      this->RequiredValue = argv[++index];
+      updated = true;
+    } else if (argv[index] == this->ExtensionFlag) {
+      this->DidExtensions = true;
+      this->ExtensionValue = argv[++index];
+      updated = true;
+    }
+    return updated;
+  }
+
+  bool Validate(cmMakefile* const makefile) const
+  {
+    if (this->DidStandard) {
+      makefile->IssueMessage(
+        MessageType::FATAL_ERROR,
+        cmStrCat(this->StandardFlag,
+                 " allowed only in source file signature."));
+      return false;
+    }
+    if (this->DidStandardRequired) {
+      makefile->IssueMessage(
+        MessageType::FATAL_ERROR,
+        cmStrCat(this->RequiredFlag,
+                 " allowed only in source file signature."));
+      return false;
+    }
+    if (this->DidExtensions) {
+      makefile->IssueMessage(
+        MessageType::FATAL_ERROR,
+        cmStrCat(this->ExtensionFlag,
+                 " allowed only in source file signature."));
+      return false;
+    }
+
+    return true;
+  }
+
+  bool DidNone() const
+  {
+    return !this->DidStandard && !this->DidStandardRequired &&
+      !this->DidExtensions;
+  }
+
+  void LoadUnsetPropertyValues(cmMakefile* const makefile, bool honorStandard,
+                               bool warnCMP0067,
+                               std::vector<std::string>& warnCMP0067Variables)
+  {
+    if (!this->IsEnabled) {
+      return;
+    }
+
+    auto lookupStdVar = [&](std::string const& var) -> std::string {
+      std::string value = makefile->GetSafeDefinition(var);
+      if (warnCMP0067 && !value.empty()) {
+        value.clear();
+        warnCMP0067Variables.push_back(var);
+      }
+      return value;
+    };
+
+    if (honorStandard || warnCMP0067) {
+      if (!this->DidStandard) {
+        this->StandardValue =
+          lookupStdVar(cmStrCat("CMAKE_", this->StandardFlag));
+      }
+      if (!this->DidStandardRequired) {
+        this->RequiredValue =
+          lookupStdVar(cmStrCat("CMAKE_", this->RequiredFlag));
+      }
+      if (!this->DidExtensions) {
+        this->ExtensionValue =
+          lookupStdVar(cmStrCat("CMAKE_", this->ExtensionFlag));
+      }
+    }
+  }
+
+  void WriteProperties(FILE* fout, std::string const& targetName) const
+  {
+    if (!this->IsEnabled) {
+      return;
+    }
+
+    auto writeProp = [&](std::string const& prop, std::string const& value) {
+      fprintf(fout, "set_property(TARGET %s PROPERTY %s %s)\n",
+              targetName.c_str(),
+              cmOutputConverter::EscapeForCMake(prop).c_str(),
+              cmOutputConverter::EscapeForCMake(value).c_str());
+    };
+
+    if (!this->StandardValue.empty()) {
+      writeProp(this->StandardFlag, this->StandardValue);
+    }
+    if (!this->RequiredValue.empty()) {
+      writeProp(this->RequiredFlag, this->RequiredValue);
+    }
+    if (!this->ExtensionValue.empty()) {
+      writeProp(this->ExtensionFlag, this->ExtensionValue);
+    }
+  }
+
+private:
+  bool IsEnabled;
+  bool DidStandard;
+  bool DidStandardRequired;
+  bool DidExtensions;
+
+  std::string StandardFlag;
+  std::string RequiredFlag;
+  std::string ExtensionFlag;
+
+  std::string StandardValue;
+  std::string RequiredValue;
+  std::string ExtensionValue;
+};
+
+constexpr size_t lang_property_start = 0;
+constexpr size_t lang_property_size = 4;
+constexpr size_t pie_property_start = 4;
+constexpr size_t pie_property_size = 2;
+#define SETUP_LANGUAGE(name, lang)                                            \
+  static const std::string name[lang_property_size + pie_property_size + 1] = \
+    { "CMAKE_" #lang "_COMPILER_EXTERNAL_TOOLCHAIN",                          \
+      "CMAKE_" #lang "_COMPILER_TARGET",                                      \
+      "CMAKE_" #lang "_LINK_NO_PIE_SUPPORTED",                                \
+      "CMAKE_" #lang "_PIE_SUPPORTED", "" }
+
+// NOLINTNEXTLINE(bugprone-suspicious-missing-comma)
+SETUP_LANGUAGE(c_properties, C);
+// NOLINTNEXTLINE(bugprone-suspicious-missing-comma)
+SETUP_LANGUAGE(cxx_properties, CXX);
+
+// NOLINTNEXTLINE(bugprone-suspicious-missing-comma)
+SETUP_LANGUAGE(cuda_properties, CUDA);
+// NOLINTNEXTLINE(bugprone-suspicious-missing-comma)
+SETUP_LANGUAGE(fortran_properties, Fortran);
+// NOLINTNEXTLINE(bugprone-suspicious-missing-comma)
+SETUP_LANGUAGE(objc_properties, OBJC);
+// NOLINTNEXTLINE(bugprone-suspicious-missing-comma)
+SETUP_LANGUAGE(objcxx_properties, OBJCXX);
+// NOLINTNEXTLINE(bugprone-suspicious-missing-comma)
+SETUP_LANGUAGE(swift_properties, Swift);
+#undef SETUP_LANGUAGE
+
+std::string const kCMAKE_CUDA_ARCHITECTURES = "CMAKE_CUDA_ARCHITECTURES";
+std::string const kCMAKE_CUDA_RUNTIME_LIBRARY = "CMAKE_CUDA_RUNTIME_LIBRARY";
+std::string const kCMAKE_ENABLE_EXPORTS = "CMAKE_ENABLE_EXPORTS";
+std::string const kCMAKE_LINK_SEARCH_END_STATIC =
   "CMAKE_LINK_SEARCH_END_STATIC";
-static std::string const kCMAKE_LINK_SEARCH_START_STATIC =
+std::string const kCMAKE_LINK_SEARCH_START_STATIC =
   "CMAKE_LINK_SEARCH_START_STATIC";
-static std::string const kCMAKE_MSVC_RUNTIME_LIBRARY_DEFAULT =
+std::string const kCMAKE_MSVC_RUNTIME_LIBRARY_DEFAULT =
   "CMAKE_MSVC_RUNTIME_LIBRARY_DEFAULT";
-static std::string const kCMAKE_OSX_ARCHITECTURES = "CMAKE_OSX_ARCHITECTURES";
-static std::string const kCMAKE_OSX_DEPLOYMENT_TARGET =
-  "CMAKE_OSX_DEPLOYMENT_TARGET";
-static std::string const kCMAKE_OSX_SYSROOT = "CMAKE_OSX_SYSROOT";
-static std::string const kCMAKE_APPLE_ARCH_SYSROOTS =
-  "CMAKE_APPLE_ARCH_SYSROOTS";
-static std::string const kCMAKE_POSITION_INDEPENDENT_CODE =
+std::string const kCMAKE_OSX_ARCHITECTURES = "CMAKE_OSX_ARCHITECTURES";
+std::string const kCMAKE_OSX_DEPLOYMENT_TARGET = "CMAKE_OSX_DEPLOYMENT_TARGET";
+std::string const kCMAKE_OSX_SYSROOT = "CMAKE_OSX_SYSROOT";
+std::string const kCMAKE_APPLE_ARCH_SYSROOTS = "CMAKE_APPLE_ARCH_SYSROOTS";
+std::string const kCMAKE_POSITION_INDEPENDENT_CODE =
   "CMAKE_POSITION_INDEPENDENT_CODE";
-static std::string const kCMAKE_SYSROOT = "CMAKE_SYSROOT";
-static std::string const kCMAKE_SYSROOT_COMPILE = "CMAKE_SYSROOT_COMPILE";
-static std::string const kCMAKE_SYSROOT_LINK = "CMAKE_SYSROOT_LINK";
-static std::string const kCMAKE_Swift_COMPILER_TARGET =
-  "CMAKE_Swift_COMPILER_TARGET";
-static std::string const kCMAKE_TRY_COMPILE_OSX_ARCHITECTURES =
+std::string const kCMAKE_SYSROOT = "CMAKE_SYSROOT";
+std::string const kCMAKE_SYSROOT_COMPILE = "CMAKE_SYSROOT_COMPILE";
+std::string const kCMAKE_SYSROOT_LINK = "CMAKE_SYSROOT_LINK";
+std::string const kCMAKE_TRY_COMPILE_OSX_ARCHITECTURES =
   "CMAKE_TRY_COMPILE_OSX_ARCHITECTURES";
-static std::string const kCMAKE_TRY_COMPILE_PLATFORM_VARIABLES =
+std::string const kCMAKE_TRY_COMPILE_PLATFORM_VARIABLES =
   "CMAKE_TRY_COMPILE_PLATFORM_VARIABLES";
-static std::string const kCMAKE_WARN_DEPRECATED = "CMAKE_WARN_DEPRECATED";
+std::string const kCMAKE_WARN_DEPRECATED = "CMAKE_WARN_DEPRECATED";
 
 /* GHS Multi platform variables */
-static std::set<std::string> ghs_platform_vars{
+std::set<std::string> const ghs_platform_vars{
   "GHS_TARGET_PLATFORM", "GHS_PRIMARY_TARGET", "GHS_TOOLSET_ROOT",
   "GHS_OS_ROOT",         "GHS_OS_DIR",         "GHS_BSP_NAME",
   "GHS_OS_DIR_OPTION"
 };
-
-static void writeProperty(FILE* fout, std::string const& targetName,
-                          std::string const& prop, std::string const& value)
-{
-  fprintf(fout, "set_property(TARGET %s PROPERTY %s %s)\n", targetName.c_str(),
-          cmOutputConverter::EscapeForCMake(prop).c_str(),
-          cmOutputConverter::EscapeForCMake(value).c_str());
-}
-
-std::string cmCoreTryCompile::LookupStdVar(std::string const& var,
-                                           bool warnCMP0067)
-{
-  std::string value = this->Makefile->GetSafeDefinition(var);
-  if (warnCMP0067 && !value.empty()) {
-    value.clear();
-    this->WarnCMP0067.push_back(var);
-  }
-  return value;
 }
 
 int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
@@ -107,9 +236,8 @@
   this->SrcFileSignature = true;
 
   cmStateEnums::TargetType targetType = cmStateEnums::EXECUTABLE;
-  const std::string* tt =
-    this->Makefile->GetDef("CMAKE_TRY_COMPILE_TARGET_TYPE");
-  if (!isTryRun && tt && !tt->empty()) {
+  cmProp tt = this->Makefile->GetDef("CMAKE_TRY_COMPILE_TARGET_TYPE");
+  if (!isTryRun && cmNonempty(tt)) {
     if (*tt == cmState::GetTargetTypeName(cmStateEnums::EXECUTABLE)) {
       targetType = cmStateEnums::EXECUTABLE;
     } else if (*tt ==
@@ -137,21 +265,11 @@
   std::string outputVariable;
   std::string copyFile;
   std::string copyFileError;
-  std::string cStandard;
-  std::string objcStandard;
-  std::string cxxStandard;
-  std::string objcxxStandard;
-  std::string cudaStandard;
-  std::string cStandardRequired;
-  std::string cxxStandardRequired;
-  std::string objcStandardRequired;
-  std::string objcxxStandardRequired;
-  std::string cudaStandardRequired;
-  std::string cExtensions;
-  std::string cxxExtensions;
-  std::string objcExtensions;
-  std::string objcxxExtensions;
-  std::string cudaExtensions;
+  LanguageStandardState cState("C");
+  LanguageStandardState cudaState("CUDA");
+  LanguageStandardState cxxState("CXX");
+  LanguageStandardState objcState("OBJC");
+  LanguageStandardState objcxxState("OBJCXX");
   std::vector<std::string> targets;
   std::vector<std::string> linkOptions;
   std::string libsToLink = " ";
@@ -160,21 +278,6 @@
   bool didOutputVariable = false;
   bool didCopyFile = false;
   bool didCopyFileError = false;
-  bool didCStandard = false;
-  bool didCxxStandard = false;
-  bool didObjCStandard = false;
-  bool didObjCxxStandard = false;
-  bool didCudaStandard = false;
-  bool didCStandardRequired = false;
-  bool didCxxStandardRequired = false;
-  bool didObjCStandardRequired = false;
-  bool didObjCxxStandardRequired = false;
-  bool didCudaStandardRequired = false;
-  bool didCExtensions = false;
-  bool didCxxExtensions = false;
-  bool didObjCExtensions = false;
-  bool didObjCxxExtensions = false;
-  bool didCudaExtensions = false;
   bool useSources = argv[2] == "SOURCES";
   std::vector<std::string> sources;
 
@@ -188,21 +291,6 @@
     DoingOutputVariable,
     DoingCopyFile,
     DoingCopyFileError,
-    DoingCStandard,
-    DoingCxxStandard,
-    DoingObjCStandard,
-    DoingObjCxxStandard,
-    DoingCudaStandard,
-    DoingCStandardRequired,
-    DoingCxxStandardRequired,
-    DoingObjCStandardRequired,
-    DoingObjCxxStandardRequired,
-    DoingCudaStandardRequired,
-    DoingCExtensions,
-    DoingCxxExtensions,
-    DoingObjCExtensions,
-    DoingObjCxxExtensions,
-    DoingCudaExtensions,
     DoingSources,
     DoingCMakeInternal
   };
@@ -226,51 +314,12 @@
     } else if (argv[i] == "COPY_FILE_ERROR") {
       doing = DoingCopyFileError;
       didCopyFileError = true;
-    } else if (argv[i] == "C_STANDARD") {
-      doing = DoingCStandard;
-      didCStandard = true;
-    } else if (argv[i] == "CXX_STANDARD") {
-      doing = DoingCxxStandard;
-      didCxxStandard = true;
-    } else if (argv[i] == "OBJC_STANDARD") {
-      doing = DoingObjCStandard;
-      didObjCStandard = true;
-    } else if (argv[i] == "OBJCXX_STANDARD") {
-      doing = DoingObjCxxStandard;
-      didObjCxxStandard = true;
-    } else if (argv[i] == "CUDA_STANDARD") {
-      doing = DoingCudaStandard;
-      didCudaStandard = true;
-    } else if (argv[i] == "C_STANDARD_REQUIRED") {
-      doing = DoingCStandardRequired;
-      didCStandardRequired = true;
-    } else if (argv[i] == "CXX_STANDARD_REQUIRED") {
-      doing = DoingCxxStandardRequired;
-      didCxxStandardRequired = true;
-    } else if (argv[i] == "OBJC_STANDARD_REQUIRED") {
-      doing = DoingObjCStandardRequired;
-      didObjCStandardRequired = true;
-    } else if (argv[i] == "OBJCXX_STANDARD_REQUIRED") {
-      doing = DoingObjCxxStandardRequired;
-      didObjCxxStandardRequired = true;
-    } else if (argv[i] == "CUDA_STANDARD_REQUIRED") {
-      doing = DoingCudaStandardRequired;
-      didCudaStandardRequired = true;
-    } else if (argv[i] == "C_EXTENSIONS") {
-      doing = DoingCExtensions;
-      didCExtensions = true;
-    } else if (argv[i] == "CXX_EXTENSIONS") {
-      doing = DoingCxxExtensions;
-      didCxxExtensions = true;
-    } else if (argv[i] == "OBJC_EXTENSIONS") {
-      doing = DoingObjCExtensions;
-      didObjCExtensions = true;
-    } else if (argv[i] == "OBJCXX_EXTENSIONS") {
-      doing = DoingObjCxxExtensions;
-      didObjCxxExtensions = true;
-    } else if (argv[i] == "CUDA_EXTENSIONS") {
-      doing = DoingCudaExtensions;
-      didCudaExtensions = true;
+    } else if (cState.UpdateIfMatches(argv, i) ||
+               cxxState.UpdateIfMatches(argv, i) ||
+               cudaState.UpdateIfMatches(argv, i) ||
+               objcState.UpdateIfMatches(argv, i) ||
+               objcxxState.UpdateIfMatches(argv, i)) {
+      continue;
     } else if (argv[i] == "__CMAKE_INTERNAL") {
       doing = DoingCMakeInternal;
     } else if (doing == DoingCMakeFlags) {
@@ -315,51 +364,6 @@
     } else if (doing == DoingCopyFileError) {
       copyFileError = argv[i];
       doing = DoingNone;
-    } else if (doing == DoingCStandard) {
-      cStandard = argv[i];
-      doing = DoingNone;
-    } else if (doing == DoingCxxStandard) {
-      cxxStandard = argv[i];
-      doing = DoingNone;
-    } else if (doing == DoingObjCStandard) {
-      objcStandard = argv[i];
-      doing = DoingNone;
-    } else if (doing == DoingObjCxxStandard) {
-      objcxxStandard = argv[i];
-      doing = DoingNone;
-    } else if (doing == DoingCudaStandard) {
-      cudaStandard = argv[i];
-      doing = DoingNone;
-    } else if (doing == DoingCStandardRequired) {
-      cStandardRequired = argv[i];
-      doing = DoingNone;
-    } else if (doing == DoingCxxStandardRequired) {
-      cxxStandardRequired = argv[i];
-      doing = DoingNone;
-    } else if (doing == DoingObjCStandardRequired) {
-      objcStandardRequired = argv[i];
-      doing = DoingNone;
-    } else if (doing == DoingObjCxxStandardRequired) {
-      objcxxStandardRequired = argv[i];
-      doing = DoingNone;
-    } else if (doing == DoingCudaStandardRequired) {
-      cudaStandardRequired = argv[i];
-      doing = DoingNone;
-    } else if (doing == DoingCExtensions) {
-      cExtensions = argv[i];
-      doing = DoingNone;
-    } else if (doing == DoingCxxExtensions) {
-      cxxExtensions = argv[i];
-      doing = DoingNone;
-    } else if (doing == DoingObjCExtensions) {
-      objcExtensions = argv[i];
-      doing = DoingNone;
-    } else if (doing == DoingObjCxxExtensions) {
-      objcxxExtensions = argv[i];
-      doing = DoingNone;
-    } else if (doing == DoingCudaExtensions) {
-      cudaExtensions = argv[i];
-      doing = DoingNone;
     } else if (doing == DoingSources) {
       sources.push_back(argv[i]);
     } else if (doing == DoingCMakeInternal) {
@@ -411,59 +415,22 @@
     return -1;
   }
 
-  if (didCStandard && !this->SrcFileSignature) {
-    this->Makefile->IssueMessage(
-      MessageType::FATAL_ERROR,
-      "C_STANDARD allowed only in source file signature.");
-    return -1;
-  }
-  if (didCxxStandard && !this->SrcFileSignature) {
-    this->Makefile->IssueMessage(
-      MessageType::FATAL_ERROR,
-      "CXX_STANDARD allowed only in source file signature.");
-    return -1;
-  }
-  if (didCudaStandard && !this->SrcFileSignature) {
-    this->Makefile->IssueMessage(
-      MessageType::FATAL_ERROR,
-      "CUDA_STANDARD allowed only in source file signature.");
-    return -1;
-  }
-  if (didCStandardRequired && !this->SrcFileSignature) {
-    this->Makefile->IssueMessage(
-      MessageType::FATAL_ERROR,
-      "C_STANDARD_REQUIRED allowed only in source file signature.");
-    return -1;
-  }
-  if (didCxxStandardRequired && !this->SrcFileSignature) {
-    this->Makefile->IssueMessage(
-      MessageType::FATAL_ERROR,
-      "CXX_STANDARD_REQUIRED allowed only in source file signature.");
-    return -1;
-  }
-  if (didCudaStandardRequired && !this->SrcFileSignature) {
-    this->Makefile->IssueMessage(
-      MessageType::FATAL_ERROR,
-      "CUDA_STANDARD_REQUIRED allowed only in source file signature.");
-    return -1;
-  }
-  if (didCExtensions && !this->SrcFileSignature) {
-    this->Makefile->IssueMessage(
-      MessageType::FATAL_ERROR,
-      "C_EXTENSIONS allowed only in source file signature.");
-    return -1;
-  }
-  if (didCxxExtensions && !this->SrcFileSignature) {
-    this->Makefile->IssueMessage(
-      MessageType::FATAL_ERROR,
-      "CXX_EXTENSIONS allowed only in source file signature.");
-    return -1;
-  }
-  if (didCudaExtensions && !this->SrcFileSignature) {
-    this->Makefile->IssueMessage(
-      MessageType::FATAL_ERROR,
-      "CUDA_EXTENSIONS allowed only in source file signature.");
-    return -1;
+  if (!this->SrcFileSignature) {
+    if (!cState.Validate(this->Makefile)) {
+      return -1;
+    }
+    if (!cudaState.Validate(this->Makefile)) {
+      return -1;
+    }
+    if (!cxxState.Validate(this->Makefile)) {
+      return -1;
+    }
+    if (!objcState.Validate(this->Makefile)) {
+      return -1;
+    }
+    if (!objcxxState.Validate(this->Makefile)) {
+      return -1;
+    }
   }
 
   // compute the binary dir when TRY_COMPILE is called with a src file
@@ -721,12 +688,23 @@
     // Forward a set of variables to the inner project cache.
     {
       std::set<std::string> vars;
-      vars.insert(kCMAKE_C_COMPILER_EXTERNAL_TOOLCHAIN);
-      vars.insert(kCMAKE_C_COMPILER_TARGET);
-      vars.insert(kCMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN);
-      vars.insert(kCMAKE_CXX_COMPILER_TARGET);
+      vars.insert(&c_properties[lang_property_start],
+                  &c_properties[lang_property_start + lang_property_size]);
+      vars.insert(&cxx_properties[lang_property_start],
+                  &cxx_properties[lang_property_start + lang_property_size]);
+      vars.insert(&cuda_properties[lang_property_start],
+                  &cuda_properties[lang_property_start + lang_property_size]);
+      vars.insert(
+        &fortran_properties[lang_property_start],
+        &fortran_properties[lang_property_start + lang_property_size]);
+      vars.insert(&objc_properties[lang_property_start],
+                  &objc_properties[lang_property_start + lang_property_size]);
+      vars.insert(
+        &objcxx_properties[lang_property_start],
+        &objcxx_properties[lang_property_start + lang_property_size]);
+      vars.insert(&swift_properties[lang_property_start],
+                  &swift_properties[lang_property_start + lang_property_size]);
       vars.insert(kCMAKE_CUDA_ARCHITECTURES);
-      vars.insert(kCMAKE_CUDA_COMPILER_TARGET);
       vars.insert(kCMAKE_CUDA_RUNTIME_LIBRARY);
       vars.insert(kCMAKE_ENABLE_EXPORTS);
       vars.insert(kCMAKE_LINK_SEARCH_END_STATIC);
@@ -739,7 +717,6 @@
       vars.insert(kCMAKE_SYSROOT);
       vars.insert(kCMAKE_SYSROOT_COMPILE);
       vars.insert(kCMAKE_SYSROOT_LINK);
-      vars.insert(kCMAKE_Swift_COMPILER_TARGET);
       vars.insert(kCMAKE_WARN_DEPRECATED);
       vars.emplace("CMAKE_MSVC_RUNTIME_LIBRARY"_s);
 
@@ -753,10 +730,22 @@
           cmPolicies::NEW) {
         // To ensure full support of PIE, propagate cache variables
         // driving the link options
-        vars.insert(kCMAKE_C_LINK_PIE_SUPPORTED);
-        vars.insert(kCMAKE_C_LINK_NO_PIE_SUPPORTED);
-        vars.insert(kCMAKE_CXX_LINK_PIE_SUPPORTED);
-        vars.insert(kCMAKE_CXX_LINK_NO_PIE_SUPPORTED);
+        vars.insert(&c_properties[pie_property_start],
+                    &c_properties[pie_property_start + pie_property_size]);
+        vars.insert(&cxx_properties[pie_property_start],
+                    &cxx_properties[pie_property_start + pie_property_size]);
+        vars.insert(&cuda_properties[pie_property_start],
+                    &cuda_properties[pie_property_start + pie_property_size]);
+        vars.insert(
+          &fortran_properties[pie_property_start],
+          &fortran_properties[pie_property_start + pie_property_size]);
+        vars.insert(&objc_properties[pie_property_start],
+                    &objc_properties[pie_property_start + pie_property_size]);
+        vars.insert(
+          &objcxx_properties[pie_property_start],
+          &objcxx_properties[pie_property_start + pie_property_size]);
+        vars.insert(&swift_properties[pie_property_start],
+                    &swift_properties[pie_property_start + pie_property_size]);
       }
 
       /* for the TRY_COMPILEs we want to be able to specify the architecture.
@@ -819,21 +808,17 @@
     }
     fprintf(fout, ")\n");
 
-    bool const testC = testLangs.find("C") != testLangs.end();
-    bool const testObjC = testLangs.find("OBJC") != testLangs.end();
-    bool const testCxx = testLangs.find("CXX") != testLangs.end();
-    bool const testObjCxx = testLangs.find("OBJCXX") != testLangs.end();
-    bool const testCuda = testLangs.find("CUDA") != testLangs.end();
+    cState.Enabled(testLangs.find("C") != testLangs.end());
+    cxxState.Enabled(testLangs.find("CXX") != testLangs.end());
+    cudaState.Enabled(testLangs.find("CUDA") != testLangs.end());
+    objcState.Enabled(testLangs.find("OBJC") != testLangs.end());
+    objcxxState.Enabled(testLangs.find("OBJCXX") != testLangs.end());
 
     bool warnCMP0067 = false;
     bool honorStandard = true;
 
-    if (!didCStandard && !didCxxStandard && !didObjCStandard &&
-        !didObjCxxStandard && !didCudaStandard && !didCStandardRequired &&
-        !didCxxStandardRequired && !didObjCStandardRequired &&
-        !didObjCxxStandardRequired && !didCudaStandardRequired &&
-        !didCExtensions && !didCxxExtensions && !didObjCExtensions &&
-        !didObjCxxExtensions && !didCudaExtensions) {
+    if (cState.DidNone() && cxxState.DidNone() && objcState.DidNone() &&
+        objcxxState.DidNone() && cudaState.DidNone()) {
       switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0067)) {
         case cmPolicies::WARN:
           warnCMP0067 = this->Makefile->PolicyOptionalWarningEnabled(
@@ -855,46 +840,20 @@
       }
     }
 
-    if (honorStandard || warnCMP0067) {
+    std::vector<std::string> warnCMP0067Variables;
 
-      auto testLanguage =
-        [&](bool testLang, bool didLangStandard, bool didLangStandardRequired,
-            bool didLangExtensions, std::string& langStandard,
-            std::string& langStandardRequired, std::string& langExtensions,
-            const std::string& lang) {
-          if (testLang) {
-            if (!didLangStandard) {
-              langStandard = this->LookupStdVar(
-                cmStrCat("CMAKE_", lang, "_STANDARD"), warnCMP0067);
-            }
-            if (!didLangStandardRequired) {
-              langStandardRequired = this->LookupStdVar(
-                cmStrCat("CMAKE_", lang, "_STANDARD_REQUIRED"), warnCMP0067);
-            }
-            if (!didLangExtensions) {
-              langExtensions = this->LookupStdVar(
-                cmStrCat("CMAKE_", lang, "_EXTENSIONS"), warnCMP0067);
-            }
-          }
-        };
+    cState.LoadUnsetPropertyValues(this->Makefile, honorStandard, warnCMP0067,
+                                   warnCMP0067Variables);
+    cxxState.LoadUnsetPropertyValues(this->Makefile, honorStandard,
+                                     warnCMP0067, warnCMP0067Variables);
+    cudaState.LoadUnsetPropertyValues(this->Makefile, honorStandard,
+                                      warnCMP0067, warnCMP0067Variables);
+    objcState.LoadUnsetPropertyValues(this->Makefile, honorStandard,
+                                      warnCMP0067, warnCMP0067Variables);
+    objcxxState.LoadUnsetPropertyValues(this->Makefile, honorStandard,
+                                        warnCMP0067, warnCMP0067Variables);
 
-      testLanguage(testC, didCStandard, didCStandardRequired, didCExtensions,
-                   cStandard, cStandardRequired, cExtensions, "C");
-      testLanguage(testObjC, didObjCStandard, didObjCStandardRequired,
-                   didObjCExtensions, objcStandard, objcStandardRequired,
-                   objcExtensions, "OBJC");
-      testLanguage(testCxx, didCxxStandard, didCxxStandardRequired,
-                   didCxxExtensions, cxxStandard, cxxStandardRequired,
-                   cxxExtensions, "CXX");
-      testLanguage(testObjCxx, didObjCxxStandard, didObjCxxStandardRequired,
-                   didObjCxxExtensions, objcxxStandard, objcxxStandardRequired,
-                   objcxxExtensions, "OBJCXX");
-      testLanguage(testCuda, didCudaStandard, didCudaStandardRequired,
-                   didCudaExtensions, cudaStandard, cudaStandardRequired,
-                   cudaExtensions, "CUDA");
-    }
-
-    if (!this->WarnCMP0067.empty()) {
+    if (!warnCMP0067Variables.empty()) {
       std::ostringstream w;
       /* clang-format off */
       w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0067) << "\n"
@@ -902,43 +861,17 @@
         "is not honoring language standard variables in the test project:\n"
         ;
       /* clang-format on */
-      for (std::string const& vi : this->WarnCMP0067) {
+      for (std::string const& vi : warnCMP0067Variables) {
         w << "  " << vi << "\n";
       }
       this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, w.str());
     }
 
-    auto writeLanguageProperties = [&](bool testLang,
-                                       const std::string& langStandard,
-                                       const std::string& langStandardRequired,
-                                       const std::string& langExtensions,
-                                       const std::string& lang) {
-      if (testLang) {
-        if (!langStandard.empty()) {
-          writeProperty(fout, targetName, cmStrCat(lang, "_STANDARD"),
-                        langStandard);
-        }
-        if (!langStandardRequired.empty()) {
-          writeProperty(fout, targetName, cmStrCat(lang, "_STANDARD_REQUIRED"),
-                        langStandardRequired);
-        }
-        if (!langExtensions.empty()) {
-          writeProperty(fout, targetName, cmStrCat(lang, "_EXTENSIONS"),
-                        langExtensions);
-        }
-      }
-    };
-
-    writeLanguageProperties(testC, cStandard, cStandardRequired, cExtensions,
-                            "C");
-    writeLanguageProperties(testObjC, objcStandard, objcStandardRequired,
-                            objcExtensions, "OBJC");
-    writeLanguageProperties(testCxx, cxxStandard, cxxStandardRequired,
-                            cxxExtensions, "CXX");
-    writeLanguageProperties(testObjCxx, objcxxStandard, objcxxStandardRequired,
-                            objcxxExtensions, "OBJCXX");
-    writeLanguageProperties(testCuda, cudaStandard, cudaStandardRequired,
-                            cudaExtensions, "CUDA");
+    cState.WriteProperties(fout, targetName);
+    cxxState.WriteProperties(fout, targetName);
+    cudaState.WriteProperties(fout, targetName);
+    objcState.WriteProperties(fout, targetName);
+    objcxxState.WriteProperties(fout, targetName);
 
     if (!linkOptions.empty()) {
       std::vector<std::string> options;
@@ -1112,14 +1045,14 @@
   const char* config =
     this->Makefile->GetDefinition("CMAKE_TRY_COMPILE_CONFIGURATION");
   // if a config was specified try that first
-  if (config && config[0]) {
+  if (cmNonempty(config)) {
     std::string tmp = cmStrCat('/', config);
     searchDirs.push_back(std::move(tmp));
   }
   searchDirs.emplace_back("/Debug");
 #if defined(__APPLE__)
   std::string app = "/" + targetName + ".app";
-  if (config && config[0]) {
+  if (cmNonempty(config)) {
     std::string tmp = cmStrCat('/', config, app);
     searchDirs.push_back(std::move(tmp));
   }
diff --git a/Source/cmCoreTryCompile.h b/Source/cmCoreTryCompile.h
index ae714a6..916572a 100644
--- a/Source/cmCoreTryCompile.h
+++ b/Source/cmCoreTryCompile.h
@@ -47,10 +47,6 @@
   std::string OutputFile;
   std::string FindErrorMessage;
   bool SrcFileSignature = false;
-
-private:
-  std::vector<std::string> WarnCMP0067;
-  std::string LookupStdVar(std::string const& var, bool warnCMP0067);
 };
 
 #endif
diff --git a/Source/cmCreateTestSourceList.cxx b/Source/cmCreateTestSourceList.cxx
index 9d492ba..9c4deea 100644
--- a/Source/cmCreateTestSourceList.cxx
+++ b/Source/cmCreateTestSourceList.cxx
@@ -127,7 +127,7 @@
   mf.AddDefinition("CMAKE_FORWARD_DECLARE_TESTS", forwardDeclareCode);
   mf.AddDefinition("CMAKE_FUNCTION_TABLE_ENTIRES", functionMapCode);
   bool res = true;
-  if (!mf.ConfigureFile(configFile, driver, false, true, false)) {
+  if (!mf.ConfigureFile(configFile, driver, false, true, false, true)) {
     res = false;
   }
 
diff --git a/Source/cmDefinitions.cxx b/Source/cmDefinitions.cxx
index 69a6427..4a4f87d 100644
--- a/Source/cmDefinitions.cxx
+++ b/Source/cmDefinitions.cxx
@@ -19,7 +19,6 @@
   {
     auto it = begin->Map.find(cm::String::borrow(key));
     if (it != begin->Map.end()) {
-      it->second.Used = true;
       return it->second;
     }
   }
@@ -108,16 +107,3 @@
 {
   this->Map[key] = Def();
 }
-
-std::vector<std::string> cmDefinitions::UnusedKeys() const
-{
-  std::vector<std::string> keys;
-  keys.reserve(this->Map.size());
-  // Consider local definitions.
-  for (auto const& mi : this->Map) {
-    if (!mi.second.Used) {
-      keys.push_back(*mi.first.str_if_stable());
-    }
-  }
-  return keys;
-}
diff --git a/Source/cmDefinitions.h b/Source/cmDefinitions.h
index 0e38fb1..d57750a 100644
--- a/Source/cmDefinitions.h
+++ b/Source/cmDefinitions.h
@@ -48,9 +48,6 @@
   /** Unset a definition.  */
   void Unset(const std::string& key);
 
-  /** List of unused keys.  */
-  std::vector<std::string> UnusedKeys() const;
-
 private:
   /** String with existence boolean.  */
   struct Def
@@ -62,7 +59,6 @@
     {
     }
     cm::String Value;
-    bool Used = false;
   };
   static Def NoDef;
 
diff --git a/Source/cmDependsFortran.cxx b/Source/cmDependsFortran.cxx
index 8f02d95..54418df 100644
--- a/Source/cmDependsFortran.cxx
+++ b/Source/cmDependsFortran.cxx
@@ -395,7 +395,7 @@
                   << ' ' << stampFileForShell;
       cmMakefile* mf = this->LocalGenerator->GetMakefile();
       const char* cid = mf->GetDefinition("CMAKE_Fortran_COMPILER_ID");
-      if (cid && *cid) {
+      if (cmNonempty(cid)) {
         makeDepends << ' ' << cid;
       }
       makeDepends << '\n';
diff --git a/Source/cmExportCommand.cxx b/Source/cmExportCommand.cxx
index 9f8a821..352eaf2 100644
--- a/Source/cmExportCommand.cxx
+++ b/Source/cmExportCommand.cxx
@@ -223,11 +223,9 @@
   ebfg->SetExportOld(arguments.ExportOld);
 
   // Compute the set of configurations exported.
-  std::vector<std::string> configurationTypes;
-  mf.GetConfigurations(configurationTypes);
-  if (configurationTypes.empty()) {
-    configurationTypes.emplace_back();
-  }
+  std::vector<std::string> configurationTypes =
+    mf.GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
+
   for (std::string const& ct : configurationTypes) {
     ebfg->AddConfiguration(ct);
   }
diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx
index 4d0e099..58aa391 100644
--- a/Source/cmExportFileGenerator.cxx
+++ b/Source/cmExportFileGenerator.cxx
@@ -567,8 +567,9 @@
   if (gtarget->GetType() != cmStateEnums::INTERFACE_LIBRARY) {
     getCompatibleInterfaceProperties(gtarget, ifaceProperties, "");
 
-    std::vector<std::string> configNames;
-    gtarget->Target->GetMakefile()->GetConfigurations(configNames);
+    std::vector<std::string> configNames =
+      gtarget->Target->GetMakefile()->GetGeneratorConfigs(
+        cmMakefile::ExcludeEmptyConfig);
 
     for (std::string const& cn : configNames) {
       getCompatibleInterfaceProperties(gtarget, ifaceProperties, cn);
diff --git a/Source/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx
index 32b0ca9..511168b 100644
--- a/Source/cmExtraCodeBlocksGenerator.cxx
+++ b/Source/cmExtraCodeBlocksGenerator.cxx
@@ -95,7 +95,7 @@
   std::string path; // only one component of the path
   std::vector<Tree> folders;
   std::set<std::string> files;
-  void InsertPath(const std::vector<std::string>& splitted,
+  void InsertPath(const std::vector<std::string>& split,
                   std::vector<std::string>::size_type start,
                   const std::string& fileName);
   void BuildVirtualFolder(cmXMLWriter& xml) const;
@@ -106,34 +106,34 @@
                      const std::string& fsPath) const;
 };
 
-void Tree::InsertPath(const std::vector<std::string>& splitted,
+void Tree::InsertPath(const std::vector<std::string>& split,
                       std::vector<std::string>::size_type start,
                       const std::string& fileName)
 {
-  if (start == splitted.size()) {
+  if (start == split.size()) {
     files.insert(fileName);
     return;
   }
   for (Tree& folder : folders) {
-    if (folder.path == splitted[start]) {
-      if (start + 1 < splitted.size()) {
-        folder.InsertPath(splitted, start + 1, fileName);
+    if (folder.path == split[start]) {
+      if (start + 1 < split.size()) {
+        folder.InsertPath(split, start + 1, fileName);
         return;
       }
-      // last part of splitted
+      // last part of split
       folder.files.insert(fileName);
       return;
     }
   }
   // Not found in folders, thus insert
   Tree newFolder;
-  newFolder.path = splitted[start];
-  if (start + 1 < splitted.size()) {
-    newFolder.InsertPath(splitted, start + 1, fileName);
+  newFolder.path = split[start];
+  if (start + 1 < split.size()) {
+    newFolder.InsertPath(split, start + 1, fileName);
     folders.push_back(newFolder);
     return;
   }
-  // last part of splitted
+  // last part of split
   newFolder.files.insert(fileName);
   folders.push_back(newFolder);
 }
@@ -224,11 +224,11 @@
 
       const std::string& relative = cmSystemTools::RelativePath(
         it.second[0]->GetSourceDirectory(), listFile);
-      std::vector<std::string> splitted;
-      cmSystemTools::SplitPath(relative, splitted, false);
+      std::vector<std::string> split;
+      cmSystemTools::SplitPath(relative, split, false);
       // Split filename from path
-      std::string fileName = *(splitted.end() - 1);
-      splitted.erase(splitted.end() - 1, splitted.end());
+      std::string fileName = *(split.end() - 1);
+      split.erase(split.end() - 1, split.end());
 
       // We don't want paths with CMakeFiles in them
       // or do we?
@@ -236,13 +236,12 @@
       //
       // Also we can disable external (outside the project) files by setting ON
       // CMAKE_CODEBLOCKS_EXCLUDE_EXTERNAL_FILES variable.
-      const bool excludeExternal =
-        cmIsOn(it.second[0]->GetMakefile()->GetSafeDefinition(
-          "CMAKE_CODEBLOCKS_EXCLUDE_EXTERNAL_FILES"));
-      if (!splitted.empty() &&
+      const bool excludeExternal = it.second[0]->GetMakefile()->IsOn(
+        "CMAKE_CODEBLOCKS_EXCLUDE_EXTERNAL_FILES");
+      if (!split.empty() &&
           (!excludeExternal || (relative.find("..") == std::string::npos)) &&
           relative.find("CMakeFiles") == std::string::npos) {
-        tree.InsertPath(splitted, 1, fileName);
+        tree.InsertPath(split, 1, fileName);
       }
     }
   }
@@ -370,7 +369,7 @@
             std::string lang = s->GetOrDetermineLanguage();
             if (lang == "C" || lang == "CXX" || lang == "CUDA") {
               std::string const& srcext = s->GetExtension();
-              isCFile = cm->IsSourceExtension(srcext);
+              isCFile = cm->IsACLikeSourceExtension(srcext);
             }
 
             std::string const& fullPath = s->ResolveFullPath();
@@ -380,9 +379,8 @@
               cmSystemTools::RelativePath(lg->GetSourceDirectory(), fullPath);
             // Do not add this file if it has ".." in relative path and
             // if CMAKE_CODEBLOCKS_EXCLUDE_EXTERNAL_FILES variable is on.
-            const bool excludeExternal =
-              cmIsOn(lg->GetMakefile()->GetSafeDefinition(
-                "CMAKE_CODEBLOCKS_EXCLUDE_EXTERNAL_FILES"));
+            const bool excludeExternal = lg->GetMakefile()->IsOn(
+              "CMAKE_CODEBLOCKS_EXCLUDE_EXTERNAL_FILES");
             if (excludeExternal &&
                 (relative.find("..") != std::string::npos)) {
               continue;
diff --git a/Source/cmExtraCodeLiteGenerator.cxx b/Source/cmExtraCodeLiteGenerator.cxx
index bf7555d..95cfb0a 100644
--- a/Source/cmExtraCodeLiteGenerator.cxx
+++ b/Source/cmExtraCodeLiteGenerator.cxx
@@ -227,8 +227,7 @@
           cmSystemTools::LowerCase(s->GetExtension());
         // check whether it is a source or a include file
         // then put it accordingly into one of the two containers
-        if (cm->IsSourceExtension(extLower) || cm->IsCudaExtension(extLower) ||
-            cm->IsFortranExtension(extLower)) {
+        if (cm->IsAKnownSourceExtension(extLower)) {
           cFiles[fullPath] = s;
         } else {
           otherFiles.insert(fullPath);
diff --git a/Source/cmExtraEclipseCDT4Generator.cxx b/Source/cmExtraEclipseCDT4Generator.cxx
index 7bc4536..b6c0a7a 100644
--- a/Source/cmExtraEclipseCDT4Generator.cxx
+++ b/Source/cmExtraEclipseCDT4Generator.cxx
@@ -604,7 +604,7 @@
 
 void cmExtraEclipseCDT4Generator::CreateCProjectFile() const
 {
-  std::set<std::string> emmited;
+  std::set<std::string> emitted;
 
   const auto& lg = this->GlobalGenerator->GetLocalGenerators()[0];
   const cmMakefile* mf = lg->GetMakefile();
@@ -751,7 +751,7 @@
   xml.EndElement();
 
   // add pre-processor definitions to allow eclipse to gray out sections
-  emmited.clear();
+  emitted.clear();
   for (const auto& lgen : this->GlobalGenerator->GetLocalGenerators()) {
 
     if (cmProp cdefs =
@@ -780,8 +780,8 @@
         }
 
         // insert the definition if not already added.
-        if (emmited.find(def) == emmited.end()) {
-          emmited.insert(def);
+        if (emitted.find(def) == emitted.end()) {
+          emitted.insert(def);
           xml.StartElement("pathentry");
           xml.Attribute("kind", "mac");
           xml.Attribute("name", def);
@@ -812,8 +812,8 @@
         }
 
         // insert the definition if not already added.
-        if (emmited.find(def) == emmited.end()) {
-          emmited.insert(def);
+        if (emitted.find(def) == emitted.end()) {
+          emitted.insert(def);
           xml.StartElement("pathentry");
           xml.Attribute("kind", "mac");
           xml.Attribute("name", def);
@@ -844,8 +844,8 @@
         }
 
         // insert the definition if not already added.
-        if (emmited.find(def) == emmited.end()) {
-          emmited.insert(def);
+        if (emitted.find(def) == emitted.end()) {
+          emitted.insert(def);
           xml.StartElement("pathentry");
           xml.Attribute("kind", "mac");
           xml.Attribute("name", def);
@@ -858,7 +858,7 @@
   }
 
   // include dirs
-  emmited.clear();
+  emitted.clear();
   for (const auto& lgen : this->GlobalGenerator->GetLocalGenerators()) {
     const auto& targets = lgen->GetGeneratorTargets();
     for (const auto& target : targets) {
@@ -868,7 +868,7 @@
       std::vector<std::string> includeDirs;
       std::string config = mf->GetSafeDefinition("CMAKE_BUILD_TYPE");
       lgen->GetIncludeDirectories(includeDirs, target.get(), "C", config);
-      this->AppendIncludeDirectories(xml, includeDirs, emmited);
+      this->AppendIncludeDirectories(xml, includeDirs, emitted);
     }
   }
   // now also the system include directories, in case we found them in
@@ -879,14 +879,14 @@
     std::string systemIncludeDirs =
       mf->GetSafeDefinition("CMAKE_EXTRA_GENERATOR_C_SYSTEM_INCLUDE_DIRS");
     std::vector<std::string> dirs = cmExpandedList(systemIncludeDirs);
-    this->AppendIncludeDirectories(xml, dirs, emmited);
+    this->AppendIncludeDirectories(xml, dirs, emitted);
   }
   compiler = mf->GetSafeDefinition("CMAKE_CXX_COMPILER");
   if (this->CXXEnabled && !compiler.empty()) {
     std::string systemIncludeDirs =
       mf->GetSafeDefinition("CMAKE_EXTRA_GENERATOR_CXX_SYSTEM_INCLUDE_DIRS");
     std::vector<std::string> dirs = cmExpandedList(systemIncludeDirs);
-    this->AppendIncludeDirectories(xml, dirs, emmited);
+    this->AppendIncludeDirectories(xml, dirs, emitted);
   }
 
   xml.EndElement(); // storageModule
@@ -895,7 +895,7 @@
   xml.StartElement("storageModule");
   xml.Attribute("moduleId", "org.eclipse.cdt.make.core.buildtargets");
   xml.StartElement("buildTargets");
-  emmited.clear();
+  emitted.clear();
   const std::string& make = mf->GetRequiredDefinition("CMAKE_MAKE_PROGRAM");
   const std::string& makeArgs =
     mf->GetSafeDefinition("CMAKE_ECLIPSE_MAKE_ARGUMENTS");
diff --git a/Source/cmExtraSublimeTextGenerator.cxx b/Source/cmExtraSublimeTextGenerator.cxx
index 613a943..3e265a0 100644
--- a/Source/cmExtraSublimeTextGenerator.cxx
+++ b/Source/cmExtraSublimeTextGenerator.cxx
@@ -349,6 +349,13 @@
   if (language.empty()) {
     language = "C";
   }
+
+  // explicitly add the explicit language flag before any other flag
+  // this way backwards compatibility with user flags is maintained
+  if (source->GetProperty("LANGUAGE")) {
+    lg->AppendFeatureOptions(flags, language, "EXPLICIT_LANGUAGE");
+  }
+
   std::string const& config =
     lg->GetMakefile()->GetSafeDefinition("CMAKE_BUILD_TYPE");
 
diff --git a/Source/cmFileAPI.cxx b/Source/cmFileAPI.cxx
index 594969b..c2ab2f1 100644
--- a/Source/cmFileAPI.cxx
+++ b/Source/cmFileAPI.cxx
@@ -665,7 +665,7 @@
 
 // The "codemodel" object kind.
 
-static unsigned int const CodeModelV2Minor = 1;
+static unsigned int const CodeModelV2Minor = 2;
 
 void cmFileAPI::BuildClientRequestCodeModel(
   ClientRequest& r, std::vector<RequestVersion> const& versions)
diff --git a/Source/cmFileAPICodemodel.cxx b/Source/cmFileAPICodemodel.cxx
index fe331ec..55fb115 100644
--- a/Source/cmFileAPICodemodel.cxx
+++ b/Source/cmFileAPICodemodel.cxx
@@ -175,6 +175,38 @@
   }
 };
 
+template <typename T>
+class JBTs
+{
+public:
+  JBTs(T v = T(), std::vector<JBTIndex> ids = std::vector<JBTIndex>())
+    : Value(std::move(v))
+    , Backtraces(std::move(ids))
+  {
+  }
+  T Value;
+  std::vector<JBTIndex> Backtraces;
+  friend bool operator==(JBTs<T> const& l, JBTs<T> const& r)
+  {
+    if ((l.Value == r.Value) && (l.Backtraces.size() == r.Backtraces.size())) {
+      for (size_t i = 0; i < l.Backtraces.size(); i++) {
+        if (l.Backtraces[i].Index != r.Backtraces[i].Index) {
+          return false;
+        }
+      }
+    }
+    return true;
+  }
+  static bool ValueEq(JBTs<T> const& l, JBTs<T> const& r)
+  {
+    return l.Value == r.Value;
+  }
+  static bool ValueLess(JBTs<T> const& l, JBTs<T> const& r)
+  {
+    return l.Value < r.Value;
+  }
+};
+
 class BacktraceData
 {
   std::string TopSource;
@@ -277,6 +309,7 @@
 
   std::string Language;
   std::string Sysroot;
+  JBTs<std::string> LanguageStandard;
   std::vector<JBT<std::string>> Flags;
   std::vector<JBT<std::string>> Defines;
   std::vector<JBT<std::string>> PrecompileHeaders;
@@ -287,6 +320,7 @@
     return (l.Language == r.Language && l.Sysroot == r.Sysroot &&
             l.Flags == r.Flags && l.Defines == r.Defines &&
             l.PrecompileHeaders == r.PrecompileHeaders &&
+            l.LanguageStandard == r.LanguageStandard &&
             l.Includes == r.Includes);
   }
 };
@@ -320,6 +354,12 @@
       result = result ^ hash<std::string>()(i.Value) ^
         hash<Json::ArrayIndex>()(i.Backtrace.Index);
     }
+    if (!in.LanguageStandard.Value.empty()) {
+      result = result ^ hash<std::string>()(in.LanguageStandard.Value);
+      for (JBTIndex backtrace : in.LanguageStandard.Backtraces) {
+        result = result ^ hash<Json::ArrayIndex>()(backtrace.Index);
+      }
+    }
     return result;
   }
 };
@@ -363,6 +403,16 @@
     return JBT<T>(bt.Value, this->Backtraces.Add(bt.Backtrace));
   }
 
+  template <typename T>
+  JBTs<T> ToJBTs(BTs<T> const& bts)
+  {
+    std::vector<JBTIndex> ids;
+    for (cmListFileBacktrace const& backtrace : bts.Backtraces) {
+      ids.emplace_back(this->Backtraces.Add(backtrace));
+    }
+    return JBTs<T>(bts.Value, ids);
+  }
+
   void ProcessLanguages();
   void ProcessLanguage(std::string const& lang);
 
@@ -377,6 +427,7 @@
   Json::Value DumpCompileData(CompileData const& cd);
   Json::Value DumpInclude(CompileData::IncludeEntry const& inc);
   Json::Value DumpPrecompileHeader(JBT<std::string> const& header);
+  Json::Value DumpLanguageStandard(JBTs<std::string> const& standard);
   Json::Value DumpDefine(JBT<std::string> const& def);
   Json::Value DumpSources();
   Json::Value DumpSource(cmGeneratorTarget::SourceAndKind const& sk,
@@ -438,7 +489,7 @@
   const auto& makefiles = gg->GetMakefiles();
   if (!makefiles.empty()) {
     std::vector<std::string> const& configs =
-      makefiles[0]->GetGeneratorConfigs();
+      makefiles[0]->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
     for (std::string const& config : configs) {
       configurations.append(this->DumpConfiguration(config));
     }
@@ -574,7 +625,7 @@
 
   for (cmGeneratorTarget* gt : targetList) {
     if (gt->GetType() == cmStateEnums::GLOBAL_TARGET ||
-        gt->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+        !gt->IsInBuildSystem()) {
       continue;
     }
 
@@ -838,6 +889,11 @@
   for (BT<std::string> const& pch : precompileHeaders) {
     cd.PrecompileHeaders.emplace_back(this->ToJBT(pch));
   }
+  BTs<std::string> const* languageStandard =
+    this->GT->GetLanguageStandardProperty(lang, this->Config);
+  if (languageStandard) {
+    cd.LanguageStandard = this->ToJBTs(*languageStandard);
+  }
 }
 
 Json::ArrayIndex Target::AddSourceGroup(cmSourceGroup* sg, Json::ArrayIndex si)
@@ -996,6 +1052,9 @@
   // All compile groups share the precompile headers of the target.
   cd.PrecompileHeaders = td.PrecompileHeaders;
 
+  // All compile groups share the language standard of the target.
+  cd.LanguageStandard = td.LanguageStandard;
+
   // Use target-wide flags followed by source-specific flags.
   cd.Flags.reserve(td.Flags.size() + fd.Flags.size());
   cd.Flags.insert(cd.Flags.end(), td.Flags.begin(), td.Flags.end());
@@ -1153,6 +1212,10 @@
     }
     result["precompileHeaders"] = std::move(precompileHeaders);
   }
+  if (!cd.LanguageStandard.Value.empty()) {
+    result["languageStandard"] =
+      this->DumpLanguageStandard(cd.LanguageStandard);
+  }
 
   return result;
 }
@@ -1176,6 +1239,20 @@
   return precompileHeader;
 }
 
+Json::Value Target::DumpLanguageStandard(JBTs<std::string> const& standard)
+{
+  Json::Value languageStandard = Json::objectValue;
+  languageStandard["standard"] = standard.Value;
+  if (!standard.Backtraces.empty()) {
+    Json::Value backtraces = Json::arrayValue;
+    for (JBTIndex backtrace : standard.Backtraces) {
+      backtraces.append(backtrace.Index);
+    }
+    languageStandard["backtraces"] = backtraces;
+  }
+  return languageStandard;
+}
+
 Json::Value Target::DumpDefine(JBT<std::string> const& def)
 {
   Json::Value define = Json::objectValue;
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index 7101e22..8d20d35 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -1394,8 +1394,10 @@
 {
   int realsize = static_cast<int>(size * nmemb);
   cmsys::ofstream* fout = static_cast<cmsys::ofstream*>(data);
-  const char* chPtr = static_cast<char*>(ptr);
-  fout->write(chPtr, realsize);
+  if (fout) {
+    const char* chPtr = static_cast<char*>(ptr);
+    fout->write(chPtr, realsize);
+  }
   return realsize;
 }
 
@@ -1551,15 +1553,14 @@
 {
 #if !defined(CMAKE_BOOTSTRAP)
   auto i = args.begin();
-  if (args.size() < 3) {
-    status.SetError("DOWNLOAD must be called with at least three arguments.");
+  if (args.size() < 2) {
+    status.SetError("DOWNLOAD must be called with at least two arguments.");
     return false;
   }
   ++i; // Get rid of subcommand
   std::string url = *i;
   ++i;
-  std::string file = *i;
-  ++i;
+  std::string file;
 
   long timeout = 0;
   long inactivity_timeout = 0;
@@ -1690,6 +1691,8 @@
         return false;
       }
       curl_headers.push_back(*i);
+    } else if (file.empty()) {
+      file = *i;
     } else {
       // Do not return error for compatibility reason.
       std::string err = cmStrCat("Unexpected argument: ", *i);
@@ -1697,11 +1700,18 @@
     }
     ++i;
   }
+  // Can't calculate hash if we don't save the file.
+  // TODO Incrementally calculate hash in the write callback as the file is
+  // being downloaded so this check can be relaxed.
+  if (file.empty() && hash) {
+    status.SetError("DOWNLOAD cannot calculate hash if file is not saved.");
+    return false;
+  }
   // If file exists already, and caller specified an expected md5 or sha,
   // and the existing file already has the expected hash, then simply
   // return.
   //
-  if (cmSystemTools::FileExists(file) && hash.get()) {
+  if (!file.empty() && cmSystemTools::FileExists(file) && hash.get()) {
     std::string msg;
     std::string actualHash = hash->HashFile(file);
     if (actualHash == expectedHash) {
@@ -1716,20 +1726,26 @@
   // Make sure parent directory exists so we can write to the file
   // as we receive downloaded bits from curl...
   //
-  std::string dir = cmSystemTools::GetFilenamePath(file);
-  if (!dir.empty() && !cmSystemTools::FileExists(dir) &&
-      !cmSystemTools::MakeDirectory(dir)) {
-    std::string errstring = "DOWNLOAD error: cannot create directory '" + dir +
-      "' - Specify file by full path name and verify that you "
-      "have directory creation and file write privileges.";
-    status.SetError(errstring);
-    return false;
+  if (!file.empty()) {
+    std::string dir = cmSystemTools::GetFilenamePath(file);
+    if (!dir.empty() && !cmSystemTools::FileExists(dir) &&
+        !cmSystemTools::MakeDirectory(dir)) {
+      std::string errstring = "DOWNLOAD error: cannot create directory '" +
+        dir +
+        "' - Specify file by full path name and verify that you "
+        "have directory creation and file write privileges.";
+      status.SetError(errstring);
+      return false;
+    }
   }
 
-  cmsys::ofstream fout(file.c_str(), std::ios::binary);
-  if (!fout) {
-    status.SetError("DOWNLOAD cannot open file for write.");
-    return false;
+  cmsys::ofstream fout;
+  if (!file.empty()) {
+    fout.open(file.c_str(), std::ios::binary);
+    if (!fout) {
+      status.SetError("DOWNLOAD cannot open file for write.");
+      return false;
+    }
   }
 
 #  if defined(_WIN32)
@@ -1791,7 +1807,8 @@
 
   cmFileCommandVectorOfChar chunkDebug;
 
-  res = ::curl_easy_setopt(curl, CURLOPT_WRITEDATA, &fout);
+  res = ::curl_easy_setopt(curl, CURLOPT_WRITEDATA,
+                           file.empty() ? nullptr : &fout);
   check_curl_result(res, "DOWNLOAD cannot set write data: ");
 
   res = ::curl_easy_setopt(curl, CURLOPT_DEBUGDATA, &chunkDebug);
@@ -1865,8 +1882,10 @@
 
   // Explicitly flush/close so we can measure the md5 accurately.
   //
-  fout.flush();
-  fout.close();
+  if (!file.empty()) {
+    fout.flush();
+    fout.close();
+  }
 
   // Verify MD5 sum if requested:
   //
@@ -2918,7 +2937,7 @@
   }
   fout.SetCopyIfDifferent(true);
 
-  // copy intput to output and expand variables from input at the same time
+  // copy input to output and expand variables from input at the same time
   std::stringstream sin(input, std::ios::in);
   std::string inLine;
   std::string outLine;
diff --git a/Source/cmFileCopier.cxx b/Source/cmFileCopier.cxx
index 627e05b..5d44a06 100644
--- a/Source/cmFileCopier.cxx
+++ b/Source/cmFileCopier.cxx
@@ -173,7 +173,7 @@
   // check if default dir creation permissions were set
   const char* default_dir_install_permissions = this->Makefile->GetDefinition(
     "CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS");
-  if (default_dir_install_permissions && *default_dir_install_permissions) {
+  if (cmNonempty(default_dir_install_permissions)) {
     std::vector<std::string> items =
       cmExpandedList(default_dir_install_permissions);
     for (const auto& arg : items) {
diff --git a/Source/cmFindCommon.cxx b/Source/cmFindCommon.cxx
index 3e97150..3401eff 100644
--- a/Source/cmFindCommon.cxx
+++ b/Source/cmFindCommon.cxx
@@ -208,10 +208,10 @@
   const char* sysrootLink =
     this->Makefile->GetDefinition("CMAKE_SYSROOT_LINK");
   const char* rootPath = this->Makefile->GetDefinition("CMAKE_FIND_ROOT_PATH");
-  const bool noSysroot = !sysroot || !*sysroot;
-  const bool noCompileSysroot = !sysrootCompile || !*sysrootCompile;
-  const bool noLinkSysroot = !sysrootLink || !*sysrootLink;
-  const bool noRootPath = !rootPath || !*rootPath;
+  const bool noSysroot = !cmNonempty(sysroot);
+  const bool noCompileSysroot = !cmNonempty(sysrootCompile);
+  const bool noLinkSysroot = !cmNonempty(sysrootLink);
+  const bool noRootPath = !cmNonempty(rootPath);
   if (noSysroot && noCompileSysroot && noLinkSysroot && noRootPath) {
     return;
   }
diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx
index 8d5b177..ae06047 100644
--- a/Source/cmFindPackageCommand.cxx
+++ b/Source/cmFindPackageCommand.cxx
@@ -1121,7 +1121,7 @@
   std::vector<std::string> foundContents;
   cmProp foundProp =
     this->Makefile->GetState()->GetGlobalProperty("PACKAGES_FOUND");
-  if (foundProp && !foundProp->empty()) {
+  if (cmNonempty(foundProp)) {
     cmExpandList(*foundProp, foundContents, false);
     auto nameIt =
       std::find(foundContents.begin(), foundContents.end(), this->Name);
@@ -1133,7 +1133,7 @@
   std::vector<std::string> notFoundContents;
   cmProp notFoundProp =
     this->Makefile->GetState()->GetGlobalProperty("PACKAGES_NOT_FOUND");
-  if (notFoundProp && !notFoundProp->empty()) {
+  if (cmNonempty(notFoundProp)) {
     cmExpandList(*notFoundProp, notFoundContents, false);
     auto nameIt =
       std::find(notFoundContents.begin(), notFoundContents.end(), this->Name);
@@ -1166,9 +1166,9 @@
   std::string found = cmStrCat(this->Name, "_FOUND");
   std::string upperFound = cmSystemTools::UpperCase(found);
 
-  const char* upperResult = this->Makefile->GetDefinition(upperFound);
-  const char* result = this->Makefile->GetDefinition(found);
-  bool packageFound = ((cmIsOn(result)) || (cmIsOn(upperResult)));
+  bool upperResult = this->Makefile->IsOn(upperFound);
+  bool result = this->Makefile->IsOn(found);
+  bool packageFound = (result || upperResult);
 
   this->AppendToFoundProperty(packageFound);
 
diff --git a/Source/cmFindProgramCommand.cxx b/Source/cmFindProgramCommand.cxx
index 4b88bea..77728ec 100644
--- a/Source/cmFindProgramCommand.cxx
+++ b/Source/cmFindProgramCommand.cxx
@@ -4,6 +4,7 @@
 
 #include "cmMakefile.h"
 #include "cmMessageType.h"
+#include "cmPolicies.h"
 #include "cmStateTypes.h"
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
@@ -19,6 +20,7 @@
   cmFindProgramHelper(cmMakefile* makefile, cmFindBase const* base)
     : DebugSearches("find_program", base)
     , Makefile(makefile)
+    , PolicyCMP0109(makefile->GetPolicyStatus(cmPolicies::CMP0109))
   {
 #if defined(_WIN32) || defined(__CYGWIN__) || defined(__MINGW32__)
     // Consider platform-specific extensions.
@@ -48,6 +50,8 @@
   cmFindBaseDebugState DebugSearches;
   cmMakefile* Makefile;
 
+  cmPolicies::PolicyStatus PolicyCMP0109;
+
   void AddName(std::string const& name) { this->Names.push_back(name); }
   void SetName(std::string const& name)
   {
@@ -85,7 +89,7 @@
       this->TestNameExt = cmStrCat(name, ext);
       this->TestPath =
         cmSystemTools::CollapseFullPath(this->TestNameExt, path);
-      bool exists = cmSystemTools::FileExists(this->TestPath, true);
+      bool exists = this->FileIsExecutable(this->TestPath);
       exists ? this->DebugSearches.FoundAt(this->TestPath)
              : this->DebugSearches.FailedAt(this->TestPath);
       if (exists) {
@@ -95,6 +99,48 @@
     }
     return false;
   }
+  bool FileIsExecutable(std::string const& file) const
+  {
+    switch (this->PolicyCMP0109) {
+      case cmPolicies::OLD:
+        return cmSystemTools::FileExists(file, true);
+      case cmPolicies::NEW:
+      case cmPolicies::REQUIRED_ALWAYS:
+      case cmPolicies::REQUIRED_IF_USED:
+        return cmSystemTools::FileIsExecutable(file);
+      default:
+        break;
+    }
+    bool const isExeOld = cmSystemTools::FileExists(file, true);
+    bool const isExeNew = cmSystemTools::FileIsExecutable(file);
+    if (isExeNew == isExeOld) {
+      return isExeNew;
+    }
+    if (isExeNew) {
+      this->Makefile->IssueMessage(
+        MessageType::AUTHOR_WARNING,
+        cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0109),
+                 "\n"
+                 "The file\n"
+                 "  ",
+                 file,
+                 "\n"
+                 "is executable but not readable.  "
+                 "CMake is ignoring it for compatibility."));
+    } else {
+      this->Makefile->IssueMessage(
+        MessageType::AUTHOR_WARNING,
+        cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0109),
+                 "\n"
+                 "The file\n"
+                 "  ",
+                 file,
+                 "\n"
+                 "is readable but not executable.  "
+                 "CMake is using it for compatibility."));
+    }
+    return isExeOld;
+  }
 };
 
 cmFindProgramCommand::cmFindProgramCommand(cmExecutionStatus& status)
@@ -266,14 +312,13 @@
 
   if (executableURL != nullptr) {
     const int MAX_OSX_PATH_SIZE = 1024;
-    char buffer[MAX_OSX_PATH_SIZE];
+    UInt8 buffer[MAX_OSX_PATH_SIZE];
 
-    // Convert the CFString to a C string
-    CFStringGetCString(CFURLGetString(executableURL), buffer,
-                       MAX_OSX_PATH_SIZE, kCFStringEncodingUTF8);
-
-    // And finally to a c++ string
-    executable = bundlePath + "/Contents/MacOS/" + std::string(buffer);
+    if (CFURLGetFileSystemRepresentation(executableURL, false, buffer,
+                                         MAX_OSX_PATH_SIZE)) {
+      executable = bundlePath + "/Contents/MacOS/" +
+        std::string(reinterpret_cast<char*>(buffer));
+    }
     // Only release CFURLRef if it's not null
     CFRelease(executableURL);
   }
diff --git a/Source/cmGeneratedFileStream.cxx b/Source/cmGeneratedFileStream.cxx
index 9cee0e6..2768547 100644
--- a/Source/cmGeneratedFileStream.cxx
+++ b/Source/cmGeneratedFileStream.cxx
@@ -14,10 +14,11 @@
 #endif
 
 cmGeneratedFileStream::cmGeneratedFileStream(Encoding encoding)
+  : OriginalLocale(getloc())
 {
 #ifndef CMAKE_BOOTSTRAP
   if (encoding != codecvt::None) {
-    imbue(std::locale(getloc(), new codecvt(encoding)));
+    imbue(std::locale(OriginalLocale, new codecvt(encoding)));
   }
 #else
   static_cast<void>(encoding);
@@ -122,10 +123,17 @@
   // Create the name of the temporary file.
   this->TempName = name;
 #if defined(__VMS)
-  this->TempName += "_tmp";
+  this->TempName += "_";
 #else
-  this->TempName += ".tmp";
+  this->TempName += ".";
 #endif
+  if (!this->TempExt.empty()) {
+    this->TempName += this->TempExt;
+  } else {
+    char buf[64];
+    sprintf(buf, "tmp%05x", cmSystemTools::RandomSeed() & 0xFFFFF);
+    this->TempName += buf;
+  }
 
   // Make sure the temporary file that will be used is not present.
   cmSystemTools::RemoveFile(this->TempName);
@@ -216,3 +224,19 @@
 {
   this->Name = fname;
 }
+
+void cmGeneratedFileStream::SetTempExt(std::string const& ext)
+{
+  this->TempExt = ext;
+}
+
+void cmGeneratedFileStream::WriteRaw(std::string const& data)
+{
+#ifndef CMAKE_BOOTSTRAP
+  std::locale activeLocale = this->imbue(this->OriginalLocale);
+  this->write(data.data(), data.size());
+  this->imbue(activeLocale);
+#else
+  this->write(data.data(), data.size());
+#endif
+}
diff --git a/Source/cmGeneratedFileStream.h b/Source/cmGeneratedFileStream.h
index a9088ac..f6da86e 100644
--- a/Source/cmGeneratedFileStream.h
+++ b/Source/cmGeneratedFileStream.h
@@ -43,6 +43,9 @@
   // The name of the final destination file for the output.
   std::string Name;
 
+  // The extension of the temporary file.
+  std::string TempExt;
+
   // The name of the temporary file.
   std::string TempName;
 
@@ -138,6 +141,22 @@
    * the output file to be changed during the use of cmGeneratedFileStream.
    */
   void SetName(const std::string& fname);
+
+  /**
+   * Set set a custom temporary file extension used with 'Open'.
+   * This does not work if the file was opened by the constructor.
+   */
+  void SetTempExt(std::string const& ext);
+
+  /**
+   * Writes the given string directly to the file without changing the
+   * encoding.
+   */
+  void WriteRaw(std::string const& data);
+
+private:
+  // The original locale of the stream (performs no encoding conversion).
+  std::locale OriginalLocale;
 };
 
 #endif
diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx
index 6e293d5..840f511 100644
--- a/Source/cmGeneratorExpression.cxx
+++ b/Source/cmGeneratorExpression.cxx
@@ -406,9 +406,3 @@
     this->LocalGenerator, this->Config, this->HeadTarget, &dagChecker, nullptr,
     this->Language);
 }
-
-const std::string& cmGeneratorExpressionInterpreter::Evaluate(
-  const char* expression, const std::string& property)
-{
-  return this->Evaluate(std::string(expression ? expression : ""), property);
-}
diff --git a/Source/cmGeneratorExpression.h b/Source/cmGeneratorExpression.h
index 75bba02..09d8b88 100644
--- a/Source/cmGeneratorExpression.h
+++ b/Source/cmGeneratorExpression.h
@@ -199,8 +199,6 @@
 
   const std::string& Evaluate(std::string expression,
                               const std::string& property);
-  const std::string& Evaluate(const char* expression,
-                              const std::string& property);
 
 protected:
   cmGeneratorExpression GeneratorExpression;
diff --git a/Source/cmGeneratorExpressionDAGChecker.cxx b/Source/cmGeneratorExpressionDAGChecker.cxx
index 4f379cd..e223f15 100644
--- a/Source/cmGeneratorExpressionDAGChecker.cxx
+++ b/Source/cmGeneratorExpressionDAGChecker.cxx
@@ -154,6 +154,14 @@
   return this->Top()->Property == "INTERFACE_POSITION_INDEPENDENT_CODE";
 }
 
+bool cmGeneratorExpressionDAGChecker::EvaluatingCompileExpression() const
+{
+  cm::string_view property(this->Top()->Property);
+
+  return property == "INCLUDE_DIRECTORIES"_s ||
+    property == "COMPILE_DEFINITIONS"_s || property == "COMPILE_OPTIONS"_s;
+}
+
 bool cmGeneratorExpressionDAGChecker::EvaluatingLinkExpression() const
 {
   cm::string_view property(this->Top()->Property);
diff --git a/Source/cmGeneratorExpressionDAGChecker.h b/Source/cmGeneratorExpressionDAGChecker.h
index c2c5b6b..ac2314c 100644
--- a/Source/cmGeneratorExpressionDAGChecker.h
+++ b/Source/cmGeneratorExpressionDAGChecker.h
@@ -68,6 +68,7 @@
 
   bool EvaluatingGenexExpression() const;
   bool EvaluatingPICExpression() const;
+  bool EvaluatingCompileExpression() const;
   bool EvaluatingLinkExpression() const;
   bool EvaluatingLinkOptionsExpression() const;
 
diff --git a/Source/cmGeneratorExpressionEvaluationFile.cxx b/Source/cmGeneratorExpressionEvaluationFile.cxx
index 9e8707d..1107adb 100644
--- a/Source/cmGeneratorExpressionEvaluationFile.cxx
+++ b/Source/cmGeneratorExpressionEvaluationFile.cxx
@@ -157,12 +157,8 @@
 
   std::map<std::string, std::string> outputFiles;
 
-  std::vector<std::string> allConfigs;
-  lg->GetMakefile()->GetConfigurations(allConfigs);
-
-  if (allConfigs.empty()) {
-    allConfigs.emplace_back();
-  }
+  std::vector<std::string> allConfigs =
+    lg->GetMakefile()->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
 
   std::vector<std::string> enabledLanguages;
   cmGlobalGenerator* gg = lg->GetGlobalGenerator();
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index e4fb67e..fdc8f29 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -37,6 +37,7 @@
 #include "cmPolicies.h"
 #include "cmProperty.h"
 #include "cmRange.h"
+#include "cmStandardLevelResolver.h"
 #include "cmState.h"
 #include "cmStateSnapshot.h"
 #include "cmStateTypes.h"
@@ -881,7 +882,7 @@
 {
   ConfigurationTestNode() {} // NOLINT(modernize-use-equals-default)
 
-  int NumExpectedParameters() const override { return OneOrZeroParameters; }
+  int NumExpectedParameters() const override { return ZeroOrMoreParameters; }
 
   std::string Evaluate(
     const std::vector<std::string>& parameters,
@@ -899,13 +900,15 @@
       return std::string();
     }
     context->HadContextSensitiveCondition = true;
-    if (context->Config.empty()) {
-      return parameters.front().empty() ? "1" : "0";
-    }
-
-    if (cmsysString_strcasecmp(parameters.front().c_str(),
-                               context->Config.c_str()) == 0) {
-      return "1";
+    for (auto& param : parameters) {
+      if (context->Config.empty()) {
+        if (param.empty()) {
+          return "1";
+        }
+      } else if (cmsysString_strcasecmp(param.c_str(),
+                                        context->Config.c_str()) == 0) {
+        return "1";
+      }
     }
 
     if (context->CurrentTarget && context->CurrentTarget->IsImported()) {
@@ -922,10 +925,12 @@
           "MAP_IMPORTED_CONFIG_", cmSystemTools::UpperCase(context->Config));
         if (cmProp mapValue = context->CurrentTarget->GetProperty(mapProp)) {
           cmExpandList(cmSystemTools::UpperCase(*mapValue), mappedConfigs);
-          return cm::contains(mappedConfigs,
-                              cmSystemTools::UpperCase(parameters.front()))
-            ? "1"
-            : "0";
+
+          for (auto& param : parameters) {
+            if (cm::contains(mappedConfigs, cmSystemTools::UpperCase(param))) {
+              return "1";
+            }
+          }
         }
       }
     }
@@ -962,9 +967,10 @@
     const std::vector<std::string>& parameters,
     cmGeneratorExpressionContext* context,
     const GeneratorExpressionContent* content,
-    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
+    cmGeneratorExpressionDAGChecker* dagChecker) const override
   {
-    if (context->Language.empty()) {
+    if (context->Language.empty() &&
+        (!dagChecker || !dagChecker->EvaluatingCompileExpression())) {
       reportError(
         context, content->GetOriginalExpression(),
         "$<COMPILE_LANGUAGE:...> may only be used to specify include "
@@ -1009,7 +1015,9 @@
     const GeneratorExpressionContent* content,
     cmGeneratorExpressionDAGChecker* dagChecker) const override
   {
-    if (!context->HeadTarget || context->Language.empty()) {
+    if (!context->HeadTarget ||
+        (context->Language.empty() &&
+         (!dagChecker || !dagChecker->EvaluatingCompileExpression()))) {
       // reportError(context, content->GetOriginalExpression(), "");
       reportError(
         context, content->GetOriginalExpression(),
@@ -1468,8 +1476,9 @@
     }
 
     if (isInterfaceProperty) {
-      return target->EvaluateInterfaceProperty(propertyName, context,
-                                               dagCheckerParent);
+      return cmGeneratorExpression::StripEmptyListElements(
+        target->EvaluateInterfaceProperty(propertyName, context,
+                                          dagCheckerParent));
     }
 
     cmGeneratorExpressionDAGChecker dagChecker(
@@ -1555,8 +1564,9 @@
     }
 
     if (!interfacePropertyName.empty()) {
-      result = this->EvaluateDependentExpression(result, context->LG, context,
-                                                 target, &dagChecker, target);
+      result = cmGeneratorExpression::StripEmptyListElements(
+        this->EvaluateDependentExpression(result, context->LG, context, target,
+                                          &dagChecker, target));
       std::string linkedTargetsContent = getLinkedTargetsContent(
         target, interfacePropertyName, context, &dagChecker);
       if (!linkedTargetsContent.empty()) {
@@ -1703,12 +1713,12 @@
     static LangMap availableFeatures;
 
     LangMap testedFeatures;
-
+    cmStandardLevelResolver standardResolver(context->LG->GetMakefile());
     for (std::string const& p : parameters) {
       std::string error;
       std::string lang;
-      if (!context->LG->GetMakefile()->CompileFeatureKnown(
-            context->HeadTarget->Target, p, lang, &error)) {
+      if (!standardResolver.CompileFeatureKnown(
+            context->HeadTarget->Target->GetName(), p, lang, &error)) {
         reportError(context, content->GetOriginalExpression(), error);
         return std::string();
       }
@@ -1716,7 +1726,7 @@
 
       if (availableFeatures.find(lang) == availableFeatures.end()) {
         const char* featuresKnown =
-          context->LG->GetMakefile()->CompileFeaturesAvailable(lang, &error);
+          standardResolver.CompileFeaturesAvailable(lang, &error);
         if (!featuresKnown) {
           reportError(context, content->GetOriginalExpression(), error);
           return std::string();
@@ -1741,10 +1751,10 @@
           // All features known for the language are always available.
           continue;
         }
-        if (!context->LG->GetMakefile()->HaveStandardAvailable(
-              target->Target, lit.first, it)) {
+        if (!standardResolver.HaveStandardAvailable(target, lit.first,
+                                                    context->Config, it)) {
           if (evalLL) {
-            cmProp l = target->GetProperty(lit.first + "_STANDARD");
+            cmProp l = target->GetLanguageStandard(lit.first, context->Config);
             if (!l) {
               l = standardDefault;
             }
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index ab6a26c..889ad7c 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -43,6 +43,7 @@
 #include "cmSourceFile.h"
 #include "cmSourceFileLocation.h"
 #include "cmSourceFileLocationKind.h"
+#include "cmStandardLevelResolver.h"
 #include "cmState.h"
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
@@ -364,7 +365,7 @@
 {
   cmProp exportName = this->GetProperty("EXPORT_NAME");
 
-  if (exportName && !exportName->empty()) {
+  if (cmNonempty(exportName)) {
     if (!cmGeneratorExpression::IsValidTargetName(*exportName)) {
       std::ostringstream e;
       e << "EXPORT_NAME property \"" << *exportName << "\" for \""
@@ -379,11 +380,6 @@
 
 cmProp cmGeneratorTarget::GetProperty(const std::string& prop) const
 {
-  if (!cmTargetPropertyComputer::PassesWhitelist(
-        this->GetType(), prop, this->Makefile->GetMessenger(),
-        this->GetBacktrace())) {
-    return nullptr;
-  }
   if (cmProp result = cmTargetPropertyComputer::GetProperty(
         this, prop, this->Makefile->GetMessenger(), this->GetBacktrace())) {
     return result;
@@ -801,7 +797,8 @@
 
 void cmGeneratorTarget::ComputeObjectMapping()
 {
-  auto const& configs = this->Makefile->GetGeneratorConfigs();
+  auto const& configs =
+    this->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
   std::set<std::string> configSet(configs.begin(), configs.end());
   if (configSet == this->VisitedConfigsForObjects) {
     return;
@@ -813,18 +810,18 @@
   }
 }
 
-const char* cmGeneratorTarget::GetFeature(const std::string& feature,
-                                          const std::string& config) const
+cmProp cmGeneratorTarget::GetFeature(const std::string& feature,
+                                     const std::string& config) const
 {
   if (!config.empty()) {
     std::string featureConfig =
       cmStrCat(feature, '_', cmSystemTools::UpperCase(config));
     if (cmProp value = this->GetProperty(featureConfig)) {
-      return value->c_str();
+      return value;
     }
   }
   if (cmProp value = this->GetProperty(feature)) {
-    return value->c_str();
+    return value;
   }
   return this->LocalGenerator->GetFeature(feature, config);
 }
@@ -851,10 +848,9 @@
 bool cmGeneratorTarget::IsIPOEnabled(std::string const& lang,
                                      std::string const& config) const
 {
-  const char* feature = "INTERPROCEDURAL_OPTIMIZATION";
-  const bool result = cmIsOn(this->GetFeature(feature, config));
+  cmProp feature = this->GetFeature("INTERPROCEDURAL_OPTIMIZATION", config);
 
-  if (!result) {
+  if (!cmIsOn(feature)) {
     // 'INTERPROCEDURAL_OPTIMIZATION' is off, no need to check policies
     return false;
   }
@@ -947,6 +943,61 @@
   return it != this->ExplicitObjectName.end();
 }
 
+BTs<std::string> const* cmGeneratorTarget::GetLanguageStandardProperty(
+  std::string const& lang, std::string const& config) const
+{
+  std::string key = cmStrCat(cmSystemTools::UpperCase(config), '-', lang);
+  auto langStandardIter = this->LanguageStandardMap.find(key);
+  if (langStandardIter != this->LanguageStandardMap.end()) {
+    return &langStandardIter->second;
+  }
+
+  return this->Target->GetLanguageStandardProperty(
+    cmStrCat(lang, "_STANDARD"));
+}
+
+cmProp cmGeneratorTarget::GetLanguageStandard(std::string const& lang,
+                                              std::string const& config) const
+{
+  BTs<std::string> const* languageStandard =
+    this->GetLanguageStandardProperty(lang, config);
+
+  if (languageStandard) {
+    return &(languageStandard->Value);
+  }
+
+  return nullptr;
+}
+
+cmProp cmGeneratorTarget::GetPropertyWithPairedLanguageSupport(
+  std::string const& lang, const char* suffix) const
+{
+  cmProp propertyValue = this->Target->GetProperty(cmStrCat(lang, suffix));
+  if (propertyValue == nullptr) {
+    // Check if we should use the value set by another language.
+    if (lang == "OBJC") {
+      propertyValue = this->GetPropertyWithPairedLanguageSupport("C", suffix);
+    } else if (lang == "OBJCXX" || lang == "CUDA") {
+      propertyValue =
+        this->GetPropertyWithPairedLanguageSupport("CXX", suffix);
+    }
+  }
+  return propertyValue;
+}
+
+cmProp cmGeneratorTarget::GetLanguageExtensions(std::string const& lang) const
+{
+  return this->GetPropertyWithPairedLanguageSupport(lang, "_EXTENSIONS");
+}
+
+bool cmGeneratorTarget::GetLanguageStandardRequired(
+  std::string const& lang) const
+{
+  cmProp p =
+    this->GetPropertyWithPairedLanguageSupport(lang, "_STANDARD_REQUIRED");
+  return cmIsOn(p);
+}
+
 void cmGeneratorTarget::GetModuleDefinitionSources(
   std::vector<cmSourceFile const*>& data, const std::string& config) const
 {
@@ -1033,6 +1084,31 @@
   return this->Target->GetPostBuildCommands();
 }
 
+bool cmGeneratorTarget::IsInBuildSystem() const
+{
+  if (this->IsImported()) {
+    return false;
+  }
+  switch (this->Target->GetType()) {
+    case cmStateEnums::EXECUTABLE:
+    case cmStateEnums::STATIC_LIBRARY:
+    case cmStateEnums::SHARED_LIBRARY:
+    case cmStateEnums::MODULE_LIBRARY:
+    case cmStateEnums::OBJECT_LIBRARY:
+    case cmStateEnums::UTILITY:
+    case cmStateEnums::GLOBAL_TARGET:
+      return true;
+    case cmStateEnums::INTERFACE_LIBRARY:
+      // An INTERFACE library is in the build system if it has SOURCES.
+      if (!this->SourceEntries.empty()) {
+        return true;
+      }
+    case cmStateEnums::UNKNOWN_LIBRARY:
+      break;
+  }
+  return false;
+}
+
 bool cmGeneratorTarget::IsImported() const
 {
   return this->Target->IsImported();
@@ -1043,6 +1119,11 @@
   return this->Target->IsImportedGloballyVisible();
 }
 
+bool cmGeneratorTarget::CanCompileSources() const
+{
+  return this->Target->CanCompileSources();
+}
+
 const std::string& cmGeneratorTarget::GetLocationForBuild() const
 {
   static std::string location;
@@ -1137,7 +1218,7 @@
 
     // If this target itself has a non-empty property value, we are done.
     cmProp p = this->GetProperty(prop);
-    maybeInterfaceProp = p && !p->empty();
+    maybeInterfaceProp = cmNonempty(p);
 
     // Otherwise, recurse to interface dependencies.
     if (!maybeInterfaceProp) {
@@ -1309,7 +1390,7 @@
 
     for (const cmLinkImplItem& library : libraries->Libraries) {
       if (const cmGeneratorTarget* dependency = library.Target) {
-        if (dependency->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+        if (!dependency->IsInBuildSystem()) {
           continue;
         }
         if (cm::contains(dependency->GetAllConfigCompileLanguages(),
@@ -1466,7 +1547,6 @@
   std::string const& config) const
 {
   std::vector<BT<std::string>> files;
-  assert(this->GetType() != cmStateEnums::INTERFACE_LIBRARY);
 
   if (!this->LocalGenerator->GetGlobalGenerator()->GetConfigureDoneCMP0026()) {
     // At configure-time, this method can be called as part of getting the
@@ -1658,9 +1738,11 @@
     std::string ext = cmSystemTools::LowerCase(sf->GetExtension());
     if (sf->GetCustomCommand()) {
       kind = SourceKindCustomCommand;
-      // XXX(clang-tidy): https://bugs.llvm.org/show_bug.cgi?id=44165
-      // NOLINTNEXTLINE(bugprone-branch-clone)
-    } else if (this->Target->GetType() == cmStateEnums::UTILITY) {
+    } else if (this->Target->GetType() == cmStateEnums::UTILITY ||
+               this->Target->GetType() == cmStateEnums::INTERFACE_LIBRARY
+               // XXX(clang-tidy): https://bugs.llvm.org/show_bug.cgi?id=44165
+               // NOLINTNEXTLINE(bugprone-branch-clone)
+    ) {
       kind = SourceKindExtra;
     } else if (this->IsSourceFilePartOfUnityBatch(sf->ResolveFullPath())) {
       kind = SourceKindUnityBatched;
@@ -1726,8 +1808,8 @@
 
 void cmGeneratorTarget::ComputeAllConfigSources() const
 {
-  std::vector<std::string> configs;
-  this->Makefile->GetConfigurations(configs);
+  std::vector<std::string> configs =
+    this->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
 
   std::map<cmSourceFile const*, size_t> index;
 
@@ -1787,12 +1869,12 @@
   std::string configUpper = cmSystemTools::UpperCase(config);
   std::string configProp = cmStrCat("COMPILE_PDB_NAME_", configUpper);
   cmProp config_name = this->GetProperty(configProp);
-  if (config_name && !config_name->empty()) {
+  if (cmNonempty(config_name)) {
     return prefix + *config_name + ".pdb";
   }
 
   cmProp name = this->GetProperty("COMPILE_PDB_NAME");
-  if (name && !name->empty()) {
+  if (cmNonempty(name)) {
     return prefix + *name + ".pdb";
   }
 
@@ -1939,7 +2021,7 @@
     std::string sepVar =
       cmStrCat("CMAKE_SHARED_LIBRARY_RUNTIME_", ll, "_FLAG_SEP");
     const char* sep = this->Makefile->GetDefinition(sepVar);
-    if (sep && *sep) {
+    if (cmNonempty(sep)) {
       // TODO: Add ELF check to ABI detection and get rid of
       // CMAKE_EXECUTABLE_FORMAT.
       if (const char* fmt =
@@ -2239,7 +2321,7 @@
     cmProp install_name_dir = this->GetProperty("INSTALL_NAME_DIR");
 
     if (this->CanGenerateInstallNameDir(INSTALL_NAME_FOR_INSTALL)) {
-      if (install_name_dir && !install_name_dir->empty()) {
+      if (cmNonempty(install_name_dir)) {
         dir = *install_name_dir;
         cmGeneratorExpression::ReplaceInstallPrefix(dir, installPrefix);
         dir =
@@ -2385,6 +2467,12 @@
 cmGeneratorTarget::LinkClosure const* cmGeneratorTarget::GetLinkClosure(
   const std::string& config) const
 {
+  // There is no link implementation for targets that cannot compile sources.
+  if (!this->CanCompileSources()) {
+    static LinkClosure const empty = { {}, {} };
+    return &empty;
+  }
+
   std::string key(cmSystemTools::UpperCase(config));
   auto i = this->LinkClosureMap.find(key);
   if (i == this->LinkClosureMap.end()) {
@@ -2701,6 +2789,12 @@
 cmGeneratorTarget::GetLinkImplementationClosure(
   const std::string& config) const
 {
+  // There is no link implementation for targets that cannot compile sources.
+  if (!this->CanCompileSources()) {
+    static std::vector<const cmGeneratorTarget*> const empty;
+    return empty;
+  }
+
   LinkImplClosure& tgts = this->LinkImplClosureMap[config];
   if (!tgts.Done) {
     tgts.Done = true;
@@ -2708,6 +2802,7 @@
 
     cmLinkImplementationLibraries const* impl =
       this->GetLinkImplementationLibraries(config);
+    assert(impl);
 
     for (cmLinkImplItem const& lib : impl->Libraries) {
       processILibs(config, this, lib,
@@ -2757,29 +2852,26 @@
   this->CurrentEntry = nullptr;
 
   // Queue all the source files already specified for the target.
-  if (target->GetType() != cmStateEnums::INTERFACE_LIBRARY) {
-    std::set<cmSourceFile*> emitted;
-    std::vector<std::string> const& configs =
-      this->Makefile->GetGeneratorConfigs();
-    for (std::string const& c : configs) {
-      std::vector<cmSourceFile*> sources;
-      this->GeneratorTarget->GetSourceFiles(sources, c);
-      for (cmSourceFile* sf : sources) {
-        const std::set<cmGeneratorTarget const*> tgts =
-          this->GlobalGenerator->GetFilenameTargetDepends(sf);
-        if (cm::contains(tgts, this->GeneratorTarget)) {
-          std::ostringstream e;
-          e << "Evaluation output file\n  \"" << sf->ResolveFullPath()
-            << "\"\ndepends on the sources of a target it is used in.  This "
-               "is a dependency loop and is not allowed.";
-          this->GeneratorTarget->LocalGenerator->IssueMessage(
-            MessageType::FATAL_ERROR, e.str());
-          return;
-        }
-        if (emitted.insert(sf).second &&
-            this->SourcesQueued.insert(sf).second) {
-          this->SourceQueue.push(sf);
-        }
+  std::set<cmSourceFile*> emitted;
+  std::vector<std::string> const& configs =
+    this->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
+  for (std::string const& c : configs) {
+    std::vector<cmSourceFile*> sources;
+    this->GeneratorTarget->GetSourceFiles(sources, c);
+    for (cmSourceFile* sf : sources) {
+      const std::set<cmGeneratorTarget const*> tgts =
+        this->GlobalGenerator->GetFilenameTargetDepends(sf);
+      if (cm::contains(tgts, this->GeneratorTarget)) {
+        std::ostringstream e;
+        e << "Evaluation output file\n  \"" << sf->ResolveFullPath()
+          << "\"\ndepends on the sources of a target it is used in.  This "
+             "is a dependency loop and is not allowed.";
+        this->GeneratorTarget->LocalGenerator->IssueMessage(
+          MessageType::FATAL_ERROR, e.str());
+        return;
+      }
+      if (emitted.insert(sf).second && this->SourcesQueued.insert(sf).second) {
+        this->SourceQueue.push(sf);
       }
     }
   }
@@ -2971,7 +3063,7 @@
   // Queue the custom command dependencies.
   std::set<std::string> emitted;
   std::vector<std::string> const& configs =
-    this->Makefile->GetGeneratorConfigs();
+    this->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
   for (std::string const& conf : configs) {
     this->FollowCommandDepends(cc, conf, emitted);
   }
@@ -3111,7 +3203,7 @@
         } else {
           this->Makefile->IssueMessage(
             MessageType::FATAL_ERROR,
-            "Uknown CUDA architecture specifier \"" + std::string(specifier) +
+            "Unknown CUDA architecture specifier \"" + std::string(specifier) +
               "\".");
         }
       }
@@ -3360,23 +3452,24 @@
                       &dagChecker, entries);
 
   if (this->Makefile->IsOn("APPLE")) {
-    cmLinkImplementationLibraries const* impl =
-      this->GetLinkImplementationLibraries(config);
-    for (cmLinkImplItem const& lib : impl->Libraries) {
-      std::string libDir = cmSystemTools::CollapseFullPath(
-        lib.AsStr(), this->Makefile->GetHomeOutputDirectory());
+    if (cmLinkImplementationLibraries const* impl =
+          this->GetLinkImplementationLibraries(config)) {
+      for (cmLinkImplItem const& lib : impl->Libraries) {
+        std::string libDir = cmSystemTools::CollapseFullPath(
+          lib.AsStr(), this->Makefile->GetHomeOutputDirectory());
 
-      static cmsys::RegularExpression frameworkCheck(
-        "(.*\\.framework)(/Versions/[^/]+)?/[^/]+$");
-      if (!frameworkCheck.find(libDir)) {
-        continue;
+        static cmsys::RegularExpression frameworkCheck(
+          "(.*\\.framework)(/Versions/[^/]+)?/[^/]+$");
+        if (!frameworkCheck.find(libDir)) {
+          continue;
+        }
+
+        libDir = frameworkCheck.match(1);
+
+        EvaluatedTargetPropertyEntry ee(lib, cmListFileBacktrace());
+        ee.Values.emplace_back(std::move(libDir));
+        entries.Entries.emplace_back(std::move(ee));
       }
-
-      libDir = frameworkCheck.match(1);
-
-      EvaluatedTargetPropertyEntry ee(lib, cmListFileBacktrace());
-      ee.Values.emplace_back(std::move(libDir));
-      entries.Entries.emplace_back(std::move(ee));
     }
   }
 
@@ -3827,7 +3920,7 @@
       cmStrCat(generatorTarget->LocalGenerator->GetCurrentBinaryDirectory(),
                "/CMakeFiles/", generatorTarget->GetName(), ".dir/cmake_pch");
 
-    // For GCC the source extension will be tranformed into .h[xx].gch
+    // For GCC the source extension will be transformed into .h[xx].gch
     if (!this->Makefile->IsOn("CMAKE_LINK_PCH")) {
       const std::map<std::string, std::string> languageToExtension = {
         { "C", ".h.c" },
@@ -4414,12 +4507,75 @@
 
 bool cmGeneratorTarget::ComputeCompileFeatures(std::string const& config) const
 {
+  // Compute the language standard based on the compile features.
+  cmStandardLevelResolver standardResolver(this->Makefile);
   std::vector<BT<std::string>> features = this->GetCompileFeatures(config);
   for (BT<std::string> const& f : features) {
-    if (!this->Makefile->AddRequiredTargetFeature(this->Target, f.Value)) {
+    std::string lang;
+    if (!standardResolver.CompileFeatureKnown(this->Target->GetName(), f.Value,
+                                              lang, nullptr)) {
       return false;
     }
+
+    std::string key = cmStrCat(cmSystemTools::UpperCase(config), '-', lang);
+    cmProp currentLanguageStandard = this->GetLanguageStandard(lang, config);
+
+    std::string newRequiredStandard;
+    if (!standardResolver.GetNewRequiredStandard(
+          this->Target->GetName(), f.Value, currentLanguageStandard,
+          newRequiredStandard)) {
+      return false;
+    }
+
+    if (!newRequiredStandard.empty()) {
+      BTs<std::string>& languageStandardProperty =
+        this->LanguageStandardMap[key];
+      if (languageStandardProperty.Value != newRequiredStandard) {
+        languageStandardProperty.Value = newRequiredStandard;
+        languageStandardProperty.Backtraces.clear();
+      }
+      languageStandardProperty.Backtraces.emplace_back(f.Backtrace);
+    }
   }
+
+  return true;
+}
+
+bool cmGeneratorTarget::ComputeCompileFeatures(
+  std::string const& config, std::set<LanguagePair> const& languagePairs) const
+{
+  for (const auto& language : languagePairs) {
+    BTs<std::string> const* generatorTargetLanguageStandard =
+      this->GetLanguageStandardProperty(language.first, config);
+    if (!generatorTargetLanguageStandard) {
+      // If the standard isn't explicitly set we copy it over from the
+      // specified paired language.
+      std::string key =
+        cmStrCat(cmSystemTools::UpperCase(config), '-', language.first);
+      BTs<std::string> const* standardToCopy =
+        this->GetLanguageStandardProperty(language.second, config);
+      if (standardToCopy != nullptr) {
+        this->LanguageStandardMap[key] = *standardToCopy;
+        generatorTargetLanguageStandard = &this->LanguageStandardMap[key];
+      } else {
+        cmProp defaultStandard = this->Makefile->GetDef(
+          cmStrCat("CMAKE_", language.second, "_STANDARD_DEFAULT"));
+        if (defaultStandard != nullptr) {
+          this->LanguageStandardMap[key] = BTs<std::string>(*defaultStandard);
+          generatorTargetLanguageStandard = &this->LanguageStandardMap[key];
+        }
+      }
+
+      // Custom updates for the CUDA standard.
+      if (generatorTargetLanguageStandard != nullptr &&
+          language.first == "CUDA") {
+        if (generatorTargetLanguageStandard->Value == "98") {
+          this->LanguageStandardMap[key].Value = "03";
+        }
+      }
+    }
+  }
+
   return true;
 }
 
@@ -5297,8 +5453,7 @@
   }
 
   cmProp value = tgt->GetProperty(prop);
-  return cmIsOn(
-    genexInterpreter->Evaluate(value ? value->c_str() : nullptr, prop));
+  return cmIsOn(genexInterpreter->Evaluate(value ? *value : "", prop));
 }
 
 template <>
@@ -5312,8 +5467,7 @@
     return value ? value->c_str() : nullptr;
   }
 
-  return genexInterpreter->Evaluate(value ? value->c_str() : nullptr, prop)
-    .c_str();
+  return genexInterpreter->Evaluate(value ? *value : "", prop).c_str();
 }
 
 template <>
@@ -5327,7 +5481,7 @@
     return valueAsString(value ? value->c_str() : nullptr);
   }
 
-  return genexInterpreter->Evaluate(value ? value->c_str() : nullptr, prop);
+  return genexInterpreter->Evaluate(value ? *value : "", prop);
 }
 
 template <typename PropertyType>
@@ -5728,7 +5882,7 @@
   // not it is overridden by a property.
   cmProp runtimeLibraryDefault = this->Makefile->GetDef(
     cmStrCat("CMAKE_", lang, "_RUNTIME_LIBRARY_DEFAULT"));
-  if (!runtimeLibraryDefault || runtimeLibraryDefault->empty()) {
+  if (!cmNonempty(runtimeLibraryDefault)) {
     return std::string();
   }
   cmProp runtimeLibraryValue =
@@ -6410,15 +6564,20 @@
                           iface.HadHeadSensitiveCondition,
                           iface.HadContextSensitiveCondition,
                           iface.HadLinkLanguageSensitiveCondition);
-  } else if (!cmp0022NEW)
+    return;
+  }
+
   // If CMP0022 is NEW then the plain tll signature sets the
   // INTERFACE_LINK_LIBRARIES, so if we get here then the project
   // cleared the property explicitly and we should not fall back
   // to the link implementation.
-  {
-    // The link implementation is the default link interface.
-    cmLinkImplementationLibraries const* impl =
-      this->GetLinkImplementationLibrariesInternal(config, headTarget);
+  if (cmp0022NEW) {
+    return;
+  }
+
+  // The link implementation is the default link interface.
+  if (cmLinkImplementationLibraries const* impl =
+        this->GetLinkImplementationLibrariesInternal(config, headTarget)) {
     iface.Libraries.insert(iface.Libraries.end(), impl->Libraries.begin(),
                            impl->Libraries.end());
     if (this->GetPolicyStatusCMP0022() == cmPolicies::WARN &&
@@ -6712,8 +6871,8 @@
 const cmLinkImplementation* cmGeneratorTarget::GetLinkImplementation(
   const std::string& config, bool secondPass) const
 {
-  // There is no link implementation for imported targets.
-  if (this->IsImported()) {
+  // There is no link implementation for targets that cannot compile sources.
+  if (!this->CanCompileSources()) {
     return nullptr;
   }
 
@@ -6737,7 +6896,7 @@
   std::vector<cmSourceFile*>& files) const
 {
   std::vector<std::string> const& configs =
-    this->Makefile->GetGeneratorConfigs();
+    this->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
 
   auto it = configs.begin();
   const std::string& firstConfig = *it;
@@ -6861,7 +7020,7 @@
 bool cmGeneratorTarget::IsDeprecated() const
 {
   cmProp deprecation = this->GetProperty("DEPRECATION");
-  return deprecation && !deprecation->empty();
+  return cmNonempty(deprecation);
 }
 
 std::string cmGeneratorTarget::GetDeprecation() const
@@ -6876,6 +7035,11 @@
 void cmGeneratorTarget::GetLanguages(std::set<std::string>& languages,
                                      const std::string& config) const
 {
+  // Targets that do not compile anything have no languages.
+  if (!this->CanCompileSources()) {
+    return;
+  }
+
   std::vector<cmSourceFile*> sourceFiles;
   this->GetSourceFiles(sourceFiles, config);
   for (cmSourceFile* src : sourceFiles) {
@@ -6926,7 +7090,7 @@
   // Consider an explicit linker language property, but *not* the
   // computed linker language that may depend on linked targets.
   cmProp linkLang = this->GetProperty("LINKER_LANGUAGE");
-  if (linkLang && !linkLang->empty()) {
+  if (cmNonempty(linkLang)) {
     languages.insert(*linkLang);
   }
   return languages.size() == 1 && languages.count("CSharp") > 0;
@@ -6971,8 +7135,8 @@
 cmGeneratorTarget::GetLinkImplementationLibrariesInternal(
   const std::string& config, cmGeneratorTarget const* head) const
 {
-  // There is no link implementation for imported targets.
-  if (this->IsImported()) {
+  // There is no link implementation for targets that cannot compile sources.
+  if (!this->CanCompileSources()) {
     return nullptr;
   }
 
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index 3aedbf5..4a03f65 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -45,8 +45,10 @@
 
   cmGlobalGenerator* GetGlobalGenerator() const;
 
+  bool IsInBuildSystem() const;
   bool IsImported() const;
   bool IsImportedGloballyVisible() const;
+  bool CanCompileSources() const;
   const std::string& GetLocation(const std::string& config) const;
 
   std::vector<cmCustomCommand> const& GetPreBuildCommands() const;
@@ -148,6 +150,16 @@
   bool HasExplicitObjectName(cmSourceFile const* file) const;
   void AddExplicitObjectName(cmSourceFile const* sf);
 
+  BTs<std::string> const* GetLanguageStandardProperty(
+    std::string const& lang, std::string const& config) const;
+
+  cmProp GetLanguageStandard(std::string const& lang,
+                             std::string const& config) const;
+
+  cmProp GetLanguageExtensions(std::string const& lang) const;
+
+  bool GetLanguageStandardRequired(std::string const& lang) const;
+
   void GetModuleDefinitionSources(std::vector<cmSourceFile const*>&,
                                   const std::string& config) const;
   void GetExternalObjects(std::vector<cmSourceFile const*>&,
@@ -165,8 +177,8 @@
 
   void ComputeObjectMapping();
 
-  const char* GetFeature(const std::string& feature,
-                         const std::string& config) const;
+  cmProp GetFeature(const std::string& feature,
+                    const std::string& config) const;
 
   const char* GetLinkPIEProperty(const std::string& config) const;
 
@@ -515,6 +527,11 @@
 
   bool ComputeCompileFeatures(std::string const& config) const;
 
+  using LanguagePair = std::pair<std::string, std::string>;
+  bool ComputeCompileFeatures(
+    std::string const& config,
+    std::set<LanguagePair> const& languagePairs) const;
+
   /**
    * Trace through the source files in this target and add al source files
    * that they depend on, used by all generators
@@ -1038,6 +1055,11 @@
   bool GetRPATH(const std::string& config, const std::string& prop,
                 std::string& rpath) const;
 
+  mutable std::map<std::string, BTs<std::string>> LanguageStandardMap;
+
+  cmProp GetPropertyWithPairedLanguageSupport(std::string const& lang,
+                                              const char* suffix) const;
+
 public:
   const std::vector<const cmGeneratorTarget*>& GetLinkImplementationClosure(
     const std::string& config) const;
diff --git a/Source/cmGetFilenameComponentCommand.cxx b/Source/cmGetFilenameComponentCommand.cxx
index 811421a..38bffbf 100644
--- a/Source/cmGetFilenameComponentCommand.cxx
+++ b/Source/cmGetFilenameComponentCommand.cxx
@@ -14,6 +14,7 @@
 {
   if (args.size() < 3) {
     status.SetError("called with incorrect number of arguments");
+    cmSystemTools::SetFatalErrorOccured();
     return false;
   }
 
@@ -114,6 +115,7 @@
   } else {
     std::string err = "unknown component " + args[2];
     status.SetError(err);
+    cmSystemTools::SetFatalErrorOccured();
     return false;
   }
 
diff --git a/Source/cmGetPropertyCommand.cxx b/Source/cmGetPropertyCommand.cxx
index cba7704..cdfd8c8 100644
--- a/Source/cmGetPropertyCommand.cxx
+++ b/Source/cmGetPropertyCommand.cxx
@@ -17,7 +17,6 @@
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
 #include "cmTarget.h"
-#include "cmTargetPropertyComputer.h"
 #include "cmTest.h"
 #include "cmake.h"
 
@@ -364,12 +363,9 @@
     cmProp prop_cstr = nullptr;
     cmListFileBacktrace bt = status.GetMakefile().GetBacktrace();
     cmMessenger* messenger = status.GetMakefile().GetMessenger();
-    if (cmTargetPropertyComputer::PassesWhitelist(
-          target->GetType(), propertyName, messenger, bt)) {
-      prop_cstr = target->GetComputedProperty(propertyName, messenger, bt);
-      if (!prop_cstr) {
-        prop_cstr = target->GetProperty(propertyName);
-      }
+    prop_cstr = target->GetComputedProperty(propertyName, messenger, bt);
+    if (!prop_cstr) {
+      prop_cstr = target->GetProperty(propertyName);
     }
     return StoreResult(infoType, status.GetMakefile(), variable,
                        prop_cstr ? prop_cstr->c_str() : nullptr);
diff --git a/Source/cmGetTargetPropertyCommand.cxx b/Source/cmGetTargetPropertyCommand.cxx
index 8a304be..78a17d2 100644
--- a/Source/cmGetTargetPropertyCommand.cxx
+++ b/Source/cmGetTargetPropertyCommand.cxx
@@ -12,7 +12,6 @@
 #include "cmPolicies.h"
 #include "cmProperty.h"
 #include "cmTarget.h"
-#include "cmTargetPropertyComputer.h"
 
 class cmMessenger;
 
@@ -46,12 +45,9 @@
       cmProp prop_cstr = nullptr;
       cmListFileBacktrace bt = mf.GetBacktrace();
       cmMessenger* messenger = mf.GetMessenger();
-      if (cmTargetPropertyComputer::PassesWhitelist(tgt->GetType(), args[2],
-                                                    messenger, bt)) {
-        prop_cstr = tgt->GetComputedProperty(args[2], messenger, bt);
-        if (!prop_cstr) {
-          prop_cstr = tgt->GetProperty(args[2]);
-        }
+      prop_cstr = tgt->GetComputedProperty(args[2], messenger, bt);
+      if (!prop_cstr) {
+        prop_cstr = tgt->GetProperty(args[2]);
       }
       if (prop_cstr) {
         prop = *prop_cstr;
diff --git a/Source/cmGhsMultiTargetGenerator.cxx b/Source/cmGhsMultiTargetGenerator.cxx
index 97580d6..1589c47 100644
--- a/Source/cmGhsMultiTargetGenerator.cxx
+++ b/Source/cmGhsMultiTargetGenerator.cxx
@@ -550,10 +550,9 @@
    */
   for (auto& sg : groupFilesList) {
     std::ostream* fout;
-    cmProp noSourceGroupFile =
-      this->GeneratorTarget->GetProperty("GHS_NO_SOURCE_GROUP_FILE");
-    bool useProjectFile = (noSourceGroupFile && cmIsOn(*noSourceGroupFile)) ||
-      cmIsOn(this->Makefile->GetDefinition("CMAKE_GHS_NO_SOURCE_GROUP_FILE"));
+    bool useProjectFile =
+      cmIsOn(this->GeneratorTarget->GetProperty("GHS_NO_SOURCE_GROUP_FILE")) ||
+      this->Makefile->IsOn("CMAKE_GHS_NO_SOURCE_GROUP_FILE");
     if (useProjectFile || sg.empty()) {
       fout = &fout_proj;
     } else {
diff --git a/Source/cmGhsMultiTargetGenerator.h b/Source/cmGhsMultiTargetGenerator.h
index f03ca44..5f26387 100644
--- a/Source/cmGhsMultiTargetGenerator.h
+++ b/Source/cmGhsMultiTargetGenerator.h
@@ -43,7 +43,7 @@
   void SetCompilerFlags(std::string const& config,
                         const std::string& language);
 
-  std::string GetDefines(const std::string& langugae,
+  std::string GetDefines(const std::string& language,
                          std::string const& config);
 
   void WriteIncludes(std::ostream& fout, const std::string& config,
diff --git a/Source/cmGlobalCommonGenerator.cxx b/Source/cmGlobalCommonGenerator.cxx
index 9dc86f4..9e5bbca 100644
--- a/Source/cmGlobalCommonGenerator.cxx
+++ b/Source/cmGlobalCommonGenerator.cxx
@@ -5,8 +5,12 @@
 #include <memory>
 #include <utility>
 
+#include <cmext/algorithm>
+
+#include "cmGeneratorExpression.h"
 #include "cmGeneratorTarget.h"
 #include "cmLocalGenerator.h"
+#include "cmMakefile.h"
 #include "cmProperty.h"
 #include "cmStateDirectory.h"
 #include "cmStateSnapshot.h"
@@ -31,26 +35,30 @@
       lg->GetStateSnapshot().GetDirectory().GetCurrentBinary());
     DirectoryTarget& dirTarget = dirTargets[currentBinaryDir];
     dirTarget.LG = lg.get();
+    const std::vector<std::string>& configs =
+      lg->GetMakefile()->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
 
     // The directory-level rule should depend on the target-level rules
     // for all targets in the directory.
     for (const auto& gt : lg->GetGeneratorTargets()) {
       cmStateEnums::TargetType const type = gt->GetType();
-      if (type != cmStateEnums::EXECUTABLE &&
-          type != cmStateEnums::STATIC_LIBRARY &&
-          type != cmStateEnums::SHARED_LIBRARY &&
-          type != cmStateEnums::MODULE_LIBRARY &&
-          type != cmStateEnums::OBJECT_LIBRARY &&
-          type != cmStateEnums::UTILITY) {
+      if (type == cmStateEnums::GLOBAL_TARGET || !gt->IsInBuildSystem()) {
         continue;
       }
       DirectoryTarget::Target t;
       t.GT = gt.get();
-      if (cmProp exclude = gt->GetProperty("EXCLUDE_FROM_ALL")) {
-        if (cmIsOn(*exclude)) {
-          // This target has been explicitly excluded.
-          t.ExcludeFromAll = true;
-        } else {
+      const std::string EXCLUDE_FROM_ALL("EXCLUDE_FROM_ALL");
+      if (cmProp exclude = gt->GetProperty(EXCLUDE_FROM_ALL)) {
+        for (const std::string& config : configs) {
+          cmGeneratorExpressionInterpreter genexInterpreter(lg.get(), config,
+                                                            gt.get());
+          if (cmIsOn(genexInterpreter.Evaluate(*exclude, EXCLUDE_FROM_ALL))) {
+            // This target has been explicitly excluded.
+            t.ExcludedFromAllInConfigs.push_back(config);
+          }
+        }
+
+        if (t.ExcludedFromAllInConfigs.empty()) {
           // This target has been explicitly un-excluded.  The directory-level
           // rule for every directory between this and the root should depend
           // on the target-level rule for this target.
@@ -78,3 +86,12 @@
 
   return dirTargets;
 }
+
+bool cmGlobalCommonGenerator::IsExcludedFromAllInConfig(
+  const DirectoryTarget::Target& t, const std::string& config)
+{
+  if (this->IsMultiConfig()) {
+    return cm::contains(t.ExcludedFromAllInConfigs, config);
+  }
+  return !t.ExcludedFromAllInConfigs.empty();
+}
diff --git a/Source/cmGlobalCommonGenerator.h b/Source/cmGlobalCommonGenerator.h
index 7d16dac..f97b5f4 100644
--- a/Source/cmGlobalCommonGenerator.h
+++ b/Source/cmGlobalCommonGenerator.h
@@ -30,7 +30,7 @@
     struct Target
     {
       cmGeneratorTarget const* GT = nullptr;
-      bool ExcludeFromAll = false;
+      std::vector<std::string> ExcludedFromAllInConfigs;
     };
     std::vector<Target> Targets;
     struct Dir
@@ -41,6 +41,8 @@
     std::vector<Dir> Children;
   };
   std::map<std::string, DirectoryTarget> ComputeDirectoryTargets() const;
+  bool IsExcludedFromAllInConfig(const DirectoryTarget::Target& t,
+                                 const std::string& config);
 };
 
 #endif
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index 4dc4092..cad5d1f 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -235,6 +235,14 @@
   }
   cmProp cname =
     this->GetCMakeInstance()->GetState()->GetInitializedCacheValue(langComp);
+
+  // Split compiler from arguments
+  std::vector<std::string> cnameArgVec;
+  if (cname && !cname->empty()) {
+    cmExpandList(*cname, cnameArgVec);
+    cname = &cnameArgVec.front();
+  }
+
   std::string changeVars;
   if (cname && !optional) {
     std::string cnameString;
@@ -302,31 +310,12 @@
   bool failed = false;
   for (const auto& localGen : this->LocalGenerators) {
     for (const auto& target : localGen->GetGeneratorTargets()) {
-      if (target->GetType() == cmStateEnums::TargetType::GLOBAL_TARGET ||
-          target->GetType() == cmStateEnums::TargetType::INTERFACE_LIBRARY ||
-          target->GetType() == cmStateEnums::TargetType::UTILITY) {
+      if (!target->CanCompileSources() ||
+          cmIsOn(target->GetProperty("ghs_integrity_app"))) {
         continue;
       }
-      if (cmProp p = target->GetProperty("ghs_integrity_app")) {
-        if (cmIsOn(*p)) {
-          continue;
-        }
-      }
 
-      std::vector<std::string> configs;
-      target->Makefile->GetConfigurations(configs);
-      std::vector<cmSourceFile*> srcs;
-      if (configs.empty()) {
-        target->GetSourceFiles(srcs, "");
-      } else {
-        for (std::string const& config : configs) {
-          target->GetSourceFiles(srcs, config);
-          if (!srcs.empty()) {
-            break;
-          }
-        }
-      }
-      if (srcs.empty()) {
+      if (target->GetAllConfigSources().empty()) {
         std::ostringstream e;
         e << "No SOURCES given to target: " << target->GetName();
         this->GetCMakeInstance()->IssueMessage(
@@ -349,7 +338,8 @@
       if (target->GetType() == cmStateEnums::EXECUTABLE &&
           target->GetPropertyAsBool("WIN32_EXECUTABLE")) {
         std::vector<std::string> const& configs =
-          target->Makefile->GetGeneratorConfigs();
+          target->Makefile->GetGeneratorConfigs(
+            cmMakefile::IncludeEmptyConfig);
         for (std::string const& config : configs) {
           if (target->GetLinkerLanguage(config) == "Swift") {
             this->GetCMakeInstance()->IssueMessage(
@@ -374,16 +364,10 @@
   bool failed = false;
   for (const auto& generator : this->LocalGenerators) {
     for (const auto& target : generator->GetGeneratorTargets()) {
-      if (target->GetType() == cmStateEnums::TargetType::GLOBAL_TARGET ||
-          target->GetType() == cmStateEnums::TargetType::INTERFACE_LIBRARY ||
-          target->GetType() == cmStateEnums::TargetType::UTILITY) {
+      if (!target->CanCompileSources() ||
+          cmIsOn(target->GetProperty("ghs_integrity_app"))) {
         continue;
       }
-      if (cmProp p = target->GetProperty("ghs_integrity_app")) {
-        if (cmIsOn(*p)) {
-          continue;
-        }
-      }
 
       std::string const& reuseFrom =
         target->GetSafeProperty("PRECOMPILE_HEADERS_REUSE_FROM");
@@ -425,15 +409,13 @@
       "all generators must specify this->FindMakeProgramFile");
     return false;
   }
-  if (!mf->GetDefinition("CMAKE_MAKE_PROGRAM") ||
-      cmIsOff(mf->GetDefinition("CMAKE_MAKE_PROGRAM"))) {
+  if (cmIsOff(mf->GetDefinition("CMAKE_MAKE_PROGRAM"))) {
     std::string setMakeProgram = mf->GetModulesFile(this->FindMakeProgramFile);
     if (!setMakeProgram.empty()) {
       mf->ReadListFile(setMakeProgram);
     }
   }
-  if (!mf->GetDefinition("CMAKE_MAKE_PROGRAM") ||
-      cmIsOff(mf->GetDefinition("CMAKE_MAKE_PROGRAM"))) {
+  if (cmIsOff(mf->GetDefinition("CMAKE_MAKE_PROGRAM"))) {
     std::ostringstream err;
     err << "CMake was unable to find a build program corresponding to \""
         << this->GetName() << "\".  CMAKE_MAKE_PROGRAM is not set.  You "
@@ -596,6 +578,16 @@
       mf->ReadListFile(fpath);
     }
   }
+
+  if (readCMakeSystem) {
+    // Find the native build tool for this generator.
+    // This has to be done early so that MSBuild can be used to examine the
+    // cross-compilation environment.
+    if (!this->FindMakeProgram(mf)) {
+      return;
+    }
+  }
+
   //  Load the CMakeDetermineSystem.cmake file and find out
   // what platform we are running on
   if (!mf->GetDefinition("CMAKE_SYSTEM")) {
@@ -667,11 +659,6 @@
       cmSystemTools::SetFatalErrorOccured();
       return;
     }
-
-    // Find the native build tool for this generator.
-    if (!this->FindMakeProgram(mf)) {
-      return;
-    }
   }
 
   // Check that the languages are supported by the generator and its
@@ -794,7 +781,7 @@
     std::string compilerEnv = cmStrCat("CMAKE_", lang, "_COMPILER_ENV_VAR");
     std::ostringstream noCompiler;
     const char* compilerFile = mf->GetDefinition(compilerName);
-    if (!compilerFile || !*compilerFile || cmIsNOTFOUND(compilerFile)) {
+    if (!cmNonempty(compilerFile) || cmIsNOTFOUND(compilerFile)) {
       /* clang-format off */
       noCompiler <<
         "No " << compilerName << " could be found.\n"
@@ -1442,12 +1429,10 @@
     localGen->AddHelperCommands();
   }
 
-  // Finalize the set of compile features for each target.
-  // FIXME: This turns into calls to cmMakefile::AddRequiredTargetFeature
-  // which actually modifies the <lang>_STANDARD target property
-  // on the original cmTarget instance.  It accumulates features
-  // across all configurations.  Some refactoring is needed to
-  // compute a per-config resulta purely during generation.
+  // Perform up-front computation in order to handle errors (such as unknown
+  // features) at this point. While processing the compile features we also
+  // calculate and cache the language standard required by the compile
+  // features.
   for (const auto& localGen : this->LocalGenerators) {
     if (!localGen->ComputeTargetCompileFeatures()) {
       return false;
@@ -1612,9 +1597,7 @@
   for (const auto& lg : this->LocalGenerators) {
     lg->CreateEvaluationFileOutputs();
     for (const auto& gt : lg->GetGeneratorTargets()) {
-      if (gt->GetType() == cmStateEnums::INTERFACE_LIBRARY ||
-          gt->GetType() == cmStateEnums::UTILITY ||
-          gt->GetType() == cmStateEnums::GLOBAL_TARGET) {
+      if (!gt->CanCompileSources()) {
         continue;
       }
       lg->AddUnityBuild(gt.get());
@@ -1626,9 +1609,7 @@
   }
   for (const auto& lg : this->LocalGenerators) {
     for (const auto& gt : lg->GetGeneratorTargets()) {
-      if (gt->GetType() == cmStateEnums::INTERFACE_LIBRARY ||
-          gt->GetType() == cmStateEnums::UTILITY ||
-          gt->GetType() == cmStateEnums::GLOBAL_TARGET) {
+      if (!gt->CanCompileSources()) {
         continue;
       }
       // Handle targets that re-use a PCH from an above-handled target.
@@ -1698,8 +1679,8 @@
       cmPolicies::PolicyStatus polSt =
         mf->GetPolicyStatus(cmPolicies::CMP0043);
       if (polSt == cmPolicies::WARN || polSt == cmPolicies::OLD) {
-        std::vector<std::string> configs;
-        mf->GetConfigurations(configs);
+        std::vector<std::string> configs =
+          mf->GetGeneratorConfigs(cmMakefile::ExcludeEmptyConfig);
 
         for (std::string const& c : configs) {
           std::string defPropName =
@@ -1988,8 +1969,9 @@
   std::string makeCommandStr;
   output += "\nRun Build Command(s):";
 
-  for (auto command = makeCommand.begin(); command != makeCommand.end();
-       ++command) {
+  retVal = 0;
+  for (auto command = makeCommand.begin();
+       command != makeCommand.end() && retVal == 0; ++command) {
     makeCommandStr = command->Printable();
     if (command != makeCommand.end()) {
       makeCommandStr += " && ";
@@ -2179,13 +2161,38 @@
 }
 
 bool cmGlobalGenerator::IsExcluded(cmLocalGenerator* root,
-                                   cmGeneratorTarget* target) const
+                                   const cmGeneratorTarget* target) const
 {
-  if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+  if (!target->IsInBuildSystem()) {
     return true;
   }
-  if (cmProp exclude = target->GetProperty("EXCLUDE_FROM_ALL")) {
-    return cmIsOn(*exclude);
+  cmMakefile* mf = root->GetMakefile();
+  const std::string EXCLUDE_FROM_ALL = "EXCLUDE_FROM_ALL";
+  if (cmProp exclude = target->GetProperty(EXCLUDE_FROM_ALL)) {
+    // Expand the property value per configuration.
+    unsigned int trueCount = 0;
+    unsigned int falseCount = 0;
+    const std::vector<std::string>& configs =
+      mf->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
+    for (const std::string& config : configs) {
+      cmGeneratorExpressionInterpreter genexInterpreter(root, config, target);
+      if (cmIsOn(genexInterpreter.Evaluate(*exclude, EXCLUDE_FROM_ALL))) {
+        ++trueCount;
+      } else {
+        ++falseCount;
+      }
+    }
+
+    // Check whether the genex expansion of the property agrees in all
+    // configurations.
+    if (trueCount && falseCount) {
+      std::ostringstream e;
+      e << "The EXCLUDE_FROM_ALL property of target \"" << target->GetName()
+        << "\" varies by configuration. This is not supported by the \""
+        << root->GetGlobalGenerator()->GetName() << "\" generator.";
+      mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
+    }
+    return trueCount;
   }
   // This target is included in its directory.  Check whether the
   // directory is excluded.
@@ -2445,7 +2452,7 @@
   gti.WorkingDir = mf->GetCurrentBinaryDirectory();
   cmCustomCommandLine singleLine;
   singleLine.push_back(cmSystemTools::GetCPackCommand());
-  if (cmakeCfgIntDir && *cmakeCfgIntDir && cmakeCfgIntDir[0] != '.') {
+  if (cmNonempty(cmakeCfgIntDir) && cmakeCfgIntDir[0] != '.') {
     singleLine.push_back("-C");
     singleLine.push_back(cmakeCfgIntDir);
   }
@@ -2530,7 +2537,7 @@
       singleLine.push_back(arg);
     }
   }
-  if (cmakeCfgIntDir && *cmakeCfgIntDir && cmakeCfgIntDir[0] != '.') {
+  if (cmNonempty(cmakeCfgIntDir) && cmakeCfgIntDir[0] != '.') {
     singleLine.push_back("-C");
     singleLine.push_back(cmakeCfgIntDir);
   } else // TODO: This is a hack. Should be something to do with the
@@ -2611,7 +2618,7 @@
       "installation rules have been specified",
       mf->GetBacktrace());
   } else if (this->InstallTargetEnabled && !skipInstallRules) {
-    if (!cmakeCfgIntDir || !*cmakeCfgIntDir || cmakeCfgIntDir[0] == '.') {
+    if (!(cmNonempty(cmakeCfgIntDir) && cmakeCfgIntDir[0] != '.')) {
       std::set<std::string>* componentsSet = &this->InstallComponents;
       std::ostringstream ostr;
       if (!componentsSet->empty()) {
@@ -2650,7 +2657,7 @@
       cmd = "cmake";
     }
     singleLine.push_back(cmd);
-    if (cmakeCfgIntDir && *cmakeCfgIntDir && cmakeCfgIntDir[0] != '.') {
+    if (cmNonempty(cmakeCfgIntDir) && cmakeCfgIntDir[0] != '.') {
       std::string cfgArg = "-DBUILD_TYPE=";
       bool useEPN = this->UseEffectivePlatformName(mf.get());
       if (useEPN) {
@@ -3045,7 +3052,7 @@
 
   for (const auto& lg : this->LocalGenerators) {
     for (const auto& tgt : lg->GetGeneratorTargets()) {
-      if (tgt->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+      if (!tgt->IsInBuildSystem()) {
         continue;
       }
       this->WriteSummary(tgt.get());
@@ -3123,7 +3130,8 @@
     fout << "# Source files and their labels\n";
     std::vector<cmSourceFile*> sources;
     std::vector<std::string> const& configs =
-      target->Target->GetMakefile()->GetGeneratorConfigs();
+      target->Target->GetMakefile()->GetGeneratorConfigs(
+        cmMakefile::IncludeEmptyConfig);
     for (std::string const& c : configs) {
       target->GetSourceFiles(sources, c);
     }
@@ -3222,8 +3230,9 @@
   const auto& lg = this->LocalGenerators[0];
   cmMakefile* mf = lg->GetMakefile();
 
-  std::vector<std::string> configs;
-  std::string config = mf->GetConfigurations(configs, false);
+  std::vector<std::string> configs =
+    mf->GetGeneratorConfigs(cmMakefile::OnlyMultiConfig);
+  std::string config = mf->GetDefaultConfiguration();
 
   std::string path = cmStrCat(this->CMakeInstance->GetHomeOutputDirectory(),
                               "/CPackProperties.cmake");
diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h
index 57c7808..c2c80c2 100644
--- a/Source/cmGlobalGenerator.h
+++ b/Source/cmGlobalGenerator.h
@@ -542,7 +542,8 @@
   bool IsExcluded(cmStateSnapshot const& root,
                   cmStateSnapshot const& snp) const;
   bool IsExcluded(cmLocalGenerator* root, cmLocalGenerator* gen) const;
-  bool IsExcluded(cmLocalGenerator* root, cmGeneratorTarget* target) const;
+  bool IsExcluded(cmLocalGenerator* root,
+                  const cmGeneratorTarget* target) const;
   virtual void InitializeProgressMarks() {}
 
   struct GlobalTargetInfo
diff --git a/Source/cmGlobalGeneratorFactory.h b/Source/cmGlobalGeneratorFactory.h
index 3709365..13cfe4d 100644
--- a/Source/cmGlobalGeneratorFactory.h
+++ b/Source/cmGlobalGeneratorFactory.h
@@ -44,7 +44,7 @@
   /** Get the list of supported platforms name for this generator */
   virtual std::vector<std::string> GetKnownPlatforms() const = 0;
 
-  /** If the generator suports platforms, get its default.  */
+  /** If the generator supports platforms, get its default.  */
   virtual std::string GetDefaultPlatformName() const = 0;
 };
 
diff --git a/Source/cmGlobalGhsMultiGenerator.cxx b/Source/cmGlobalGhsMultiGenerator.cxx
index d36adfb..7c87131 100644
--- a/Source/cmGlobalGhsMultiGenerator.cxx
+++ b/Source/cmGlobalGhsMultiGenerator.cxx
@@ -218,10 +218,11 @@
 {
   const char* ghsRoot = mf->GetDefinition("GHS_TOOLSET_ROOT");
 
-  if (!ghsRoot || ghsRoot[0] == '\0') {
-    ghsRoot = DEFAULT_TOOLSET_ROOT;
+  if (cmNonempty(ghsRoot)) {
+    tsd = ghsRoot;
+  } else {
+    tsd = DEFAULT_TOOLSET_ROOT;
   }
-  tsd = ghsRoot;
 
   if (ts.empty()) {
     std::vector<std::string> output;
@@ -467,11 +468,10 @@
     this->ProjectTargets.push_back(t);
   }
   for (cmGeneratorTarget const* t : sortedProjectTargets) {
-    if (t->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+    if (!t->IsInBuildSystem()) {
       continue;
     }
-    cmProp p = t->GetProperty("EXCLUDE_FROM_ALL");
-    if (!(p && cmIsOn(*p))) {
+    if (!IsExcluded(t->GetLocalGenerator(), t)) {
       defaultTargets.push_back(t);
     }
   }
@@ -635,7 +635,7 @@
   std::string tgt;
   const char* t =
     this->GetCMakeInstance()->GetCacheDefinition("GHS_PRIMARY_TARGET");
-  if (t && *t != '\0') {
+  if (cmNonempty(t)) {
     tgt = t;
     this->GetCMakeInstance()->MarkCliAsUsed("GHS_PRIMARY_TARGET");
   } else {
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index 843b0f4..f0fa1f4 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -5,9 +5,9 @@
 #include <algorithm>
 #include <cctype>
 #include <cstdio>
-#include <iterator>
 #include <sstream>
 
+#include <cm/iterator>
 #include <cm/memory>
 #include <cmext/algorithm>
 #include <cmext/memory>
@@ -518,7 +518,8 @@
 
   if (cmSystemTools::GetErrorOccuredFlag()) {
     this->RulesFileStream->setstate(std::ios::failbit);
-    for (auto const& config : this->Makefiles[0]->GetGeneratorConfigs()) {
+    for (auto const& config : this->Makefiles[0]->GetGeneratorConfigs(
+           cmMakefile::IncludeEmptyConfig)) {
       this->GetImplFileStream(config)->setstate(std::ios::failbit);
       this->GetConfigFileStream(config)->setstate(std::ios::failbit);
     }
@@ -1092,6 +1093,7 @@
     }
     // FALLTHROUGH
     case cmStateEnums::GLOBAL_TARGET:
+    case cmStateEnums::INTERFACE_LIBRARY:
     case cmStateEnums::UTILITY: {
       std::string path =
         cmStrCat(target->GetLocalGenerator()->GetCurrentBinaryDirectory(), '/',
@@ -1104,8 +1106,8 @@
       break;
     }
 
-    default:
-      return;
+    case cmStateEnums::UNKNOWN_LIBRARY:
+      break;
   }
 }
 
@@ -1127,7 +1129,7 @@
     cmNinjaDeps outs;
     for (cmTargetDepend const& targetDep :
          this->GetTargetDirectDepends(target)) {
-      if (targetDep->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+      if (!targetDep->IsInBuildSystem()) {
         continue;
       }
       if (targetDep.IsCross()) {
@@ -1169,7 +1171,7 @@
     cmNinjaOuts this_outs; // this will be the new cache entry
 
     for (auto const& dep_target : this->GetTargetDirectDepends(target)) {
-      if (dep_target->GetType() == cmStateEnums::INTERFACE_LIBRARY ||
+      if (!dep_target->IsInBuildSystem() ||
           (this->EnableCrossConfigBuild() && !dep_target.IsCross())) {
         continue;
       }
@@ -1188,7 +1190,7 @@
   // finally generate the outputs of the target itself, if applicable
   cmNinjaDeps outs;
   if (!omit_self) {
-    this->AppendTargetOutputs(target, outs, config);
+    this->AppendTargetOutputs(target, outs, config, DependOnTargetArtifact);
   }
   outputs.insert(outs.begin(), outs.end());
 }
@@ -1200,14 +1202,15 @@
   std::string outputPath = this->NinjaOutputPath(alias);
   std::string buildAlias = this->BuildAlias(outputPath, config);
   cmNinjaDeps outputs;
-  this->AppendTargetOutputs(target, outputs, config);
+  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) {
     this->TargetAliases[output].GeneratorTarget = nullptr;
     this->DefaultTargetAliases[output].GeneratorTarget = nullptr;
     for (const std::string& config2 :
-         this->Makefiles.front()->GetGeneratorConfigs()) {
+         this->Makefiles.front()->GetGeneratorConfigs(
+           cmMakefile::IncludeEmptyConfig)) {
       this->Configs[config2].TargetAliases[output].GeneratorTarget = nullptr;
     }
   }
@@ -1265,11 +1268,12 @@
     if (ta.second.Config == "all") {
       for (auto const& config : this->CrossConfigs) {
         this->AppendTargetOutputs(ta.second.GeneratorTarget,
-                                  build.ExplicitDeps, config);
+                                  build.ExplicitDeps, config,
+                                  DependOnTargetArtifact);
       }
     } else {
       this->AppendTargetOutputs(ta.second.GeneratorTarget, build.ExplicitDeps,
-                                ta.second.Config);
+                                ta.second.Config, DependOnTargetArtifact);
     }
     this->WriteBuild(this->EnableCrossConfigBuild() &&
                          (ta.second.Config == "all" ||
@@ -1280,7 +1284,8 @@
   }
 
   if (this->IsMultiConfig()) {
-    for (auto const& config : this->Makefiles.front()->GetGeneratorConfigs()) {
+    for (auto const& config : this->Makefiles.front()->GetGeneratorConfigs(
+           cmMakefile::IncludeEmptyConfig)) {
       for (auto const& ta : this->Configs[config].TargetAliases) {
         // Don't write ambiguous aliases.
         if (!ta.second.GeneratorTarget) {
@@ -1296,7 +1301,8 @@
         build.Outputs.front() = ta.first;
         build.ExplicitDeps.clear();
         this->AppendTargetOutputs(ta.second.GeneratorTarget,
-                                  build.ExplicitDeps, config);
+                                  build.ExplicitDeps, config,
+                                  DependOnTargetArtifact);
         this->WriteBuild(*this->GetConfigFileStream(config), build);
       }
     }
@@ -1318,7 +1324,8 @@
         build.ExplicitDeps.clear();
         for (auto const& config : this->DefaultConfigs) {
           this->AppendTargetOutputs(ta.second.GeneratorTarget,
-                                    build.ExplicitDeps, config);
+                                    build.ExplicitDeps, config,
+                                    DependOnTargetArtifact);
         }
         this->WriteBuild(*this->GetDefaultFileStream(), build);
       }
@@ -1339,11 +1346,9 @@
     cmGlobalNinjaGenerator::WriteDivider(os);
     std::string const& currentBinaryDir = it.first;
     DirectoryTarget const& dt = it.second;
-    std::vector<std::string> configs;
-    dt.LG->GetMakefile()->GetConfigurations(configs, true);
-    if (configs.empty()) {
-      configs.emplace_back();
-    }
+    std::vector<std::string> configs =
+      dt.LG->GetMakefile()->GetGeneratorConfigs(
+        cmMakefile::IncludeEmptyConfig);
 
     // Setup target
     cmNinjaDeps configDeps;
@@ -1356,8 +1361,9 @@
       build.Outputs.front() = this->BuildAlias(buildDirAllTarget, config);
       configDeps.emplace_back(build.Outputs.front());
       for (DirectoryTarget::Target const& t : dt.Targets) {
-        if (!t.ExcludeFromAll) {
-          this->AppendTargetOutputs(t.GT, build.ExplicitDeps, config);
+        if (!IsExcludedFromAllInConfig(t, config)) {
+          this->AppendTargetOutputs(t.GT, build.ExplicitDeps, config,
+                                    DependOnTargetArtifact);
         }
       }
       for (DirectoryTarget::Dir const& d : dt.Children) {
@@ -1538,7 +1544,8 @@
   this->WriteTargetClean(os);
   this->WriteTargetHelp(os);
 
-  for (auto const& config : this->Makefiles[0]->GetGeneratorConfigs()) {
+  for (auto const& config : this->Makefiles[0]->GetGeneratorConfigs(
+         cmMakefile::IncludeEmptyConfig)) {
     this->WriteTargetDefault(*this->GetConfigFileStream(config));
   }
 
@@ -1712,11 +1719,8 @@
   std::string cleanScriptRel = "CMakeFiles/clean_additional.cmake";
   std::string cleanScriptAbs =
     cmStrCat(lgr->GetBinaryDirectory(), '/', cleanScriptRel);
-  std::vector<std::string> configs;
-  this->Makefiles[0]->GetConfigurations(configs, true);
-  if (configs.empty()) {
-    configs.emplace_back();
-  }
+  std::vector<std::string> configs =
+    this->Makefiles[0]->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
 
   // Check if there are additional files to clean
   bool empty = true;
@@ -1810,7 +1814,8 @@
     WriteRule(*this->RulesFileStream, rule);
   }
 
-  auto const configs = this->Makefiles.front()->GetGeneratorConfigs();
+  auto const configs = this->Makefiles.front()->GetGeneratorConfigs(
+    cmMakefile::IncludeEmptyConfig);
 
   // Write build
   {
@@ -2489,7 +2494,8 @@
     << "# This file contains build statements common to all "
        "configurations.\n\n";
 
-  for (auto const& config : this->Makefiles[0]->GetGeneratorConfigs()) {
+  for (auto const& config : this->Makefiles[0]->GetGeneratorConfigs(
+         cmMakefile::IncludeEmptyConfig)) {
     // Open impl file.
     if (!this->OpenFileStream(this->ImplFileStreams[config],
                               GetNinjaImplFilename(config))) {
@@ -2529,7 +2535,8 @@
     this->DefaultFileStream.reset();
   } // No error if it wasn't open
 
-  for (auto const& config : this->Makefiles[0]->GetGeneratorConfigs()) {
+  for (auto const& config : this->Makefiles[0]->GetGeneratorConfigs(
+         cmMakefile::IncludeEmptyConfig)) {
     if (this->ImplFileStreams[config]) {
       this->ImplFileStreams[config].reset();
     } else {
@@ -2571,7 +2578,8 @@
 void cmGlobalNinjaMultiGenerator::AddRebuildManifestOutputs(
   cmNinjaDeps& outputs) const
 {
-  for (auto const& config : this->Makefiles.front()->GetGeneratorConfigs()) {
+  for (auto const& config : this->Makefiles.front()->GetGeneratorConfigs(
+         cmMakefile::IncludeEmptyConfig)) {
     outputs.push_back(this->NinjaOutputPath(GetNinjaImplFilename(config)));
     outputs.push_back(this->NinjaOutputPath(GetNinjaConfigFilename(config)));
   }
@@ -2583,11 +2591,9 @@
 void cmGlobalNinjaMultiGenerator::GetQtAutoGenConfigs(
   std::vector<std::string>& configs) const
 {
-  auto const oldSize = configs.size();
-  this->Makefiles.front()->GetConfigurations(configs);
-  if (configs.size() == oldSize) {
-    configs.emplace_back();
-  }
+  auto allConfigs =
+    this->Makefiles[0]->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
+  configs.insert(configs.end(), cm::cbegin(allConfigs), cm::cend(allConfigs));
 }
 
 bool cmGlobalNinjaMultiGenerator::InspectConfigTypeVariables()
diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h
index 44e632f..10f5cf6 100644
--- a/Source/cmGlobalNinjaGenerator.h
+++ b/Source/cmGlobalNinjaGenerator.h
@@ -318,14 +318,13 @@
   virtual std::string OrderDependsTargetForTarget(
     cmGeneratorTarget const* target, const std::string& config) const;
 
-  void AppendTargetOutputs(
-    cmGeneratorTarget const* target, cmNinjaDeps& outputs,
-    const std::string& config,
-    cmNinjaTargetDepends depends = DependOnTargetArtifact);
-  void AppendTargetDepends(
-    cmGeneratorTarget const* target, cmNinjaDeps& outputs,
-    const std::string& config, const std::string& fileConfig,
-    cmNinjaTargetDepends depends = DependOnTargetArtifact);
+  void AppendTargetOutputs(cmGeneratorTarget const* target,
+                           cmNinjaDeps& outputs, const std::string& config,
+                           cmNinjaTargetDepends depends);
+  void AppendTargetDepends(cmGeneratorTarget const* target,
+                           cmNinjaDeps& outputs, const std::string& config,
+                           const std::string& fileConfig,
+                           cmNinjaTargetDepends depends);
   void AppendTargetDependsClosure(cmGeneratorTarget const* target,
                                   cmNinjaDeps& outputs,
                                   const std::string& config);
diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx
index c31983b..37a77fa 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.cxx
+++ b/Source/cmGlobalUnixMakefileGenerator3.cxx
@@ -143,7 +143,7 @@
     total += pmi.second.NumberOfActions;
   }
 
-  // write each target's progress.make this loop is done twice. Bascially the
+  // write each target's progress.make this loop is done twice. Basically the
   // Generate pass counts all the actions, the first loop below determines
   // how many actions have progress updates for each target and writes to
   // corrrect variable values for everything except the all targets. The
@@ -387,12 +387,8 @@
       cm::static_reference_cast<cmLocalUnixMakefileGenerator3>(lGenerator);
     // for all of out targets
     for (const auto& tgt : lg.GetGeneratorTargets()) {
-      if ((tgt->GetType() == cmStateEnums::EXECUTABLE) ||
-          (tgt->GetType() == cmStateEnums::STATIC_LIBRARY) ||
-          (tgt->GetType() == cmStateEnums::SHARED_LIBRARY) ||
-          (tgt->GetType() == cmStateEnums::MODULE_LIBRARY) ||
-          (tgt->GetType() == cmStateEnums::OBJECT_LIBRARY) ||
-          (tgt->GetType() == cmStateEnums::UTILITY)) {
+      if (tgt->IsInBuildSystem() &&
+          tgt->GetType() != cmStateEnums::GLOBAL_TARGET) {
         std::string tname = cmStrCat(lg.GetRelativeTargetDirectory(tgt.get()),
                                      "/DependInfo.cmake");
         cmSystemTools::ConvertToUnixSlashes(tname);
@@ -416,7 +412,7 @@
   std::vector<std::string> depends;
   for (DirectoryTarget::Target const& t : dt.Targets) {
     // Add this to the list of depends rules in this directory.
-    if ((!check_all || !t.ExcludeFromAll) &&
+    if ((!check_all || t.ExcludedFromAllInConfigs.empty()) &&
         (!check_relink ||
          t.GT->NeedRelinkBeforeInstall(lg->GetConfigName()))) {
       // The target may be from a different directory; use its local gen.
@@ -635,17 +631,12 @@
     for (const auto& gtarget : lg.GetGeneratorTargets()) {
       // Don't emit the same rule twice (e.g. two targets with the same
       // simple name)
-      int type = gtarget->GetType();
       std::string name = gtarget->GetName();
       if (!name.empty() && emitted.insert(name).second &&
           // Handle user targets here.  Global targets are handled in
           // the local generator on a per-directory basis.
-          ((type == cmStateEnums::EXECUTABLE) ||
-           (type == cmStateEnums::STATIC_LIBRARY) ||
-           (type == cmStateEnums::SHARED_LIBRARY) ||
-           (type == cmStateEnums::MODULE_LIBRARY) ||
-           (type == cmStateEnums::OBJECT_LIBRARY) ||
-           (type == cmStateEnums::UTILITY))) {
+          (gtarget->IsInBuildSystem() &&
+           gtarget->GetType() != cmStateEnums::GLOBAL_TARGET)) {
         // Add a rule to build the target by name.
         lg.WriteDivider(ruleFileStream);
         ruleFileStream << "# Target rules for targets named " << name
@@ -709,15 +700,10 @@
 
   // for each target Generate the rule files for each target.
   for (const auto& gtarget : lg.GetGeneratorTargets()) {
-    int type = gtarget->GetType();
     std::string name = gtarget->GetName();
     if (!name.empty() &&
-        ((type == cmStateEnums::EXECUTABLE) ||
-         (type == cmStateEnums::STATIC_LIBRARY) ||
-         (type == cmStateEnums::SHARED_LIBRARY) ||
-         (type == cmStateEnums::MODULE_LIBRARY) ||
-         (type == cmStateEnums::OBJECT_LIBRARY) ||
-         (type == cmStateEnums::UTILITY))) {
+        (gtarget->IsInBuildSystem() &&
+         gtarget->GetType() != cmStateEnums::GLOBAL_TARGET)) {
       std::string makefileName;
       // Add a rule to build the target by name.
       localName = lg.GetRelativeTargetDirectory(gtarget.get());
@@ -845,8 +831,7 @@
     for (const auto& gt : lg->GetGeneratorTargets()) {
       cmLocalGenerator* tlg = gt->GetLocalGenerator();
 
-      if (gt->GetType() == cmStateEnums::INTERFACE_LIBRARY ||
-          gt->GetPropertyAsBool("EXCLUDE_FROM_ALL")) {
+      if (!gt->IsInBuildSystem() || IsExcluded(lg.get(), gt.get())) {
         continue;
       }
 
@@ -881,7 +866,7 @@
   if (emitted.insert(target).second) {
     count = this->ProgressMap[target].Marks.size();
     for (cmTargetDepend const& depend : this->GetTargetDirectDepends(target)) {
-      if (depend->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+      if (!depend->IsInBuildSystem()) {
         continue;
       }
       count += this->CountProgressMarksInTarget(depend, emitted);
@@ -938,7 +923,7 @@
   for (cmTargetDepend const& i : this->GetTargetDirectDepends(target)) {
     // Create the target-level dependency.
     cmGeneratorTarget const* dep = i;
-    if (dep->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+    if (!dep->IsInBuildSystem()) {
       continue;
     }
     cmLocalUnixMakefileGenerator3* lg3 =
@@ -986,7 +971,9 @@
             (type == cmStateEnums::STATIC_LIBRARY) ||
             (type == cmStateEnums::SHARED_LIBRARY) ||
             (type == cmStateEnums::MODULE_LIBRARY) ||
-            (type == cmStateEnums::OBJECT_LIBRARY)) {
+            (type == cmStateEnums::OBJECT_LIBRARY) ||
+            (type == cmStateEnums::INTERFACE_LIBRARY &&
+             target->IsInBuildSystem())) {
           project_targets.insert(target->GetName());
         } else if (type == cmStateEnums::GLOBAL_TARGET) {
           globals_targets.insert(target->GetName());
diff --git a/Source/cmGlobalVisualStudio10Generator.cxx b/Source/cmGlobalVisualStudio10Generator.cxx
index 5dac072..3805546 100644
--- a/Source/cmGlobalVisualStudio10Generator.cxx
+++ b/Source/cmGlobalVisualStudio10Generator.cxx
@@ -138,9 +138,6 @@
     "ProductDir",
     vc10Express, cmSystemTools::KeyWOW64_32);
   this->CudaEnabled = false;
-  this->SystemIsWindowsCE = false;
-  this->SystemIsWindowsPhone = false;
-  this->SystemIsWindowsStore = false;
   this->MSBuildCommandInitialized = false;
   {
     std::string envPlatformToolset;
@@ -511,18 +508,16 @@
       mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
       return false;
     }
-    std::string v = this->GetInstalledNsightTegraVersion();
-    if (v.empty()) {
-      mf->IssueMessage(MessageType::FATAL_ERROR,
-                       "CMAKE_SYSTEM_NAME is 'Android' but "
-                       "'NVIDIA Nsight Tegra Visual Studio Edition' "
-                       "is not installed.");
-      return false;
+    if (mf->GetSafeDefinition("CMAKE_GENERATOR_PLATFORM") == "Tegra-Android") {
+      if (!this->InitializeTegraAndroid(mf)) {
+        return false;
+      }
+    } else {
+      this->SystemIsAndroid = true;
+      if (!this->InitializeAndroid(mf)) {
+        return false;
+      }
     }
-    this->DefaultPlatformName = "Tegra-Android";
-    this->DefaultPlatformToolset = "Default";
-    this->NsightTegraVersion = v;
-    mf->AddDefinition("CMAKE_VS_NsightTegra_VERSION", v);
   }
 
   return true;
@@ -564,6 +559,31 @@
   return false;
 }
 
+bool cmGlobalVisualStudio10Generator::InitializeTegraAndroid(cmMakefile* mf)
+{
+  std::string v = this->GetInstalledNsightTegraVersion();
+  if (v.empty()) {
+    mf->IssueMessage(MessageType::FATAL_ERROR,
+                     "CMAKE_SYSTEM_NAME is 'Android' but "
+                     "'NVIDIA Nsight Tegra Visual Studio Edition' "
+                     "is not installed.");
+    return false;
+  }
+  this->DefaultPlatformName = "Tegra-Android";
+  this->DefaultPlatformToolset = "Default";
+  this->NsightTegraVersion = v;
+  mf->AddDefinition("CMAKE_VS_NsightTegra_VERSION", v);
+  return true;
+}
+
+bool cmGlobalVisualStudio10Generator::InitializeAndroid(cmMakefile* mf)
+{
+  std::ostringstream e;
+  e << this->GetName() << " does not support Android.";
+  mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
+  return false;
+}
+
 bool cmGlobalVisualStudio10Generator::SelectWindowsPhoneToolset(
   std::string& toolset) const
 {
@@ -598,6 +618,28 @@
 {
   this->LongestSource = LongestSourcePath();
   this->cmGlobalVisualStudio8Generator::Generate();
+  if (!this->AndroidExecutableWarnings.empty() &&
+      !this->CMakeInstance->GetIsInTryCompile()) {
+    std::ostringstream e;
+    /* clang-format off */
+    e <<
+      "You are using Visual Studio tools for Android, which does not support "
+      "standalone executables. However, the following executable targets do "
+      "not have the ANDROID_GUI property set, and thus will not be built as "
+      "expected. They will be built as shared libraries with executable "
+      "filenames:\n"
+      "  ";
+    /* clang-format on */
+    bool first = true;
+    for (auto const& name : this->AndroidExecutableWarnings) {
+      if (!first) {
+        e << ", ";
+      }
+      first = false;
+      e << name;
+    }
+    this->CMakeInstance->IssueMessage(MessageType::WARNING, e.str());
+  }
   if (this->LongestSource.Length > 0) {
     cmLocalGenerator* lg = this->LongestSource.Target->GetLocalGenerator();
     std::ostringstream e;
@@ -664,8 +706,14 @@
   if (!this->GeneratorToolset.empty()) {
     return this->GeneratorToolset;
   }
-  if (!this->DefaultPlatformToolset.empty()) {
-    return this->DefaultPlatformToolset;
+  if (this->SystemIsAndroid) {
+    if (!this->DefaultAndroidToolset.empty()) {
+      return this->DefaultAndroidToolset;
+    }
+  } else {
+    if (!this->DefaultPlatformToolset.empty()) {
+      return this->DefaultPlatformToolset;
+    }
   }
   static std::string const empty;
   return empty;
@@ -879,7 +927,10 @@
       epg.Attribute("Label", "Globals");
       cmXMLElement(epg, "ProjectGuid")
         .Content("{F3FC6D86-508D-3FB1-96D2-995F08B142EC}");
-      cmXMLElement(epg, "Keyword").Content("Win32Proj");
+      cmXMLElement(epg, "Keyword")
+        .Content(mf->GetSafeDefinition("CMAKE_SYSTEM_NAME") == "Android"
+                   ? "Android"
+                   : "Win32Proj");
       cmXMLElement(epg, "Platform").Content(this->GetPlatformName());
       if (this->GetSystemName() == "WindowsPhone") {
         cmXMLElement(epg, "ApplicationType").Content("Windows Phone");
@@ -889,15 +940,21 @@
         cmXMLElement(epg, "ApplicationType").Content("Windows Store");
         cmXMLElement(epg, "ApplicationTypeRevision")
           .Content(this->GetApplicationTypeRevision());
+      } else if (this->GetSystemName() == "Android") {
+        cmXMLElement(epg, "ApplicationType").Content("Android");
+        cmXMLElement(epg, "ApplicationTypeRevision")
+          .Content(this->GetApplicationTypeRevision());
       }
       if (!this->WindowsTargetPlatformVersion.empty()) {
         cmXMLElement(epg, "WindowsTargetPlatformVersion")
           .Content(this->WindowsTargetPlatformVersion);
       }
-      if (this->GetPlatformName() == "ARM64") {
-        cmXMLElement(epg, "WindowsSDKDesktopARM64Support").Content("true");
-      } else if (this->GetPlatformName() == "ARM") {
-        cmXMLElement(epg, "WindowsSDKDesktopARMSupport").Content("true");
+      if (this->GetSystemName() != "Android") {
+        if (this->GetPlatformName() == "ARM64") {
+          cmXMLElement(epg, "WindowsSDKDesktopARM64Support").Content("true");
+        } else if (this->GetPlatformName() == "ARM") {
+          cmXMLElement(epg, "WindowsSDKDesktopARMSupport").Content("true");
+        }
       }
     }
     cmXMLElement(eprj, "Import")
@@ -1209,6 +1266,10 @@
 
 std::string cmGlobalVisualStudio10Generator::GetApplicationTypeRevision() const
 {
+  if (this->GetSystemName() == "Android") {
+    return this->GetAndroidApplicationTypeRevision();
+  }
+
   // Return the first two '.'-separated components of the Windows version.
   std::string::size_type end1 = this->SystemVersion.find('.');
   std::string::size_type end2 =
diff --git a/Source/cmGlobalVisualStudio10Generator.h b/Source/cmGlobalVisualStudio10Generator.h
index b8c18b4..0c53537 100644
--- a/Source/cmGlobalVisualStudio10Generator.h
+++ b/Source/cmGlobalVisualStudio10Generator.h
@@ -4,6 +4,7 @@
 #define cmGlobalVisualStudio10Generator_h
 
 #include <memory>
+#include <set>
 
 #include "cmGlobalVisualStudio8Generator.h"
 #include "cmVisualStudio10ToolsetOptions.h"
@@ -43,6 +44,11 @@
   void EnableLanguage(std::vector<std::string> const& languages, cmMakefile*,
                       bool optional) override;
 
+  void AddAndroidExecutableWarning(const std::string& name)
+  {
+    this->AndroidExecutableWarnings.insert(name);
+  }
+
   bool IsCudaEnabled() const { return this->CudaEnabled; }
 
   /** Generating for Nsight Tegra VS plugin?  */
@@ -100,6 +106,9 @@
   /** Return true if building for WindowsStore */
   bool TargetsWindowsStore() const { return this->SystemIsWindowsStore; }
 
+  /** Return true if building for Android */
+  bool TargetsAndroid() const { return this->SystemIsAndroid; }
+
   const char* GetCMakeCFGIntDir() const override { return "$(Configuration)"; }
   bool Find64BitTools(cmMakefile* mf);
 
@@ -128,6 +137,8 @@
   /** Return the first two components of CMAKE_SYSTEM_VERSION.  */
   std::string GetApplicationTypeRevision() const;
 
+  virtual const char* GetAndroidApplicationTypeRevision() const { return ""; }
+
   cmIDEFlagTable const* GetClFlagTable() const;
   cmIDEFlagTable const* GetCSharpFlagTable() const;
   cmIDEFlagTable const* GetRcFlagTable() const;
@@ -148,6 +159,8 @@
   virtual bool InitializeWindowsCE(cmMakefile* mf);
   virtual bool InitializeWindowsPhone(cmMakefile* mf);
   virtual bool InitializeWindowsStore(cmMakefile* mf);
+  virtual bool InitializeTegraAndroid(cmMakefile* mf);
+  virtual bool InitializeAndroid(cmMakefile* mf);
 
   virtual bool ProcessGeneratorToolsetField(std::string const& key,
                                             std::string const& value);
@@ -171,6 +184,7 @@
   std::string GeneratorToolsetCudaCustomDir;
   std::string DefaultPlatformToolset;
   std::string DefaultPlatformToolsetHostArchitecture;
+  std::string DefaultAndroidToolset;
   std::string WindowsTargetPlatformVersion;
   std::string SystemName;
   std::string SystemVersion;
@@ -185,9 +199,10 @@
   std::string DefaultNasmFlagTableName;
   std::string DefaultRCFlagTableName;
   bool SupportsUnityBuilds = false;
-  bool SystemIsWindowsCE;
-  bool SystemIsWindowsPhone;
-  bool SystemIsWindowsStore;
+  bool SystemIsWindowsCE = false;
+  bool SystemIsWindowsPhone = false;
+  bool SystemIsWindowsStore = false;
+  bool SystemIsAndroid = false;
 
 private:
   class Factory;
@@ -211,6 +226,7 @@
   std::string MSBuildCommand;
   bool MSBuildCommandInitialized;
   cmVisualStudio10ToolsetOptions ToolsetOptions;
+  std::set<std::string> AndroidExecutableWarnings;
   virtual std::string FindMSBuildCommand();
   std::string FindDevEnvCommand() override;
   std::string GetVSMakeProgram() override { return this->GetMSBuildCommand(); }
diff --git a/Source/cmGlobalVisualStudio14Generator.cxx b/Source/cmGlobalVisualStudio14Generator.cxx
index f549b6a..451d448 100644
--- a/Source/cmGlobalVisualStudio14Generator.cxx
+++ b/Source/cmGlobalVisualStudio14Generator.cxx
@@ -109,6 +109,7 @@
     "ProductDir",
     vc14Express, cmSystemTools::KeyWOW64_32);
   this->DefaultPlatformToolset = "v140";
+  this->DefaultAndroidToolset = "Clang_3_8";
   this->DefaultCLFlagTableName = "v140";
   this->DefaultCSharpFlagTableName = "v140";
   this->DefaultLibFlagTableName = "v14";
@@ -159,6 +160,11 @@
   return true;
 }
 
+bool cmGlobalVisualStudio14Generator::InitializeAndroid(cmMakefile*)
+{
+  return true;
+}
+
 bool cmGlobalVisualStudio14Generator::SelectWindows10SDK(cmMakefile* mf,
                                                          bool required)
 {
diff --git a/Source/cmGlobalVisualStudio14Generator.h b/Source/cmGlobalVisualStudio14Generator.h
index ccc2917..39353f2 100644
--- a/Source/cmGlobalVisualStudio14Generator.h
+++ b/Source/cmGlobalVisualStudio14Generator.h
@@ -23,12 +23,18 @@
 
   bool MatchesGeneratorName(const std::string& name) const override;
 
+  const char* GetAndroidApplicationTypeRevision() const override
+  {
+    return "2.0";
+  }
+
 protected:
   cmGlobalVisualStudio14Generator(cmake* cm, const std::string& name,
                                   std::string const& platformInGeneratorName);
 
   bool InitializeWindows(cmMakefile* mf) override;
   bool InitializeWindowsStore(cmMakefile* mf) override;
+  bool InitializeAndroid(cmMakefile* mf) override;
   bool SelectWindowsStoreToolset(std::string& toolset) const override;
 
   // These aren't virtual because we need to check if the selected version
diff --git a/Source/cmGlobalVisualStudio71Generator.cxx b/Source/cmGlobalVisualStudio71Generator.cxx
index 7ada325..0083c40 100644
--- a/Source/cmGlobalVisualStudio71Generator.cxx
+++ b/Source/cmGlobalVisualStudio71Generator.cxx
@@ -19,8 +19,8 @@
   std::ostream& fout, cmLocalGenerator* root,
   std::vector<cmLocalGenerator*>& generators)
 {
-  std::vector<std::string> configs;
-  root->GetMakefile()->GetConfigurations(configs);
+  std::vector<std::string> configs =
+    root->GetMakefile()->GetGeneratorConfigs(cmMakefile::ExcludeEmptyConfig);
 
   // Write out the header for a SLN file
   this->WriteSLNHeader(fout);
diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx
index 428c748..f8b438a 100644
--- a/Source/cmGlobalVisualStudio7Generator.cxx
+++ b/Source/cmGlobalVisualStudio7Generator.cxx
@@ -339,7 +339,7 @@
   // loop over again and write out configurations for each target
   // in the solution
   for (cmGeneratorTarget const* target : projectTargets) {
-    if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+    if (!target->IsInBuildSystem()) {
       continue;
     }
     cmProp expath = target->GetProperty("EXTERNAL_MSPROJECT");
@@ -369,7 +369,7 @@
 
   std::string rootBinaryDir = root->GetCurrentBinaryDirectory();
   for (cmGeneratorTarget const* target : projectTargets) {
-    if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+    if (!target->IsInBuildSystem()) {
       continue;
     }
     bool written = false;
@@ -436,7 +436,7 @@
   std::ostream& fout, OrderedTargetDependSet const& projectTargets)
 {
   for (cmGeneratorTarget const* target : projectTargets) {
-    if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+    if (!target->IsInBuildSystem()) {
       continue;
     }
     cmProp vcprojName = target->GetProperty("GENERATOR_FILE_NAME");
@@ -568,8 +568,9 @@
 std::string cmGlobalVisualStudio7Generator::WriteUtilityDepend(
   cmGeneratorTarget const* target)
 {
-  std::vector<std::string> configs;
-  target->Target->GetMakefile()->GetConfigurations(configs);
+  std::vector<std::string> configs =
+    target->Target->GetMakefile()->GetGeneratorConfigs(
+      cmMakefile::ExcludeEmptyConfig);
   std::string pname = cmStrCat(target->GetName(), "_UTILITY");
   std::string fname =
     cmStrCat(target->GetLocalGenerator()->GetCurrentBinaryDirectory(), '/',
@@ -693,9 +694,7 @@
   }
   // inspect EXCLUDE_FROM_DEFAULT_BUILD[_<CONFIG>] properties
   for (std::string const& i : configs) {
-    const char* propertyValue =
-      target->GetFeature("EXCLUDE_FROM_DEFAULT_BUILD", i);
-    if (cmIsOff(propertyValue)) {
+    if (cmIsOff(target->GetFeature("EXCLUDE_FROM_DEFAULT_BUILD", i))) {
       activeConfigs.insert(i);
     }
   }
diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx
index 29ca154..fcdfc50 100644
--- a/Source/cmGlobalVisualStudio8Generator.cxx
+++ b/Source/cmGlobalVisualStudio8Generator.cxx
@@ -325,7 +325,7 @@
   TargetDependSet const& unordered = this->GetTargetDirectDepends(gt);
   OrderedTargetDependSet depends(unordered, std::string());
   for (cmTargetDepend const& i : depends) {
-    if (i->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+    if (!i->IsInBuildSystem()) {
       continue;
     }
     std::string guid = this->GetGUID(i->GetName());
@@ -341,7 +341,7 @@
     if (cmGeneratorTarget* depTarget =
           target->GetLocalGenerator()->FindGeneratorTargetToUse(
             ui.Value.first)) {
-      if (depTarget->GetType() != cmStateEnums::INTERFACE_LIBRARY &&
+      if (depTarget->IsInBuildSystem() &&
           depTarget->GetProperty("EXTERNAL_MSPROJECT")) {
         // This utility dependency names an external .vcproj target.
         // We use LinkLibraryDependencies="true" to link to it without
diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx
index c688da2..001d876 100644
--- a/Source/cmGlobalVisualStudioGenerator.cxx
+++ b/Source/cmGlobalVisualStudioGenerator.cxx
@@ -368,7 +368,7 @@
 void cmGlobalVisualStudioGenerator::FollowLinkDepends(
   const cmGeneratorTarget* target, std::set<const cmGeneratorTarget*>& linked)
 {
-  if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+  if (!target->IsInBuildSystem()) {
     return;
   }
   if (linked.insert(target).second &&
@@ -509,7 +509,7 @@
   cmLocalGenerator const* root) const
 {
   cmProp n = root->GetMakefile()->GetProperty("VS_STARTUP_PROJECT");
-  if (n && !n->empty()) {
+  if (cmNonempty(n)) {
     std::string startup = *n;
     if (this->FindTarget(startup)) {
       return startup;
@@ -810,7 +810,7 @@
   // a target with none of its own sources, e.g. when also using
   // object libraries.
   cmProp linkLang = gt->GetProperty("LINKER_LANGUAGE");
-  if (linkLang && !linkLang->empty()) {
+  if (cmNonempty(linkLang)) {
     languages.insert(*linkLang);
   }
 
diff --git a/Source/cmGlobalVisualStudioVersionedGenerator.cxx b/Source/cmGlobalVisualStudioVersionedGenerator.cxx
index 605dc8b..e2e045c 100644
--- a/Source/cmGlobalVisualStudioVersionedGenerator.cxx
+++ b/Source/cmGlobalVisualStudioVersionedGenerator.cxx
@@ -100,6 +100,24 @@
   return "";
 }
 
+static const char* VSVersionToAndroidToolset(
+  cmGlobalVisualStudioGenerator::VSVersion v)
+{
+  switch (v) {
+    case cmGlobalVisualStudioGenerator::VS9:
+    case cmGlobalVisualStudioGenerator::VS10:
+    case cmGlobalVisualStudioGenerator::VS11:
+    case cmGlobalVisualStudioGenerator::VS12:
+      return "";
+    case cmGlobalVisualStudioGenerator::VS14:
+      return "Clang_3_8";
+    case cmGlobalVisualStudioGenerator::VS15:
+    case cmGlobalVisualStudioGenerator::VS16:
+      return "Clang_5_0";
+  }
+  return "";
+}
+
 static const char vs15generatorName[] = "Visual Studio 15 2017";
 
 // Map generator name without year to name with year.
@@ -284,6 +302,7 @@
   this->Version = version;
   this->ExpressEdition = false;
   this->DefaultPlatformToolset = VSVersionToToolset(this->Version);
+  this->DefaultAndroidToolset = VSVersionToAndroidToolset(this->Version);
   this->DefaultCLFlagTableName = VSVersionToToolset(this->Version);
   this->DefaultCSharpFlagTableName = VSVersionToToolset(this->Version);
   this->DefaultLinkFlagTableName = VSVersionToToolset(this->Version);
@@ -408,6 +427,25 @@
           vsInstanceVersion > vsInstanceVersion16_7_P2);
 }
 
+const char*
+cmGlobalVisualStudioVersionedGenerator::GetAndroidApplicationTypeRevision()
+  const
+{
+  switch (this->Version) {
+    case cmGlobalVisualStudioGenerator::VS9:
+    case cmGlobalVisualStudioGenerator::VS10:
+    case cmGlobalVisualStudioGenerator::VS11:
+    case cmGlobalVisualStudioGenerator::VS12:
+      return "";
+    case cmGlobalVisualStudioGenerator::VS14:
+      return "2.0";
+    case cmGlobalVisualStudioGenerator::VS15:
+    case cmGlobalVisualStudioGenerator::VS16:
+      return "3.0";
+  }
+  return "";
+}
+
 std::string cmGlobalVisualStudioVersionedGenerator::GetAuxiliaryToolset() const
 {
   const char* version = this->GetPlatformToolsetVersion();
diff --git a/Source/cmGlobalVisualStudioVersionedGenerator.h b/Source/cmGlobalVisualStudioVersionedGenerator.h
index cbd3ba7..d5b8337 100644
--- a/Source/cmGlobalVisualStudioVersionedGenerator.h
+++ b/Source/cmGlobalVisualStudioVersionedGenerator.h
@@ -36,6 +36,8 @@
 
   bool IsStdOutEncodingSupported() const override;
 
+  const char* GetAndroidApplicationTypeRevision() const override;
+
 protected:
   cmGlobalVisualStudioVersionedGenerator(
     VSVersion version, cmake* cm, const std::string& name,
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index b28395a..793f6f7 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -173,6 +173,7 @@
 
   this->RootObject = nullptr;
   this->MainGroupChildren = nullptr;
+  this->FrameworkGroup = nullptr;
   this->CurrentMakefile = nullptr;
   this->CurrentLocalGenerator = nullptr;
   this->XcodeBuildCommandInitialized = false;
@@ -476,6 +477,9 @@
       }
     }
 
+    // cache the enabled languages for source file type queries
+    this->GetEnabledLanguages(this->EnabledLangs);
+
     this->SetGenerationRoot(root);
     // now create the project
     this->OutputXCodeProject(root, keyVal.second);
@@ -673,6 +677,7 @@
   this->GroupNameMap.clear();
   this->TargetGroup.clear();
   this->FileRefs.clear();
+  this->ExternalLibRefs.clear();
 }
 
 void cmGlobalXCodeGenerator::addObject(std::unique_ptr<cmXCodeObject> obj)
@@ -741,7 +746,7 @@
   return key;
 }
 
-cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeSourceFileFromPath(
+cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeBuildFileFromPath(
   const std::string& fullpath, cmGeneratorTarget* target,
   const std::string& lang, cmSourceFile* sf)
 {
@@ -827,6 +832,14 @@
     default:
       break;
   }
+
+  // explicitly add the explicit language flag before any other flag
+  // this way backwards compatibility with user flags is maintained
+  if (sf->GetProperty("LANGUAGE")) {
+    this->CurrentLocalGenerator->AppendFeatureOptions(flags, lang,
+                                                      "EXPLICIT_LANGUAGE");
+  }
+
   const std::string COMPILE_FLAGS("COMPILE_FLAGS");
   if (cmProp cflags = sf->GetProperty(COMPILE_FLAGS)) {
     lg->AppendFlags(flags, genexInterpreter.Evaluate(*cflags, COMPILE_FLAGS));
@@ -869,7 +882,7 @@
   lg->AppendFlags(flags, lg->GetIncludeFlags(includes, gtgt, lang, true));
 
   cmXCodeObject* buildFile =
-    this->CreateXCodeSourceFileFromPath(sf->ResolveFullPath(), gtgt, lang, sf);
+    this->CreateXCodeBuildFileFromPath(sf->ResolveFullPath(), gtgt, lang, sf);
 
   cmXCodeObject* settings = this->CreateObject(cmXCodeObject::ATTRIBUTE_GROUP);
   settings->AddAttributeIfNotEmpty("COMPILER_FLAGS",
@@ -922,14 +935,40 @@
   }
 }
 
-std::string GetSourcecodeValueFromFileExtension(const std::string& _ext,
-                                                const std::string& lang,
-                                                bool& keepLastKnownFileType)
+bool IsLibraryExtension(const std::string& fileExt)
+{
+  return (fileExt == ".framework" || fileExt == ".a" || fileExt == ".o" ||
+          fileExt == ".dylib" || fileExt == ".tbd");
+}
+bool IsLibraryType(const std::string& fileType)
+{
+  return (fileType == "wrapper.framework" || fileType == "archive.ar" ||
+          fileType == "compiled.mach-o.objfile" ||
+          fileType == "compiled.mach-o.dylib" ||
+          fileType == "sourcecode.text-based-dylib-definition");
+}
+
+std::string GetDirectoryValueFromFileExtension(const std::string& dirExt)
+{
+  std::string ext = cmSystemTools::LowerCase(dirExt);
+  if (ext == "framework") {
+    return "wrapper.framework";
+  }
+  if (ext == "xcassets") {
+    return "folder.assetcatalog";
+  }
+  return "folder";
+}
+
+std::string GetSourcecodeValueFromFileExtension(
+  const std::string& _ext, const std::string& lang,
+  bool& keepLastKnownFileType, const std::vector<std::string>& enabled_langs)
 {
   std::string ext = cmSystemTools::LowerCase(_ext);
   std::string sourcecode = "sourcecode";
 
   if (ext == "o") {
+    keepLastKnownFileType = true;
     sourcecode = "compiled.mach-o.objfile";
   } else if (ext == "xctest") {
     sourcecode = "wrapper.cfbundle";
@@ -939,9 +978,9 @@
   } else if (ext == "storyboard") {
     keepLastKnownFileType = true;
     sourcecode = "file.storyboard";
-  } else if (ext == "mm") {
+  } else if (ext == "mm" && !cm::contains(enabled_langs, "OBJCXX")) {
     sourcecode += ".cpp.objcpp";
-  } else if (ext == "m") {
+  } else if (ext == "m" && !cm::contains(enabled_langs, "OBJC")) {
     sourcecode += ".c.objc";
   } else if (ext == "swift") {
     sourcecode += ".swift";
@@ -973,6 +1012,14 @@
     sourcecode += ".metal";
   } else if (ext == "mig") {
     sourcecode += ".mig";
+  } else if (ext == "tbd") {
+    sourcecode += ".text-based-dylib-definition";
+  } else if (ext == "a") {
+    keepLastKnownFileType = true;
+    sourcecode = "archive.ar";
+  } else if (ext == "dylib") {
+    keepLastKnownFileType = true;
+    sourcecode = "compiled.mach-o.dylib";
   }
   // else
   //  {
@@ -989,20 +1036,6 @@
   const std::string& fullpath, cmGeneratorTarget* target,
   const std::string& lang, cmSourceFile* sf)
 {
-  std::string key = GetGroupMapKeyFromPath(target, fullpath);
-  cmXCodeObject* fileRef = this->FileRefs[key];
-  if (!fileRef) {
-    fileRef = this->CreateObject(cmXCodeObject::PBXFileReference);
-    fileRef->SetComment(fullpath);
-    this->FileRefs[key] = fileRef;
-  }
-  cmXCodeObject* group = this->GroupMap[key];
-  cmXCodeObject* children = group->GetObject("children");
-  if (!children->HasObject(fileRef)) {
-    children->AddObject(fileRef);
-  }
-  fileRef->AddAttribute("fileEncoding", this->CreateString("4"));
-
   bool useLastKnownFileType = false;
   std::string fileType;
   if (sf) {
@@ -1013,38 +1046,70 @@
       fileType = *l;
     }
   }
+  // Make a copy so that we can override it later
+  std::string path = fullpath;
+  // Compute the extension without leading '.'.
+  std::string ext = cmSystemTools::GetFilenameLastExtension(path);
+  if (!ext.empty()) {
+    ext = ext.substr(1);
+  }
   if (fileType.empty()) {
-    // Compute the extension without leading '.'.
-    std::string ext = cmSystemTools::GetFilenameLastExtension(fullpath);
-    if (!ext.empty()) {
-      ext = ext.substr(1);
+    // If file has no extension it's either a raw executable or might
+    // be a direct reference to binary within a framework (bad practice!)
+    // so this is where we change the path to the point to framework
+    // directory.
+    if (ext.empty()) {
+      auto parentDir = cmSystemTools::GetParentDirectory(path);
+      auto parentExt = cmSystemTools::GetFilenameLastExtension(parentDir);
+      if (parentExt == ".framework") {
+        path = parentDir;
+        ext = parentExt.substr(1);
+      }
     }
-
     // If fullpath references a directory, then we need to specify
     // lastKnownFileType as folder in order for Xcode to be able to
     // open the contents of the folder.
     // (Xcode 4.6 does not like explicitFileType=folder).
-    if (cmSystemTools::FileIsDirectory(fullpath)) {
-      fileType = (ext == "xcassets" ? "folder.assetcatalog" : "folder");
+    if (cmSystemTools::FileIsDirectory(path)) {
+      fileType = GetDirectoryValueFromFileExtension(ext);
       useLastKnownFileType = true;
     } else {
-      fileType =
-        GetSourcecodeValueFromFileExtension(ext, lang, useLastKnownFileType);
+      fileType = GetSourcecodeValueFromFileExtension(
+        ext, lang, useLastKnownFileType, this->EnabledLangs);
     }
   }
 
+  std::string key = GetGroupMapKeyFromPath(target, path);
+  cmXCodeObject* fileRef = this->FileRefs[key];
+  if (!fileRef) {
+    fileRef = this->CreateObject(cmXCodeObject::PBXFileReference);
+    fileRef->SetComment(path);
+    this->FileRefs[key] = fileRef;
+  }
+  fileRef->AddAttribute("fileEncoding", this->CreateString("4"));
   fileRef->AddAttribute(useLastKnownFileType ? "lastKnownFileType"
                                              : "explicitFileType",
                         this->CreateString(fileType));
-
   // Store the file path relative to the top of the source tree.
-  std::string path = this->RelativeToSource(fullpath);
+  if (!IsLibraryType(fileType)) {
+    path = this->RelativeToSource(path);
+  }
   std::string name = cmSystemTools::GetFilenameName(path);
   const char* sourceTree =
     cmSystemTools::FileIsFullPath(path) ? "<absolute>" : "SOURCE_ROOT";
   fileRef->AddAttribute("name", this->CreateString(name));
   fileRef->AddAttribute("path", this->CreateString(path));
   fileRef->AddAttribute("sourceTree", this->CreateString(sourceTree));
+
+  cmXCodeObject* group = this->GroupMap[key];
+  if (!group && IsLibraryType(fileType)) {
+    group = this->FrameworkGroup;
+    this->GroupMap[key] = group;
+  }
+  cmXCodeObject* children = group->GetObject("children");
+  if (!children->HasObject(fileRef)) {
+    children->AddObject(fileRef);
+  }
   return fileRef;
 }
 
@@ -1077,11 +1142,8 @@
   this->CurrentMakefile = gen->GetMakefile();
 
   // Select the current set of configuration types.
-  this->CurrentConfigurationTypes.clear();
-  this->CurrentMakefile->GetConfigurations(this->CurrentConfigurationTypes);
-  if (this->CurrentConfigurationTypes.empty()) {
-    this->CurrentConfigurationTypes.emplace_back();
-  }
+  this->CurrentConfigurationTypes =
+    this->CurrentMakefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
 }
 
 struct cmSourceFilePathCompare
@@ -1137,11 +1199,12 @@
     return true;
   }
 
-  if (gtgt->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+  if (!gtgt->IsInBuildSystem()) {
     return true;
   }
 
   if (gtgt->GetType() == cmStateEnums::UTILITY ||
+      gtgt->GetType() == cmStateEnums::INTERFACE_LIBRARY ||
       gtgt->GetType() == cmStateEnums::GLOBAL_TARGET) {
     cmXCodeObject* t = this->CreateUtilityTarget(gtgt);
     if (!t) {
@@ -1152,23 +1215,24 @@
   }
 
   // organize the sources
-  std::vector<cmSourceFile*> classes;
-  if (!gtgt->GetConfigCommonSourceFiles(classes)) {
+  std::vector<cmSourceFile*> commonSourceFiles;
+  if (!gtgt->GetConfigCommonSourceFiles(commonSourceFiles)) {
     return false;
   }
 
   // Add CMakeLists.txt file for user convenience.
-  this->AddXCodeProjBuildRule(gtgt, classes);
+  this->AddXCodeProjBuildRule(gtgt, commonSourceFiles);
 
   // Add the Info.plist we are about to generate for an App Bundle.
   if (gtgt->GetPropertyAsBool("MACOSX_BUNDLE")) {
     std::string plist = this->ComputeInfoPListLocation(gtgt);
     cmSourceFile* sf = gtgt->Makefile->GetOrCreateSource(
       plist, true, cmSourceFileLocationKind::Known);
-    classes.push_back(sf);
+    commonSourceFiles.push_back(sf);
   }
 
-  std::sort(classes.begin(), classes.end(), cmSourceFilePathCompare());
+  std::sort(commonSourceFiles.begin(), commonSourceFiles.end(),
+            cmSourceFilePathCompare());
 
   gtgt->ComputeObjectMapping();
 
@@ -1176,16 +1240,19 @@
   std::vector<cmXCodeObject*> headerFiles;
   std::vector<cmXCodeObject*> resourceFiles;
   std::vector<cmXCodeObject*> sourceFiles;
-  for (auto sourceFile : classes) {
+  for (auto sourceFile : commonSourceFiles) {
     cmXCodeObject* xsf = this->CreateXCodeSourceFile(
       this->CurrentLocalGenerator, sourceFile, gtgt);
     cmXCodeObject* fr = xsf->GetObject("fileRef");
     cmXCodeObject* filetype = fr->GetObject()->GetObject("explicitFileType");
+    if (!filetype) {
+      filetype = fr->GetObject()->GetObject("lastKnownFileType");
+    }
 
     cmGeneratorTarget::SourceFileFlags tsFlags =
       gtgt->GetTargetSourceFileFlags(sourceFile);
 
-    if (filetype && filetype->GetString() == "compiled.mach-o.objfile") {
+    if (filetype && IsLibraryType(filetype->GetString())) {
       if (sourceFile->GetObjectLibrary().empty()) {
         externalObjFiles.push_back(xsf);
       }
@@ -1275,7 +1342,7 @@
     using mapOfVectorOfSourceFiles =
       std::map<std::string, std::vector<cmSourceFile*>>;
     mapOfVectorOfSourceFiles bundleFiles;
-    for (auto sourceFile : classes) {
+    for (auto sourceFile : commonSourceFiles) {
       cmGeneratorTarget::SourceFileFlags tsFlags =
         gtgt->GetTargetSourceFileFlags(sourceFile);
       if (tsFlags.Type == cmGeneratorTarget::SourceFileTypeMacContent) {
@@ -1323,7 +1390,7 @@
     using mapOfVectorOfSourceFiles =
       std::map<std::string, std::vector<cmSourceFile*>>;
     mapOfVectorOfSourceFiles bundleFiles;
-    for (auto sourceFile : classes) {
+    for (auto sourceFile : commonSourceFiles) {
       cmGeneratorTarget::SourceFileFlags tsFlags =
         gtgt->GetTargetSourceFileFlags(sourceFile);
       if (tsFlags.Type == cmGeneratorTarget::SourceFileTypeDeepResource) {
@@ -1353,22 +1420,20 @@
     }
   }
 
-  // create framework build phase
+  // always create framework build phase
   cmXCodeObject* frameworkBuildPhase = nullptr;
-  if (!externalObjFiles.empty()) {
-    frameworkBuildPhase =
-      this->CreateObject(cmXCodeObject::PBXFrameworksBuildPhase);
-    frameworkBuildPhase->SetComment("Frameworks");
-    frameworkBuildPhase->AddAttribute("buildActionMask",
-                                      this->CreateString("2147483647"));
-    buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST);
-    frameworkBuildPhase->AddAttribute("files", buildFiles);
-    for (auto& externalObjFile : externalObjFiles) {
-      buildFiles->AddObject(externalObjFile);
-    }
-    frameworkBuildPhase->AddAttribute("runOnlyForDeploymentPostprocessing",
-                                      this->CreateString("0"));
+  frameworkBuildPhase =
+    this->CreateObject(cmXCodeObject::PBXFrameworksBuildPhase);
+  frameworkBuildPhase->SetComment("Frameworks");
+  frameworkBuildPhase->AddAttribute("buildActionMask",
+                                    this->CreateString("2147483647"));
+  buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST);
+  frameworkBuildPhase->AddAttribute("files", buildFiles);
+  for (auto& externalObjFile : externalObjFiles) {
+    buildFiles->AddObject(externalObjFile);
   }
+  frameworkBuildPhase->AddAttribute("runOnlyForDeploymentPostprocessing",
+                                    this->CreateString("0"));
 
   // create list of build phases and create the Xcode target
   cmXCodeObject* buildPhases = this->CreateObject(cmXCodeObject::OBJECT_LIST);
@@ -1781,7 +1846,7 @@
                                                  cmXCodeObject* buildSettings,
                                                  const std::string& configName)
 {
-  if (gtgt->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+  if (!gtgt->IsInBuildSystem()) {
     return;
   }
 
@@ -2472,7 +2537,7 @@
   this->XCodeObjectMap[gtgt] = target;
 
   // Add source files without build rules for editing convenience.
-  if (gtgt->GetType() == cmStateEnums::UTILITY &&
+  if (gtgt->GetType() != cmStateEnums::GLOBAL_TARGET &&
       gtgt->GetName() != CMAKE_CHECK_BUILD_SYSTEM_TARGET) {
     std::vector<cmSourceFile*> sources;
     if (!gtgt->GetConfigCommonSourceFiles(sources)) {
@@ -2614,7 +2679,7 @@
 cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeTarget(
   cmGeneratorTarget* gtgt, cmXCodeObject* buildPhases)
 {
-  if (gtgt->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+  if (!gtgt->IsInBuildSystem()) {
     return nullptr;
   }
   cmXCodeObject* target = this->CreateObject(cmXCodeObject::PBXNativeTarget);
@@ -2757,7 +2822,7 @@
     cmSystemTools::Error("Error no target on xobject\n");
     return;
   }
-  if (gt->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+  if (!gt->IsInBuildSystem()) {
     return;
   }
 
@@ -2768,6 +2833,190 @@
     }
   }
 
+  // Separate libraries into ones that can be linked using "Link Binary With
+  // Libraries" build phase and the ones that can't. Only targets that build
+  // Apple bundles (.app, .framework, .bundle) can use this feature and only
+  // targets that represent actual libraries (static or dynamic, local or
+  // imported) not objects and not executables will be used. These are
+  // limitations imposed by CMake use-cases - otherwise a lot of things break.
+  // The rest will be linked using linker flags (OTHER_LDFLAGS setting in Xcode
+  // project).
+  std::map<std::string, std::vector<cmComputeLinkInformation::Item const*>>
+    configItemMap;
+  auto addToLinkerArguments =
+    [&configItemMap](const std::string& configName,
+                     cmComputeLinkInformation::Item const* libItemPtr) {
+      auto& linkVector = configItemMap[configName];
+      if (std::find_if(linkVector.begin(), linkVector.end(),
+                       [libItemPtr](cmComputeLinkInformation::Item const* p) {
+                         return p == libItemPtr;
+                       }) == linkVector.end()) {
+        linkVector.push_back(libItemPtr);
+      }
+    };
+  std::vector<cmComputeLinkInformation::Item const*> linkPhaseTargetVector;
+  std::map<std::string, std::vector<std::string>> targetConfigMap;
+  using ConfigItemPair =
+    std::pair<std::string, cmComputeLinkInformation::Item const*>;
+  std::map<std::string, std::vector<ConfigItemPair>> targetItemMap;
+  std::map<std::string, std::vector<std::string>> targetProductNameMap;
+  for (auto const& configName : this->CurrentConfigurationTypes) {
+    cmComputeLinkInformation* cli = gt->GetLinkInformation(configName);
+    if (!cli) {
+      continue;
+    }
+    for (auto const& libItem : cli->GetItems()) {
+      if (gt->IsBundleOnApple() &&
+          (gt->GetType() == cmStateEnums::EXECUTABLE ||
+           gt->GetType() == cmStateEnums::SHARED_LIBRARY ||
+           gt->GetType() == cmStateEnums::MODULE_LIBRARY ||
+           gt->GetType() == cmStateEnums::UNKNOWN_LIBRARY) &&
+          ((libItem.Target &&
+            (libItem.Target->GetType() == cmStateEnums::STATIC_LIBRARY ||
+             libItem.Target->GetType() == cmStateEnums::SHARED_LIBRARY ||
+             libItem.Target->GetType() == cmStateEnums::MODULE_LIBRARY)) ||
+           (!libItem.Target && libItem.IsPath))) {
+        // Add unique configuration name to target-config map for later
+        // checks
+        std::string libName;
+        if (libItem.Target) {
+          libName = libItem.Target->GetName();
+        } else {
+          libName = cmSystemTools::GetFilenameName(libItem.Value.Value);
+          const auto libExt = cmSystemTools::GetFilenameExtension(libName);
+          if (!IsLibraryExtension(libExt)) {
+            // Add this library item to a regular linker flag list
+            addToLinkerArguments(configName, &libItem);
+            continue;
+          }
+        }
+        auto& configVector = targetConfigMap[libName];
+        if (std::find(configVector.begin(), configVector.end(), configName) ==
+            configVector.end()) {
+          configVector.push_back(configName);
+        }
+        // Add a pair of config and item to target-item map
+        auto& itemVector = targetItemMap[libName];
+        itemVector.emplace_back(ConfigItemPair(configName, &libItem));
+        // Add product file-name to a lib-product map
+        auto productName = cmSystemTools::GetFilenameName(libItem.Value.Value);
+        auto& productVector = targetProductNameMap[libName];
+        if (std::find(productVector.begin(), productVector.end(),
+                      productName) == productVector.end()) {
+          productVector.push_back(productName);
+        }
+      } else {
+        // Add this library item to a regular linker flag list
+        addToLinkerArguments(configName, &libItem);
+      }
+    }
+  }
+
+  // Go through target library map and separate libraries that are linked
+  // in all configurations and produce only single product, from the rest.
+  // Only these will be linked through "Link Binary With Libraries" build
+  // phase.
+  for (auto const& targetLibConfigs : targetConfigMap) {
+    // Add this library to "Link Binary With Libraries" build phase if it's
+    // linked in all configurations and it has only one product name
+    auto& itemVector = targetItemMap[targetLibConfigs.first];
+    auto& productVector = targetProductNameMap[targetLibConfigs.first];
+    if (targetLibConfigs.second == this->CurrentConfigurationTypes &&
+        productVector.size() == 1) {
+      // Add this library to "Link Binary With Libraries" list
+      linkPhaseTargetVector.push_back(itemVector[0].second);
+    } else {
+      for (auto const& libItem : targetItemMap[targetLibConfigs.first]) {
+        // Add this library item to a regular linker flag list
+        addToLinkerArguments(libItem.first, libItem.second);
+      }
+    }
+  }
+
+  // Add libraries to "Link Binary With Libraries" build phase and collect
+  // their search paths. Xcode does not support per-configuration linking
+  // in this build phase so we don't have to do this for each configuration
+  // separately.
+  std::vector<std::string> linkSearchPaths;
+  for (auto const& libItem : linkPhaseTargetVector) {
+    // Add target output directory as a library search path
+    std::string linkDir;
+    if (libItem->Target) {
+      linkDir = cmSystemTools::GetParentDirectory(
+        libItem->Target->GetLocationForBuild());
+    } else {
+      linkDir = cmSystemTools::GetParentDirectory(libItem->Value.Value);
+    }
+    if (std::find(linkSearchPaths.begin(), linkSearchPaths.end(), linkDir) ==
+        linkSearchPaths.end()) {
+      linkSearchPaths.push_back(linkDir);
+    }
+    // Add target dependency
+    if (libItem->Target && !libItem->Target->IsImported()) {
+      for (auto const& configName : this->CurrentConfigurationTypes) {
+        target->AddDependTarget(configName, libItem->Target->GetName());
+      }
+    }
+    // Get the library target
+    auto* libTarget = FindXCodeTarget(libItem->Target);
+    cmXCodeObject* buildFile;
+    if (!libTarget) {
+      if (libItem->IsPath) {
+        // Get or create a direct file ref in the root project
+        auto it = this->ExternalLibRefs.find(libItem->Value.Value);
+        if (it == this->ExternalLibRefs.end()) {
+          buildFile = CreateXCodeBuildFileFromPath(libItem->Value.Value, gt,
+                                                   "", nullptr);
+          this->ExternalLibRefs.emplace(libItem->Value.Value, buildFile);
+        } else {
+          buildFile = it->second;
+        }
+      } else {
+        // Add this library item back to a regular linker flag list
+        for (const auto& conf : configItemMap) {
+          addToLinkerArguments(conf.first, libItem);
+        }
+        continue;
+      }
+    } else {
+      // Add the target output file as a build reference for other targets
+      // to link against
+      auto* fileRefObject = libTarget->GetObject("productReference");
+      if (!fileRefObject) {
+        // Add this library item back to a regular linker flag list
+        for (const auto& conf : configItemMap) {
+          addToLinkerArguments(conf.first, libItem);
+        }
+        continue;
+      }
+      auto it = FileRefToBuildFileMap.find(fileRefObject);
+      if (it == FileRefToBuildFileMap.end()) {
+        buildFile = this->CreateObject(cmXCodeObject::PBXBuildFile);
+        buildFile->AddAttribute("fileRef", fileRefObject);
+        FileRefToBuildFileMap[fileRefObject] = buildFile;
+      } else {
+        buildFile = it->second;
+      }
+    }
+    // Add this reference to current target
+    auto* buildPhases = target->GetObject("buildPhases");
+    if (!buildPhases) {
+      continue;
+    }
+    auto* frameworkBuildPhase =
+      buildPhases->GetObject(cmXCodeObject::PBXFrameworksBuildPhase);
+    if (!frameworkBuildPhase) {
+      continue;
+    }
+    auto* buildFiles = frameworkBuildPhase->GetObject("files");
+    if (!buildFiles) {
+      continue;
+    }
+    if (!buildFiles->HasObject(buildFile)) {
+      buildFiles->AddObject(buildFile);
+    }
+  }
+
   // Loop over configuration types and set per-configuration info.
   for (auto const& configName : this->CurrentConfigurationTypes) {
     {
@@ -2795,21 +3044,20 @@
     }
 
     // Compute the link library and directory information.
-    cmComputeLinkInformation* pcli = gt->GetLinkInformation(configName);
-    if (!pcli) {
+    cmComputeLinkInformation* cli = gt->GetLinkInformation(configName);
+    if (!cli) {
       continue;
     }
-    cmComputeLinkInformation& cli = *pcli;
 
     // Add dependencies directly on library files.
-    for (auto const& libDep : cli.GetDepends()) {
+    for (auto const& libDep : cli->GetDepends()) {
       target->AddDependLibrary(configName, libDep);
     }
 
     // add the library search paths
     {
       std::string linkDirs;
-      for (auto const& libDir : cli.GetDirectories()) {
+      for (auto const& libDir : cli->GetDirectories()) {
         if (!libDir.empty() && libDir != "/usr/lib") {
           // Now add the same one but append
           // $(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) to it:
@@ -2820,15 +3068,22 @@
           linkDirs += this->XCodeEscapePath(libDir);
         }
       }
+      // Add previously collected paths where to look for libraries
+      // that were added to "Link Binary With Libraries"
+      for (auto& linkDir : linkSearchPaths) {
+        linkDirs += " ";
+        linkDirs += this->XCodeEscapePath(linkDir);
+      }
       this->AppendBuildSettingAttribute(target, "LIBRARY_SEARCH_PATHS",
                                         linkDirs.c_str(), configName);
     }
 
-    // now add the link libraries
+    // now add the left-over link libraries
     {
       std::string linkLibs;
       const char* sep = "";
-      for (auto const& libName : cli.GetItems()) {
+      for (auto const& libItem : configItemMap[configName]) {
+        auto const& libName = *libItem;
         linkLibs += sep;
         sep = " ";
         if (libName.IsPath) {
@@ -2859,13 +3114,9 @@
       // end up with (empty anyhow) ZERO_CHECK, install, or test source
       // groups:
       //
-      if (gtgt->GetType() == cmStateEnums::GLOBAL_TARGET) {
-        continue;
-      }
-      if (gtgt->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
-        continue;
-      }
-      if (gtgt->GetName() == CMAKE_CHECK_BUILD_SYSTEM_TARGET) {
+      if (!gtgt->IsInBuildSystem() ||
+          gtgt->GetType() == cmStateEnums::GLOBAL_TARGET ||
+          gtgt->GetName() == CMAKE_CHECK_BUILD_SYSTEM_TARGET) {
         continue;
       }
 
@@ -3009,6 +3260,7 @@
   this->ClearXCodeObjects();
   this->RootObject = nullptr;
   this->MainGroupChildren = nullptr;
+  this->FrameworkGroup = nullptr;
   cmXCodeObject* group = this->CreateObject(cmXCodeObject::ATTRIBUTE_GROUP);
   group->AddAttribute("COPY_PHASE_STRIP", this->CreateString("NO"));
   cmXCodeObject* listObjs = this->CreateObject(cmXCodeObject::OBJECT_LIST);
@@ -3043,6 +3295,15 @@
   productGroup->AddAttribute("children", productGroupChildren);
   this->MainGroupChildren->AddObject(productGroup);
 
+  this->FrameworkGroup = this->CreateObject(cmXCodeObject::PBXGroup);
+  this->FrameworkGroup->AddAttribute("name", this->CreateString("Frameworks"));
+  this->FrameworkGroup->AddAttribute("sourceTree",
+                                     this->CreateString("<group>"));
+  cmXCodeObject* frameworkGroupChildren =
+    this->CreateObject(cmXCodeObject::OBJECT_LIST);
+  this->FrameworkGroup->AddAttribute("children", frameworkGroupChildren);
+  this->MainGroupChildren->AddObject(this->FrameworkGroup);
+
   this->RootObject = this->CreateObject(cmXCodeObject::PBXProject);
   this->RootObject->SetComment("Project object");
 
@@ -3121,7 +3382,7 @@
     buildSettings->AddAttribute("ONLY_ACTIVE_ARCH", this->CreateString("YES"));
     // When targeting macOS, use only the host architecture.
     if (this->SystemName == "Darwin"_s &&
-        (!sysroot || !*sysroot ||
+        (!cmNonempty(sysroot) ||
          cmSystemTools::LowerCase(sysroot).find("macos") !=
            std::string::npos)) {
       buildSettings->AddAttribute("ARCHS",
@@ -3131,7 +3392,7 @@
     // Tell Xcode to use ARCHS (ONLY_ACTIVE_ARCH defaults to NO).
     buildSettings->AddAttribute("ARCHS", this->CreateString(archs));
   }
-  if (deploymentTarget && *deploymentTarget) {
+  if (cmNonempty(deploymentTarget)) {
     buildSettings->AddAttribute(GetDeploymentPlatform(root->GetMakefile()),
                                 this->CreateString(deploymentTarget));
   }
diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h
index e2d1b3a..7018de7 100644
--- a/Source/cmGlobalXCodeGenerator.h
+++ b/Source/cmGlobalXCodeGenerator.h
@@ -28,7 +28,7 @@
 /** \class cmGlobalXCodeGenerator
  * \brief Write a Unix makefiles.
  *
- * cmGlobalXCodeGenerator manages UNIX build process for a tree
+ * cmGlobalXCodeGenerator manages Xcode build process for a tree
  */
 class cmGlobalXCodeGenerator : public cmGlobalGenerator
 {
@@ -204,10 +204,10 @@
                                                   cmGeneratorTarget* target,
                                                   const std::string& lang,
                                                   cmSourceFile* sf);
-  cmXCodeObject* CreateXCodeSourceFileFromPath(const std::string& fullpath,
-                                               cmGeneratorTarget* target,
-                                               const std::string& lang,
-                                               cmSourceFile* sf);
+  cmXCodeObject* CreateXCodeBuildFileFromPath(const std::string& fullpath,
+                                              cmGeneratorTarget* target,
+                                              const std::string& lang,
+                                              cmSourceFile* sf);
   cmXCodeObject* CreateXCodeFileReference(cmSourceFile* sf,
                                           cmGeneratorTarget* target);
   cmXCodeObject* CreateXCodeSourceFile(cmLocalGenerator* gen, cmSourceFile* sf,
@@ -282,6 +282,7 @@
   std::string PostBuildMakeTarget(std::string const& tName,
                                   std::string const& configName);
   cmXCodeObject* MainGroupChildren;
+  cmXCodeObject* FrameworkGroup;
   cmMakefile* CurrentMakefile;
   cmLocalGenerator* CurrentLocalGenerator;
   std::vector<std::string> CurrentConfigurationTypes;
@@ -295,13 +296,16 @@
   std::map<std::string, cmXCodeObject*> GroupNameMap;
   std::map<std::string, cmXCodeObject*> TargetGroup;
   std::map<std::string, cmXCodeObject*> FileRefs;
+  std::map<std::string, cmXCodeObject*> ExternalLibRefs;
   std::map<cmGeneratorTarget const*, cmXCodeObject*> XCodeObjectMap;
+  std::map<cmXCodeObject*, cmXCodeObject*> FileRefToBuildFileMap;
   std::vector<std::string> Architectures;
   std::string ObjectDirArchDefault;
   std::string ObjectDirArch;
   std::string SystemName;
   std::string GeneratorToolset;
   std::map<cmGeneratorTarget const*, size_t> TargetOrderIndex;
+  std::vector<std::string> EnabledLangs;
 };
 
 #endif
diff --git a/Source/cmGraphVizWriter.cxx b/Source/cmGraphVizWriter.cxx
index c23156d..570f4ea 100644
--- a/Source/cmGraphVizWriter.cxx
+++ b/Source/cmGraphVizWriter.cxx
@@ -125,14 +125,6 @@
 cmGraphVizWriter::~cmGraphVizWriter()
 {
   this->WriteFooter(this->GlobalFileStream);
-
-  for (auto& fileStream : this->PerTargetFileStreams) {
-    this->WriteFooter(*fileStream.second);
-  }
-
-  for (auto& fileStream : this->TargetDependersFileStreams) {
-    this->WriteFooter(*fileStream.second);
-  }
 }
 
 void cmGraphVizWriter::VisitGraph(std::string const&)
@@ -151,20 +143,10 @@
   ++NextNodeId;
 
   this->WriteNode(this->GlobalFileStream, item);
-
-  if (this->GeneratePerTarget) {
-    this->CreateTargetFile(this->PerTargetFileStreams, item);
-  }
-
-  if (this->GenerateDependers) {
-    this->CreateTargetFile(this->TargetDependersFileStreams, item,
-                           ".dependers");
-  }
 }
 
-void cmGraphVizWriter::CreateTargetFile(FileStreamMap& fileStreamMap,
-                                        cmLinkItem const& item,
-                                        std::string const& fileNameSuffix)
+std::unique_ptr<cmGeneratedFileStream> cmGraphVizWriter::CreateTargetFile(
+  cmLinkItem const& item, std::string const& fileNameSuffix)
 {
   auto const pathSafeItemName = PathSafeString(item.AsStr());
   auto const perTargetFileName =
@@ -175,7 +157,7 @@
   this->WriteHeader(*perTargetFileStream, item.AsStr());
   this->WriteNode(*perTargetFileStream, item);
 
-  fileStreamMap.emplace(item.AsStr(), std::move(perTargetFileStream));
+  return perTargetFileStream;
 }
 
 void cmGraphVizWriter::OnDirectLink(cmLinkItem const& depender,
@@ -260,7 +242,7 @@
   do {                                                                        \
     const char* value = mf.GetDefinition(cmakeDefinition);                    \
     if (value) {                                                              \
-      (var) = mf.IsOn(cmakeDefinition);                                       \
+      (var) = cmIsOn(value);                                                  \
     }                                                                         \
   } while (false)
 
@@ -323,13 +305,12 @@
   }
 
   if (this->GeneratePerTarget) {
-    WritePerTargetConnections<DependeesDir>(PerTargetConnections,
-                                            PerTargetFileStreams);
+    WritePerTargetConnections<DependeesDir>(PerTargetConnections);
   }
 
   if (this->GenerateDependers) {
     WritePerTargetConnections<DependersDir>(TargetDependersConnections,
-                                            TargetDependersFileStreams);
+                                            ".dependers");
   }
 }
 
@@ -368,7 +349,7 @@
 
 template <typename DirFunc>
 void cmGraphVizWriter::WritePerTargetConnections(
-  const ConnectionsMap& connections, const FileStreamMap& streams)
+  const ConnectionsMap& connections, const std::string& fileNameSuffix)
 {
   // the per target connections must be extended by indirect dependencies
   ConnectionsMap extendedConnections;
@@ -387,7 +368,9 @@
     }
 
     const Connections& cons = conPerTarget.second;
-    auto fileStream = streams.at(rootItem.AsStr()).get();
+
+    std::unique_ptr<cmGeneratedFileStream> fileStream =
+      this->CreateTargetFile(rootItem, fileNameSuffix);
 
     for (const Connection& con : cons) {
       const cmLinkItem& src = DirFunc::src(con);
@@ -395,6 +378,8 @@
       this->WriteNode(*fileStream, con.dst);
       this->WriteConnection(*fileStream, src, dst, con.scopeType);
     }
+
+    this->WriteFooter(*fileStream);
   }
 }
 
diff --git a/Source/cmGraphVizWriter.h b/Source/cmGraphVizWriter.h
index 9766068..d1300ac 100644
--- a/Source/cmGraphVizWriter.h
+++ b/Source/cmGraphVizWriter.h
@@ -46,9 +46,6 @@
   void Write();
 
 private:
-  using FileStreamMap =
-    std::map<std::string, std::unique_ptr<cmGeneratedFileStream>>;
-
   struct Connection
   {
     Connection(cmLinkItem s, cmLinkItem d, std::string scope)
@@ -76,8 +73,8 @@
 
   void WriteNode(cmGeneratedFileStream& fs, cmLinkItem const& item);
 
-  void CreateTargetFile(FileStreamMap& fileStreamMap, cmLinkItem const& target,
-                        std::string const& fileNameSuffix = "");
+  std::unique_ptr<cmGeneratedFileStream> CreateTargetFile(
+    cmLinkItem const& target, std::string const& fileNameSuffix = "");
 
   void WriteConnection(cmGeneratedFileStream& fs,
                        cmLinkItem const& dependerTargetName,
@@ -95,7 +92,7 @@
 
   template <typename DirFunc>
   void WritePerTargetConnections(const ConnectionsMap& connections,
-                                 const FileStreamMap& streams);
+                                 const std::string& fileNameSuffix = "");
 
   bool ItemExcluded(cmLinkItem const& item);
   bool ItemNameFilteredOut(std::string const& itemName);
@@ -111,8 +108,6 @@
 
   std::string FileName;
   cmGeneratedFileStream GlobalFileStream;
-  FileStreamMap PerTargetFileStreams;
-  FileStreamMap TargetDependersFileStreams;
 
   ConnectionsMap PerTargetConnections;
   ConnectionsMap TargetDependersConnections;
diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx
index 178af73..83609e2 100644
--- a/Source/cmInstallCommand.cxx
+++ b/Source/cmInstallCommand.cxx
@@ -680,7 +680,7 @@
 
     if (createInstallGeneratorsForTargetFileSets && !namelinkOnly) {
       cmProp files = target.GetProperty("PRIVATE_HEADER");
-      if (files && !files->empty()) {
+      if (cmNonempty(files)) {
         std::vector<std::string> relFiles = cmExpandedList(*files);
         std::vector<std::string> absFiles;
         if (!helper.MakeFilesFullPath("PRIVATE_HEADER", relFiles, absFiles)) {
@@ -702,7 +702,7 @@
       }
 
       files = target.GetProperty("PUBLIC_HEADER");
-      if (files && !files->empty()) {
+      if (cmNonempty(files)) {
         std::vector<std::string> relFiles = cmExpandedList(*files);
         std::vector<std::string> absFiles;
         if (!helper.MakeFilesFullPath("PUBLIC_HEADER", relFiles, absFiles)) {
@@ -724,7 +724,7 @@
       }
 
       files = target.GetProperty("RESOURCE");
-      if (files && !files->empty()) {
+      if (cmNonempty(files)) {
         std::vector<std::string> relFiles = cmExpandedList(*files);
         std::vector<std::string> absFiles;
         if (!helper.MakeFilesFullPath("RESOURCE", relFiles, absFiles)) {
@@ -1157,7 +1157,7 @@
     } else if (doing == DoingRegex) {
       literal_args += " REGEX \"";
 // Match rules are case-insensitive on some platforms.
-#if defined(_WIN32) || defined(__APPLE__) || defined(__CYGWIN__)
+#if defined(_WIN32) || defined(__APPLE__)
       std::string regex = cmSystemTools::LowerCase(args[i]);
 #else
       std::string regex = args[i];
diff --git a/Source/cmJsonObjects.cxx b/Source/cmJsonObjects.cxx
index 9f17f15..3a2e3be 100644
--- a/Source/cmJsonObjects.cxx
+++ b/Source/cmJsonObjects.cxx
@@ -51,11 +51,7 @@
     return configurations;
   }
 
-  makefiles[0]->GetConfigurations(configurations);
-  if (configurations.empty()) {
-    configurations.emplace_back();
-  }
-  return configurations;
+  return makefiles[0]->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
 }
 
 bool hasString(const Json::Value& v, const std::string& s)
diff --git a/Source/cmLinkItemGraphVisitor.cxx b/Source/cmLinkItemGraphVisitor.cxx
index acc23c8..dfdd3ff 100644
--- a/Source/cmLinkItemGraphVisitor.cxx
+++ b/Source/cmLinkItemGraphVisitor.cxx
@@ -24,15 +24,12 @@
 void cmLinkItemGraphVisitor::VisitLinks(cmLinkItem const& item,
                                         cmLinkItem const& rootItem)
 {
-  if (this->LinkVisited(item, rootItem)) {
-    return;
-  }
-
   if (item.Target == nullptr) {
     return;
   }
 
-  for (auto const& config : item.Target->Makefile->GetGeneratorConfigs()) {
+  for (auto const& config : item.Target->Makefile->GetGeneratorConfigs(
+         cmMakefile::IncludeEmptyConfig)) {
     this->VisitLinks(item, rootItem, config);
   }
 }
diff --git a/Source/cmLinkLineDeviceComputer.cxx b/Source/cmLinkLineDeviceComputer.cxx
index c50a786..5739fec 100644
--- a/Source/cmLinkLineDeviceComputer.cxx
+++ b/Source/cmLinkLineDeviceComputer.cxx
@@ -191,21 +191,18 @@
     target.GetLinkClosure(config);
 
   if (cm::contains(closure->Languages, "CUDA")) {
-    if (cmProp separableCompilation =
-          target.GetProperty("CUDA_SEPARABLE_COMPILATION")) {
-      if (cmIsOn(*separableCompilation)) {
-        bool doDeviceLinking = false;
-        switch (target.GetType()) {
-          case cmStateEnums::SHARED_LIBRARY:
-          case cmStateEnums::MODULE_LIBRARY:
-          case cmStateEnums::EXECUTABLE:
-            doDeviceLinking = true;
-            break;
-          default:
-            break;
-        }
-        return doDeviceLinking;
+    if (cmIsOn(target.GetProperty("CUDA_SEPARABLE_COMPILATION"))) {
+      bool doDeviceLinking = false;
+      switch (target.GetType()) {
+        case cmStateEnums::SHARED_LIBRARY:
+        case cmStateEnums::MODULE_LIBRARY:
+        case cmStateEnums::EXECUTABLE:
+          doDeviceLinking = true;
+          break;
+        default:
+          break;
       }
+      return doDeviceLinking;
     }
 
     cmComputeLinkInformation* pcli = target.GetLinkInformation(config);
diff --git a/Source/cmListFileCache.h b/Source/cmListFileCache.h
index 89902ff..0b4414d 100644
--- a/Source/cmListFileCache.h
+++ b/Source/cmListFileCache.h
@@ -175,6 +175,32 @@
 
 std::ostream& operator<<(std::ostream& os, BT<std::string> const& s);
 
+// Wrap type T as a value with potentially multiple backtraces.  For purposes
+// of ordering and equality comparison, only the original value is used.  The
+// backtrace is considered incidental.
+template <typename T>
+class BTs
+{
+public:
+  BTs(T v = T(), cmListFileBacktrace bt = cmListFileBacktrace())
+    : Value(std::move(v))
+  {
+    Backtraces.emplace_back(std::move(bt));
+  }
+  T Value;
+  std::vector<cmListFileBacktrace> Backtraces;
+  friend bool operator==(BTs<T> const& l, BTs<T> const& r)
+  {
+    return l.Value == r.Value;
+  }
+  friend bool operator<(BTs<T> const& l, BTs<T> const& r)
+  {
+    return l.Value < r.Value;
+  }
+  friend bool operator==(BTs<T> const& l, T const& r) { return l.Value == r; }
+  friend bool operator==(T const& l, BTs<T> const& r) { return l == r.Value; }
+};
+
 std::vector<BT<std::string>> ExpandListWithBacktrace(
   std::string const& list,
   cmListFileBacktrace const& bt = cmListFileBacktrace());
diff --git a/Source/cmLocalCommonGenerator.cxx b/Source/cmLocalCommonGenerator.cxx
index 278ec8b..44db842 100644
--- a/Source/cmLocalCommonGenerator.cxx
+++ b/Source/cmLocalCommonGenerator.cxx
@@ -17,10 +17,8 @@
   : cmLocalGenerator(gg, mf)
   , WorkingDirectory(std::move(wd))
 {
-  this->Makefile->GetConfigurations(this->ConfigNames);
-  if (this->ConfigNames.empty()) {
-    this->ConfigNames.emplace_back();
-  }
+  this->ConfigNames =
+    this->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
 }
 
 cmLocalCommonGenerator::~cmLocalCommonGenerator() = default;
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index c15ca7c..2380cce 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -39,6 +39,7 @@
 #include "cmSourceFile.h"
 #include "cmSourceFileLocation.h"
 #include "cmSourceFileLocationKind.h"
+#include "cmStandardLevelResolver.h"
 #include "cmState.h"
 #include "cmStateDirectory.h"
 #include "cmStateTypes.h"
@@ -129,7 +130,7 @@
     this->LinkerSysroot = this->Makefile->GetSafeDefinition("CMAKE_SYSROOT");
   }
 
-  if (std::string const* appleArchSysroots =
+  if (cmProp appleArchSysroots =
         this->Makefile->GetDef("CMAKE_APPLE_ARCH_SYSROOTS")) {
     std::string const& appleArchs =
       this->Makefile->GetSafeDefinition("CMAKE_OSX_ARCHITECTURES");
@@ -220,7 +221,7 @@
   this->ObjectPathMax = 1000;
 #endif
   const char* plen = this->Makefile->GetDefinition("CMAKE_OBJECT_PATH_MAX");
-  if (plen && *plen) {
+  if (cmNonempty(plen)) {
     unsigned int pmax;
     if (sscanf(plen, "%u", &pmax) == 1) {
       if (pmax >= 128) {
@@ -283,7 +284,7 @@
   // Generate the rule files for each target.
   const auto& targets = this->GetGeneratorTargets();
   for (const auto& target : targets) {
-    if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+    if (!target->IsInBuildSystem()) {
       continue;
     }
     target->TraceDependencies();
@@ -297,9 +298,9 @@
   }
 
   // Compute the set of configurations.
-  std::vector<std::string> configurationTypes;
-  const std::string& config =
-    this->Makefile->GetConfigurations(configurationTypes, false);
+  std::vector<std::string> configurationTypes =
+    this->Makefile->GetGeneratorConfigs(cmMakefile::OnlyMultiConfig);
+  std::string config = this->Makefile->GetDefaultConfiguration();
 
   std::string file =
     cmStrCat(this->StateSnapshot.GetDirectory().GetCurrentBinary(),
@@ -379,7 +380,7 @@
 void cmLocalGenerator::CreateEvaluationFileOutputs()
 {
   std::vector<std::string> const& configs =
-    this->Makefile->GetGeneratorConfigs();
+    this->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
   for (std::string const& c : configs) {
     this->CreateEvaluationFileOutputs(c);
   }
@@ -433,7 +434,7 @@
       prefix_win32 = "C:";
     }
     const char* project_name = this->Makefile->GetDefinition("PROJECT_NAME");
-    if (project_name && project_name[0]) {
+    if (cmNonempty(project_name)) {
       prefix_win32 += "/Program Files/";
       prefix_win32 += project_name;
     } else {
@@ -462,9 +463,9 @@
   }
 
   // Compute the set of configurations.
-  std::vector<std::string> configurationTypes;
-  const std::string& config =
-    this->Makefile->GetConfigurations(configurationTypes, false);
+  std::vector<std::string> configurationTypes =
+    this->Makefile->GetGeneratorConfigs(cmMakefile::OnlyMultiConfig);
+  std::string config = this->Makefile->GetDefaultConfiguration();
 
   // Choose a default install configuration.
   std::string default_config = config;
@@ -753,16 +754,13 @@
 void cmLocalGenerator::ComputeTargetManifest()
 {
   // Collect the set of configuration types.
-  std::vector<std::string> configNames;
-  this->Makefile->GetConfigurations(configNames);
-  if (configNames.empty()) {
-    configNames.emplace_back();
-  }
+  std::vector<std::string> configNames =
+    this->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
 
   // Add our targets to the manifest for each configuration.
   const auto& targets = this->GetGeneratorTargets();
   for (const auto& target : targets) {
-    if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+    if (!target->IsInBuildSystem()) {
       continue;
     }
     for (std::string const& c : configNames) {
@@ -774,11 +772,8 @@
 bool cmLocalGenerator::ComputeTargetCompileFeatures()
 {
   // Collect the set of configuration types.
-  std::vector<std::string> configNames;
-  this->Makefile->GetConfigurations(configNames);
-  if (configNames.empty()) {
-    configNames.emplace_back();
-  }
+  std::vector<std::string> configNames =
+    this->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
 
   using LanguagePair = std::pair<std::string, std::string>;
   std::vector<LanguagePair> pairedLanguages{ { "OBJC", "C" },
@@ -802,40 +797,9 @@
 
     // Now that C/C++ _STANDARD values have been computed
     // set the values to ObjC/ObjCXX _STANDARD variables
-    if (target->GetType() != cmStateEnums::INTERFACE_LIBRARY) {
-      auto copyStandardToObjLang = [&](LanguagePair const& lang) -> bool {
-        if (!target->GetProperty(cmStrCat(lang.first, "_STANDARD"))) {
-          cmProp standard =
-            target->GetProperty(cmStrCat(lang.second, "_STANDARD"));
-          if (!standard) {
-            standard = this->Makefile->GetDef(
-              cmStrCat("CMAKE_", lang.second, "_STANDARD_DEFAULT"));
-          }
-          target->Target->SetProperty(cmStrCat(lang.first, "_STANDARD"),
-                                      standard ? standard->c_str() : nullptr);
-          return true;
-        }
-        return false;
-      };
-      auto copyPropertyToObjLang = [&](LanguagePair const& lang,
-                                       const char* property) {
-        if (!target->GetProperty(cmStrCat(lang.first, property)) &&
-            target->GetProperty(cmStrCat(lang.second, property))) {
-          cmProp p = target->GetProperty(cmStrCat(lang.second, property));
-          target->Target->SetProperty(cmStrCat(lang.first, property),
-                                      p ? p->c_str() : nullptr);
-        }
-      };
-      for (auto const& lang : pairedLanguages) {
-        if (copyStandardToObjLang(lang)) {
-          copyPropertyToObjLang(lang, "_STANDARD_REQUIRED");
-          copyPropertyToObjLang(lang, "_EXTENSIONS");
-        }
-      }
-      if (cmProp standard = target->GetProperty("CUDA_STANDARD")) {
-        if (*standard == "98") {
-          target->Target->SetProperty("CUDA_STANDARD", "03");
-        }
+    if (target->CanCompileSources()) {
+      for (std::string const& c : configNames) {
+        target->ComputeCompileFeatures(c, inferredEnabledLanguages);
       }
     }
   }
@@ -929,7 +893,7 @@
   emitted.insert("/System/Library/Frameworks");
 #endif
   for (std::string const& i : includes) {
-    if (fwSearchFlag && *fwSearchFlag && this->Makefile->IsOn("APPLE") &&
+    if (cmNonempty(fwSearchFlag) && this->Makefile->IsOn("APPLE") &&
         cmSystemTools::IsPathToFramework(i)) {
       std::string const frameworkDir =
         cmSystemTools::CollapseFullPath(cmStrCat(i, "/../"));
@@ -1025,12 +989,13 @@
     this->AppendCompileOptions(flags, targetCompileOpts);
   }
 
+  cmStandardLevelResolver standardResolver(this->Makefile);
   for (auto const& it : target->GetMaxLanguageStandards()) {
-    cmProp standard = target->GetProperty(it.first + "_STANDARD");
+    cmProp standard = target->GetLanguageStandard(it.first, config);
     if (!standard) {
       continue;
     }
-    if (this->Makefile->IsLaterStandard(it.first, *standard, it.second)) {
+    if (standardResolver.IsLaterStandard(it.first, *standard, it.second)) {
       std::ostringstream e;
       e << "The COMPILE_FEATURES property of target \"" << target->GetName()
         << "\" was evaluated when computing the link "
@@ -1050,7 +1015,7 @@
   }
 
   std::string compReqFlag;
-  this->AddCompilerRequirementFlag(compReqFlag, target, lang);
+  this->AddCompilerRequirementFlag(compReqFlag, target, lang, config);
   if (!compReqFlag.empty()) {
     flags.emplace_back(std::move(compReqFlag));
   }
@@ -1308,7 +1273,7 @@
     }
   }
 
-  // Emit remaining non implicit user direcories.
+  // Emit remaining non implicit user directories.
   for (BT<std::string> const& udr : userDirs) {
     if (notExcluded(udr.Value)) {
       emitBT(udr);
@@ -1578,9 +1543,8 @@
                                   frameworkPath, linkPath);
       }
 
-      if (cmIsOn(this->Makefile->GetDefinition("BUILD_SHARED_LIBS"))) {
-        std::string sFlagVar = std::string("CMAKE_SHARED_BUILD_") +
-          linkLanguage + std::string("_FLAGS");
+      if (this->Makefile->IsOn("BUILD_SHARED_LIBS")) {
+        std::string sFlagVar = "CMAKE_SHARED_BUILD_" + linkLanguage + "_FLAGS";
         exeFlags += this->Makefile->GetSafeDefinition(sFlagVar);
         exeFlags += " ";
       }
@@ -1689,7 +1653,7 @@
 
   std::string fwSearchFlagVar = "CMAKE_" + lang + "_FRAMEWORK_SEARCH_FLAG";
   const char* fwSearchFlag = mf->GetDefinition(fwSearchFlagVar);
-  if (!(fwSearchFlag && *fwSearchFlag)) {
+  if (!cmNonempty(fwSearchFlag)) {
     return std::string();
   }
 
@@ -1928,7 +1892,7 @@
     std::string sysrootFlagVar =
       std::string("CMAKE_") + lang + "_SYSROOT_FLAG";
     const char* sysrootFlag = this->Makefile->GetDefinition(sysrootFlagVar);
-    if (sysrootFlag && *sysrootFlag) {
+    if (cmNonempty(sysrootFlag)) {
       if (!this->AppleArchSysroots.empty() &&
           !this->AllAppleArchSysrootsAreTheSame(archs, sysroot)) {
         for (std::string const& arch : archs) {
@@ -1957,8 +1921,7 @@
       std::string("CMAKE_") + lang + "_OSX_DEPLOYMENT_TARGET_FLAG";
     const char* deploymentTargetFlag =
       this->Makefile->GetDefinition(deploymentTargetFlagVar);
-    if (deploymentTargetFlag && *deploymentTargetFlag && deploymentTarget &&
-        *deploymentTarget) {
+    if (cmNonempty(deploymentTargetFlag) && cmNonempty(deploymentTarget)) {
       flags += " ";
       flags += deploymentTargetFlag;
       flags += deploymentTarget;
@@ -1975,6 +1938,9 @@
   this->AddConfigVariableFlags(flags, cmStrCat("CMAKE_", lang, "_FLAGS"),
                                config);
 
+  std::string const& compiler = this->Makefile->GetSafeDefinition(
+    cmStrCat("CMAKE_", lang, "_COMPILER_ID"));
+
   if (lang == "Swift") {
     if (cmProp v = target->GetProperty("Swift_LANGUAGE_VERSION")) {
       if (cmSystemTools::VersionCompare(
@@ -1988,9 +1954,6 @@
     target->AddCUDAArchitectureFlags(flags);
     target->AddCUDAToolkitFlags(flags);
 
-    std::string const& compiler =
-      this->Makefile->GetSafeDefinition("CMAKE_CUDA_COMPILER_ID");
-
     if (compiler == "Clang") {
       bool separable = target->GetPropertyAsBool("CUDA_SEPARABLE_COMPILATION");
 
@@ -2002,12 +1965,29 @@
       }
     }
   }
-
+  // Add VFS Overlay for Clang compiliers
+  if (compiler == "Clang") {
+    if (const char* vfsOverlay =
+          this->Makefile->GetDefinition("CMAKE_CLANG_VFS_OVERLAY")) {
+      std::string const& compilerSimulateId =
+        this->Makefile->GetSafeDefinition(
+          cmStrCat("CMAKE_", lang, "_SIMULATE_ID"));
+      if (compilerSimulateId == "MSVC") {
+        this->AppendCompileOptions(
+          flags,
+          std::vector<std::string>{ "-Xclang", "-ivfsoverlay", "-Xclang",
+                                    vfsOverlay });
+      } else {
+        this->AppendCompileOptions(
+          flags, std::vector<std::string>{ "-ivfsoverlay", vfsOverlay });
+      }
+    }
+  }
   // Add MSVC runtime library flags.  This is activated by the presence
   // of a default selection whether or not it is overridden by a property.
   cmProp msvcRuntimeLibraryDefault =
     this->Makefile->GetDef("CMAKE_MSVC_RUNTIME_LIBRARY_DEFAULT");
-  if (msvcRuntimeLibraryDefault && !msvcRuntimeLibraryDefault->empty()) {
+  if (cmNonempty(msvcRuntimeLibraryDefault)) {
     cmProp msvcRuntimeLibraryValue =
       target->GetProperty("MSVC_RUNTIME_LIBRARY");
     if (!msvcRuntimeLibraryValue) {
@@ -2046,7 +2026,7 @@
     // when linking in order to use the matching standard library.
     // FIXME: If CMake gains an abstraction for standard library
     // selection, this will have to be reconciled with it.
-    this->AddCompilerRequirementFlag(flags, target, lang);
+    this->AddCompilerRequirementFlag(flags, target, lang, config);
   }
 
   this->AddLanguageFlags(flags, target, lang, config);
@@ -2189,157 +2169,21 @@
 }
 
 void cmLocalGenerator::AddCompilerRequirementFlag(
-  std::string& flags, cmGeneratorTarget const* target, const std::string& lang)
+  std::string& flags, cmGeneratorTarget const* target, const std::string& lang,
+  const std::string& config)
 {
-  if (lang.empty()) {
-    return;
-  }
-  const char* defaultStd =
-    this->Makefile->GetDefinition("CMAKE_" + lang + "_STANDARD_DEFAULT");
-  if (!defaultStd || !*defaultStd) {
-    // This compiler has no notion of language standard levels.
-    return;
-  }
-  std::string extProp = lang + "_EXTENSIONS";
-  bool ext = true;
-  if (cmProp extPropValue = target->GetProperty(extProp)) {
-    if (cmIsOff(*extPropValue)) {
-      ext = false;
-    }
-  }
-  std::string stdProp = lang + "_STANDARD";
-  cmProp standardProp = target->GetProperty(stdProp);
-  if (!standardProp) {
-    if (ext) {
-      // No language standard is specified and extensions are not disabled.
-      // Check if this compiler needs a flag to enable extensions.
-      std::string const option_flag =
-        "CMAKE_" + lang + "_EXTENSION_COMPILE_OPTION";
-      if (const char* opt =
-            target->Target->GetMakefile()->GetDefinition(option_flag)) {
-        std::vector<std::string> optVec = cmExpandedList(opt);
-        for (std::string const& i : optVec) {
-          this->AppendFlagEscape(flags, i);
-        }
-      }
-    }
-    return;
-  }
+  cmStandardLevelResolver standardResolver(this->Makefile);
 
-  std::string const type = ext ? "EXTENSION" : "STANDARD";
-
-  if (target->GetPropertyAsBool(lang + "_STANDARD_REQUIRED")) {
-    std::string option_flag =
-      "CMAKE_" + lang + *standardProp + "_" + type + "_COMPILE_OPTION";
-
-    const char* opt =
-      target->Target->GetMakefile()->GetDefinition(option_flag);
-    if (!opt) {
-      std::ostringstream e;
-      e << "Target \"" << target->GetName()
-        << "\" requires the language "
-           "dialect \""
-        << lang << *standardProp << "\" "
-        << (ext ? "(with compiler extensions)" : "")
-        << ", but CMake "
-           "does not know the compile flags to use to enable it.";
-      this->IssueMessage(MessageType::FATAL_ERROR, e.str());
-    } else {
+  std::string const& optionFlagDef =
+    standardResolver.GetCompileOptionDef(target, lang, config);
+  if (!optionFlagDef.empty()) {
+    auto opt = target->Target->GetMakefile()->GetDefinition(optionFlagDef);
+    if (opt) {
       std::vector<std::string> optVec = cmExpandedList(opt);
       for (std::string const& i : optVec) {
         this->AppendFlagEscape(flags, i);
       }
     }
-    return;
-  }
-
-  static std::map<std::string, std::vector<std::string>> langStdMap;
-  if (langStdMap.empty()) {
-    // Maintain sorted order, most recent first.
-    langStdMap["CXX"].emplace_back("20");
-    langStdMap["CXX"].emplace_back("17");
-    langStdMap["CXX"].emplace_back("14");
-    langStdMap["CXX"].emplace_back("11");
-    langStdMap["CXX"].emplace_back("98");
-
-    langStdMap["OBJCXX"].emplace_back("20");
-    langStdMap["OBJCXX"].emplace_back("17");
-    langStdMap["OBJCXX"].emplace_back("14");
-    langStdMap["OBJCXX"].emplace_back("11");
-    langStdMap["OBJCXX"].emplace_back("98");
-
-    langStdMap["C"].emplace_back("11");
-    langStdMap["C"].emplace_back("99");
-    langStdMap["C"].emplace_back("90");
-
-    langStdMap["OBJC"].emplace_back("11");
-    langStdMap["OBJC"].emplace_back("99");
-    langStdMap["OBJC"].emplace_back("90");
-
-    langStdMap["CUDA"].emplace_back("20");
-    langStdMap["CUDA"].emplace_back("17");
-    langStdMap["CUDA"].emplace_back("14");
-    langStdMap["CUDA"].emplace_back("11");
-    langStdMap["CUDA"].emplace_back("03");
-  }
-
-  std::string standard(*standardProp);
-  if (lang == "CUDA" && standard == "98") {
-    standard = "03";
-  }
-  std::vector<std::string>& stds = langStdMap[lang];
-
-  auto stdIt = std::find(stds.begin(), stds.end(), standard);
-  if (stdIt == stds.end()) {
-
-    std::string e =
-      lang + "_STANDARD is set to invalid value '" + standard + "'";
-    this->GetGlobalGenerator()->GetCMakeInstance()->IssueMessage(
-      MessageType::FATAL_ERROR, e, target->GetBacktrace());
-    return;
-  }
-
-  auto defaultStdIt = std::find(stds.begin(), stds.end(), defaultStd);
-  if (defaultStdIt == stds.end()) {
-    std::string e = "CMAKE_" + lang +
-      "_STANDARD_DEFAULT is set to invalid value '" + std::string(defaultStd) +
-      "'";
-    this->IssueMessage(MessageType::INTERNAL_ERROR, e);
-    return;
-  }
-
-  // If the standard requested is older than the compiler's default
-  // then we need to use a flag to change it.  The comparison is
-  // greater-or-equal because the standards are stored in backward
-  // chronological order.
-  if (stdIt >= defaultStdIt) {
-    std::string option_flag =
-      "CMAKE_" + lang + *stdIt + "_" + type + "_COMPILE_OPTION";
-
-    std::string const& opt =
-      target->Target->GetMakefile()->GetRequiredDefinition(option_flag);
-    std::vector<std::string> optVec = cmExpandedList(opt);
-    for (std::string const& i : optVec) {
-      this->AppendFlagEscape(flags, i);
-    }
-    return;
-  }
-
-  // The standard requested is at least as new as the compiler's default,
-  // and the standard request is not required.  Decay to the newest standard
-  // for which a flag is defined.
-  for (; stdIt < defaultStdIt; ++stdIt) {
-    std::string option_flag =
-      cmStrCat("CMAKE_", lang, *stdIt, "_", type, "_COMPILE_OPTION");
-
-    if (const char* opt =
-          target->Target->GetMakefile()->GetDefinition(option_flag)) {
-      std::vector<std::string> optVec = cmExpandedList(opt);
-      for (std::string const& i : optVec) {
-        this->AppendFlagEscape(flags, i);
-      }
-      return;
-    }
   }
 }
 
@@ -2583,11 +2427,8 @@
 
 void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target)
 {
-  std::vector<std::string> configsList;
-  std::string configDefault = this->Makefile->GetConfigurations(configsList);
-  if (configsList.empty()) {
-    configsList.push_back(configDefault);
-  }
+  std::vector<std::string> configsList =
+    this->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
 
   for (std::string const& config : configsList) {
     // FIXME: Refactor collection of sources to not evaluate object
@@ -3236,7 +3077,7 @@
   if (!lang.empty()) {
     const char* df =
       this->Makefile->GetDefinition(cmStrCat("CMAKE_", lang, "_DEFINE_FLAG"));
-    if (df && *df) {
+    if (cmNonempty(df)) {
       dflag = df;
     }
   }
@@ -3291,8 +3132,8 @@
   }
 }
 
-const char* cmLocalGenerator::GetFeature(const std::string& feature,
-                                         const std::string& config)
+cmProp cmLocalGenerator::GetFeature(const std::string& feature,
+                                    const std::string& config)
 {
   std::string featureName = feature;
   // TODO: Define accumulation policy for features (prepend, append,
@@ -3304,7 +3145,7 @@
   cmStateSnapshot snp = this->StateSnapshot;
   while (snp.IsValid()) {
     if (cmProp value = snp.GetDirectory().GetProperty(featureName)) {
-      return value->c_str();
+      return value;
     }
     snp = snp.GetBuildsystemDirectoryParent();
   }
@@ -3845,8 +3686,7 @@
 {
   // Find the Info.plist template.
   cmProp in = target->GetProperty("MACOSX_BUNDLE_INFO_PLIST");
-  std::string inFile =
-    (in && !in->empty()) ? *in : "MacOSXBundleInfo.plist.in";
+  std::string inFile = cmNonempty(in) ? *in : "MacOSXBundleInfo.plist.in";
   if (!cmSystemTools::FileIsFullPath(inFile)) {
     std::string inMod = this->Makefile->GetModulesFile(inFile);
     if (!inMod.empty()) {
@@ -3876,7 +3716,7 @@
   cmLGInfoProp(mf, target, "MACOSX_BUNDLE_SHORT_VERSION_STRING");
   cmLGInfoProp(mf, target, "MACOSX_BUNDLE_BUNDLE_VERSION");
   cmLGInfoProp(mf, target, "MACOSX_BUNDLE_COPYRIGHT");
-  mf->ConfigureFile(inFile, fname, false, false, false);
+  mf->ConfigureFile(inFile, fname, false, false, false, true);
 }
 
 void cmLocalGenerator::GenerateFrameworkInfoPList(
@@ -3885,8 +3725,7 @@
 {
   // Find the Info.plist template.
   cmProp in = target->GetProperty("MACOSX_FRAMEWORK_INFO_PLIST");
-  std::string inFile =
-    (in && !in->empty()) ? *in : "MacOSXFrameworkInfo.plist.in";
+  std::string inFile = cmNonempty(in) ? *in : "MacOSXFrameworkInfo.plist.in";
   if (!cmSystemTools::FileIsFullPath(inFile)) {
     std::string inMod = this->Makefile->GetModulesFile(inFile);
     if (!inMod.empty()) {
@@ -3912,7 +3751,7 @@
   cmLGInfoProp(mf, target, "MACOSX_FRAMEWORK_IDENTIFIER");
   cmLGInfoProp(mf, target, "MACOSX_FRAMEWORK_SHORT_VERSION_STRING");
   cmLGInfoProp(mf, target, "MACOSX_FRAMEWORK_BUNDLE_VERSION");
-  mf->ConfigureFile(inFile, fname, false, false, false);
+  mf->ConfigureFile(inFile, fname, false, false, false, true);
 }
 
 namespace {
diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h
index f2d9145..0c51a65 100644
--- a/Source/cmLocalGenerator.h
+++ b/Source/cmLocalGenerator.h
@@ -20,6 +20,7 @@
 #include "cmMessageType.h"
 #include "cmOutputConverter.h"
 #include "cmPolicies.h"
+#include "cmProperty.h"
 #include "cmStateSnapshot.h"
 
 class cmComputeLinkInformation;
@@ -123,7 +124,8 @@
                               const std::string& config);
   void AddCompilerRequirementFlag(std::string& flags,
                                   cmGeneratorTarget const* target,
-                                  const std::string& lang);
+                                  const std::string& lang,
+                                  const std::string& config);
   //! Append flags to a string.
   virtual void AppendFlags(std::string& flags,
                            const std::string& newFlags) const;
@@ -208,8 +210,7 @@
   void AppendFeatureOptions(std::string& flags, const std::string& lang,
                             const char* feature);
 
-  const char* GetFeature(const std::string& feature,
-                         const std::string& config);
+  cmProp GetFeature(const std::string& feature, const std::string& config);
 
   /** \brief Get absolute path to dependency \a name
    *
diff --git a/Source/cmLocalGhsMultiGenerator.cxx b/Source/cmLocalGhsMultiGenerator.cxx
index 098fa5a..a23ad57 100644
--- a/Source/cmLocalGhsMultiGenerator.cxx
+++ b/Source/cmLocalGhsMultiGenerator.cxx
@@ -11,7 +11,6 @@
 #include "cmGhsMultiTargetGenerator.h"
 #include "cmGlobalGenerator.h"
 #include "cmSourceFile.h"
-#include "cmStateTypes.h"
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
 
@@ -33,7 +32,7 @@
 void cmLocalGhsMultiGenerator::GenerateTargetsDepthFirst(
   cmGeneratorTarget* target, std::vector<cmGeneratorTarget*>& remaining)
 {
-  if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+  if (!target->IsInBuildSystem()) {
     return;
   }
   // Find this target in the list of remaining targets.
diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx
index 87e8aa4..eb841d9 100644
--- a/Source/cmLocalNinjaGenerator.cxx
+++ b/Source/cmLocalNinjaGenerator.cxx
@@ -84,13 +84,31 @@
     if (!showIncludesPrefix.empty()) {
       cmGlobalNinjaGenerator::WriteComment(this->GetRulesFileStream(),
                                            "localized /showIncludes string");
-      this->GetRulesFileStream()
-        << "msvc_deps_prefix = " << showIncludesPrefix << "\n\n";
+      this->GetRulesFileStream() << "msvc_deps_prefix = ";
+#ifdef WIN32
+      // Ninja uses the ANSI Windows APIs, so strings in the rules file
+      // typically need to be ANSI encoded. However, in this case the compiler
+      // is being invoked using the UTF-8 codepage so the /showIncludes prefix
+      // will be UTF-8 encoded on stdout. Ninja can't successfully compare this
+      // UTF-8 encoded prefix to the ANSI encoded msvc_deps_prefix if it
+      // contains any non-ASCII characters and dependency checking will fail.
+      // As a workaround, leave the msvc_deps_prefix UTF-8 encoded even though
+      // the rest of the file is ANSI encoded.
+      if (GetConsoleOutputCP() == CP_UTF8 && GetACP() != CP_UTF8) {
+        this->GetRulesFileStream().WriteRaw(showIncludesPrefix);
+      } else {
+        this->GetRulesFileStream() << showIncludesPrefix;
+      }
+#else
+      // It's safe to use the standard encoding on other platforms.
+      this->GetRulesFileStream() << showIncludesPrefix;
+#endif
+      this->GetRulesFileStream() << "\n\n";
     }
   }
 
   for (const auto& target : this->GetGeneratorTargets()) {
-    if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+    if (!target->IsInBuildSystem()) {
       continue;
     }
     auto tg = cmNinjaTargetGenerator::New(target.get());
@@ -102,9 +120,10 @@
               this->GetGlobalGenerator()->IsMultiConfig()) {
             cmNinjaBuild phonyAlias("phony");
             this->GetGlobalNinjaGenerator()->AppendTargetOutputs(
-              target.get(), phonyAlias.Outputs, "");
+              target.get(), phonyAlias.Outputs, "", DependOnTargetArtifact);
             this->GetGlobalNinjaGenerator()->AppendTargetOutputs(
-              target.get(), phonyAlias.ExplicitDeps, config);
+              target.get(), phonyAlias.ExplicitDeps, config,
+              DependOnTargetArtifact);
             this->GetGlobalNinjaGenerator()->WriteBuild(
               *this->GetGlobalNinjaGenerator()->GetConfigFileStream(config),
               phonyAlias);
@@ -115,11 +134,12 @@
           if (!this->GetGlobalNinjaGenerator()->GetDefaultConfigs().empty()) {
             cmNinjaBuild phonyAlias("phony");
             this->GetGlobalNinjaGenerator()->AppendTargetOutputs(
-              target.get(), phonyAlias.Outputs, "");
+              target.get(), phonyAlias.Outputs, "", DependOnTargetArtifact);
             for (auto const& config :
                  this->GetGlobalNinjaGenerator()->GetDefaultConfigs()) {
               this->GetGlobalNinjaGenerator()->AppendTargetOutputs(
-                target.get(), phonyAlias.ExplicitDeps, config);
+                target.get(), phonyAlias.ExplicitDeps, config,
+                DependOnTargetArtifact);
             }
             this->GetGlobalNinjaGenerator()->WriteBuild(
               *this->GetGlobalNinjaGenerator()->GetDefaultFileStream(),
@@ -127,10 +147,11 @@
           }
           cmNinjaBuild phonyAlias("phony");
           this->GetGlobalNinjaGenerator()->AppendTargetOutputs(
-            target.get(), phonyAlias.Outputs, "all");
+            target.get(), phonyAlias.Outputs, "all", DependOnTargetArtifact);
           for (auto const& config : this->GetConfigNames()) {
             this->GetGlobalNinjaGenerator()->AppendTargetOutputs(
-              target.get(), phonyAlias.ExplicitDeps, config);
+              target.get(), phonyAlias.ExplicitDeps, config,
+              DependOnTargetArtifact);
           }
           this->GetGlobalNinjaGenerator()->WriteBuild(
             *this->GetGlobalNinjaGenerator()->GetDefaultFileStream(),
@@ -355,8 +376,8 @@
                                                 cmNinjaDeps& outputs,
                                                 const std::string& config)
 {
-  this->GetGlobalNinjaGenerator()->AppendTargetOutputs(target, outputs,
-                                                       config);
+  this->GetGlobalNinjaGenerator()->AppendTargetOutputs(target, outputs, config,
+                                                       DependOnTargetArtifact);
 }
 
 void cmLocalNinjaGenerator::AppendTargetDepends(cmGeneratorTarget* target,
@@ -668,7 +689,7 @@
 {
   cmProp property_value = this->Makefile->GetProperty("RULE_LAUNCH_CUSTOM");
 
-  if (!property_value || property_value->empty()) {
+  if (!cmNonempty(property_value)) {
     return std::string();
   }
 
diff --git a/Source/cmLocalNinjaGenerator.h b/Source/cmLocalNinjaGenerator.h
index ef160e7..73c0cde 100644
--- a/Source/cmLocalNinjaGenerator.h
+++ b/Source/cmLocalNinjaGenerator.h
@@ -66,10 +66,10 @@
 
   void AppendTargetOutputs(cmGeneratorTarget* target, cmNinjaDeps& outputs,
                            const std::string& config);
-  void AppendTargetDepends(
-    cmGeneratorTarget* target, cmNinjaDeps& outputs, const std::string& config,
-    const std::string& fileConfig,
-    cmNinjaTargetDepends depends = DependOnTargetArtifact);
+  void AppendTargetDepends(cmGeneratorTarget* target, cmNinjaDeps& outputs,
+                           const std::string& config,
+                           const std::string& fileConfig,
+                           cmNinjaTargetDepends depends);
 
   void AddCustomCommandTarget(cmCustomCommand const* cc,
                               cmGeneratorTarget* target);
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index de1461a..8acd1e3 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -101,7 +101,7 @@
   cmGlobalUnixMakefileGenerator3* gg =
     static_cast<cmGlobalUnixMakefileGenerator3*>(this->GlobalGenerator);
   for (const auto& target : this->GetGeneratorTargets()) {
-    if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+    if (!target->IsInBuildSystem()) {
       continue;
     }
     std::unique_ptr<cmMakefileTargetGenerator> tg(
@@ -137,7 +137,7 @@
   std::map<std::string, LocalObjectInfo>& localObjectFiles)
 {
   for (const auto& gt : this->GetGeneratorTargets()) {
-    if (gt->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+    if (!gt->CanCompileSources()) {
       continue;
     }
     std::vector<cmSourceFile const*> objectSources;
@@ -950,7 +950,7 @@
       std::string launcher;
       // Short-circuit if there is no launcher.
       const char* val = this->GetRuleLauncher(target, "RULE_LAUNCH_CUSTOM");
-      if (val && *val) {
+      if (cmNonempty(val)) {
         // Expand rule variables referenced in the given launcher command.
         cmRulePlaceholderExpander::RuleVariables vars;
         vars.CMTargetName = target->GetName().c_str();
@@ -1744,7 +1744,7 @@
       return false;
     }
     // If it's an absolute path, check if it starts with the source
-    // direcotory:
+    // directory:
     return (
       !(IsInDirectory(SourceDir, path) || IsInDirectory(BinaryDir, path)));
   }
@@ -1807,7 +1807,7 @@
     std::string cidVar =
       cmStrCat("CMAKE_", implicitLang.first, "_COMPILER_ID");
     const char* cid = this->Makefile->GetDefinition(cidVar);
-    if (cid && *cid) {
+    if (cmNonempty(cid)) {
       cmakefileStream << "set(CMAKE_" << implicitLang.first
                       << "_COMPILER_ID \"" << cid << "\")\n";
     }
diff --git a/Source/cmLocalVisualStudio10Generator.cxx b/Source/cmLocalVisualStudio10Generator.cxx
index 9076e26..6c7d6c6 100644
--- a/Source/cmLocalVisualStudio10Generator.cxx
+++ b/Source/cmLocalVisualStudio10Generator.cxx
@@ -69,7 +69,7 @@
 void cmLocalVisualStudio10Generator::GenerateTargetsDepthFirst(
   cmGeneratorTarget* target, std::vector<cmGeneratorTarget*>& remaining)
 {
-  if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+  if (!target->IsInBuildSystem()) {
     return;
   }
   // Find this target in the list of remaining targets.
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index 5d50e2d..50ffe8d 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -66,7 +66,7 @@
   // Now create GUIDs for targets
   const auto& tgts = this->GetGeneratorTargets();
   for (const auto& l : tgts) {
-    if (l->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+    if (!l->IsInBuildSystem()) {
       continue;
     }
     cmProp path = l->GetProperty("EXTERNAL_MSPROJECT");
@@ -129,7 +129,7 @@
 
   // Create the project file for each target.
   for (const auto& l : tgts) {
-    if (l->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+    if (!l->IsInBuildSystem()) {
       continue;
     }
     // INCLUDE_EXTERNAL_MSPROJECT command only affects the workspace
@@ -629,9 +629,10 @@
       break;
     case cmStateEnums::UTILITY:
     case cmStateEnums::GLOBAL_TARGET:
+    case cmStateEnums::INTERFACE_LIBRARY:
       configType = "10";
       CM_FALLTHROUGH;
-    default:
+    case cmStateEnums::UNKNOWN_LIBRARY:
       targetBuilds = false;
       break;
   }
@@ -1331,8 +1332,8 @@
                                                     const std::string& libName,
                                                     cmGeneratorTarget* target)
 {
-  std::vector<std::string> configs;
-  this->Makefile->GetConfigurations(configs);
+  std::vector<std::string> configs =
+    this->Makefile->GetGeneratorConfigs(cmMakefile::ExcludeEmptyConfig);
 
   // We may be modifying the source groups temporarily, so make a copy.
   std::vector<cmSourceGroup> sourceGroups = this->Makefile->GetSourceGroups();
@@ -1580,8 +1581,9 @@
 std::string cmLocalVisualStudio7Generator::ComputeLongestObjectDirectory(
   cmGeneratorTarget const* target) const
 {
-  std::vector<std::string> configs;
-  target->Target->GetMakefile()->GetConfigurations(configs);
+  std::vector<std::string> configs =
+    target->Target->GetMakefile()->GetGeneratorConfigs(
+      cmMakefile::ExcludeEmptyConfig);
 
   // Compute the maximum length configuration name.
   std::string config_max;
@@ -1637,7 +1639,8 @@
     std::string source = sf->GetFullPath();
 
     if (source != libName || target->GetType() == cmStateEnums::UTILITY ||
-        target->GetType() == cmStateEnums::GLOBAL_TARGET) {
+        target->GetType() == cmStateEnums::GLOBAL_TARGET ||
+        target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
       // Look up the source kind and configs.
       std::map<cmSourceFile const*, size_t>::const_iterator map_it =
         sources.Index.find(sf);
@@ -1936,6 +1939,7 @@
   const char* keyword = p ? p->c_str() : "Console Application";
   const char* projectType = 0;
   switch (target->GetType()) {
+    case cmStateEnums::OBJECT_LIBRARY:
     case cmStateEnums::STATIC_LIBRARY:
       projectType = "typeStaticLibrary";
       if (keyword) {
@@ -1957,7 +1961,8 @@
       break;
     case cmStateEnums::UTILITY:
     case cmStateEnums::GLOBAL_TARGET:
-    default:
+    case cmStateEnums::INTERFACE_LIBRARY:
+    case cmStateEnums::UNKNOWN_LIBRARY:
       break;
   }
   if (projectType) {
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index db5cee9..5e1f070 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -34,6 +34,7 @@
 #include "cmExecutionStatus.h"
 #include "cmExpandedCommandArgument.h" // IWYU pragma: keep
 #include "cmExportBuildFileGenerator.h"
+#include "cmFSPermissions.h"
 #include "cmFileLockPool.h"
 #include "cmFunctionBlocker.h"
 #include "cmGeneratedFileStream.h"
@@ -68,6 +69,8 @@
 
 class cmMessenger;
 
+using namespace cmFSPermissions;
+
 cmDirectoryId::cmDirectoryId(std::string s)
   : String(std::move(s))
 {
@@ -82,7 +85,6 @@
 {
   this->IsSourceFileTryCompile = false;
 
-  this->WarnUnused = this->GetCMakeInstance()->GetWarnUnused();
   this->CheckSystemVars = this->GetCMakeInstance()->GetCheckSystemVars();
 
   this->SuppressSideEffects = false;
@@ -194,7 +196,7 @@
   std::string env;
   cmSystemTools::GetEnv(varName, env);
 
-  bool const haveVar = var && *var;
+  bool const haveVar = cmNonempty(var);
   bool const haveEnv = !env.empty();
   if ((haveVar || haveEnv) && this->WarnedCMP0074.insert(varName).second) {
     std::ostringstream w;
@@ -750,7 +752,6 @@
       break;
     }
   }
-  this->CheckForUnusedVariables();
 
   this->AddDefinition("CMAKE_PARENT_LIST_FILE", currentParentFile);
   this->AddDefinition("CMAKE_CURRENT_LIST_FILE", currentFile);
@@ -1434,8 +1435,8 @@
   if (polSt == cmPolicies::WARN || polSt == cmPolicies::OLD) {
     cmProp p = parent->GetProperty("COMPILE_DEFINITIONS");
     this->SetProperty("COMPILE_DEFINITIONS", p ? p->c_str() : nullptr);
-    std::vector<std::string> configs;
-    this->GetConfigurations(configs);
+    std::vector<std::string> configs =
+      this->GetGeneratorConfigs(cmMakefile::ExcludeEmptyConfig);
     for (std::string const& config : configs) {
       std::string defPropName =
         cmStrCat("COMPILE_DEFINITIONS_", cmSystemTools::UpperCase(config));
@@ -1513,8 +1514,6 @@
 #endif
 
   this->PopLoopBlockBarrier();
-
-  this->CheckForUnusedVariables();
 }
 
 void cmMakefile::PushMacroScope(std::string const& fileName,
@@ -1661,7 +1660,8 @@
         this->SetCheckCMP0000(true);
 
         // Implicitly set the version for the user.
-        this->SetPolicyVersion("2.4", std::string());
+        cmPolicies::ApplyPolicyVersion(this, 2, 4, 0,
+                                       cmPolicies::WarnCompat::Off);
       }
     }
     bool hasProject = false;
@@ -1860,9 +1860,6 @@
 
 void cmMakefile::AddDefinition(const std::string& name, cm::string_view value)
 {
-  if (this->VariableInitialized(name)) {
-    this->LogUnused("changing definition", name);
-  }
   this->StateSnapshot.SetDefinition(name, value);
 
 #ifndef CMAKE_BOOTSTRAP
@@ -1923,16 +1920,6 @@
   this->StateSnapshot.RemoveDefinition(name);
 }
 
-void cmMakefile::CheckForUnusedVariables() const
-{
-  if (!this->WarnUnused) {
-    return;
-  }
-  for (const std::string& key : this->StateSnapshot.UnusedKeys()) {
-    this->LogUnused("out of scope", key);
-  }
-}
-
 void cmMakefile::MarkVariableAsUsed(const std::string& var)
 {
   this->StateSnapshot.GetDefinition(var);
@@ -1960,29 +1947,8 @@
   }
 }
 
-void cmMakefile::LogUnused(const char* reason, const std::string& name) const
-{
-  if (this->WarnUnused) {
-    std::string path;
-    if (!this->ExecutionStatusStack.empty()) {
-      path = this->GetExecutionContext().FilePath;
-    } else {
-      path = cmStrCat(this->GetCurrentSourceDirectory(), "/CMakeLists.txt");
-    }
-
-    if (this->CheckSystemVars || this->IsProjectFile(path.c_str())) {
-      std::ostringstream msg;
-      msg << "unused variable (" << reason << ") \'" << name << "\'";
-      this->IssueMessage(MessageType::AUTHOR_WARNING, msg.str());
-    }
-  }
-}
-
 void cmMakefile::RemoveDefinition(const std::string& name)
 {
-  if (this->VariableInitialized(name)) {
-    this->LogUnused("unsetting", name);
-  }
   this->StateSnapshot.RemoveDefinition(name);
 #ifndef CMAKE_BOOTSTRAP
   cmVariableWatch* vv = this->GetVariableWatch();
@@ -2555,8 +2521,7 @@
 
 bool cmMakefile::IsOn(const std::string& name) const
 {
-  const char* value = this->GetDefinition(name);
-  return cmIsOn(value);
+  return cmIsOn(this->GetDef(name));
 }
 
 bool cmMakefile::IsSet(const std::string& name) const
@@ -3287,25 +3252,28 @@
   }
 }
 
-std::string cmMakefile::GetConfigurations(std::vector<std::string>& configs,
-                                          bool singleConfig) const
+std::string cmMakefile::GetDefaultConfiguration() const
 {
   if (this->GetGlobalGenerator()->IsMultiConfig()) {
-    this->GetDefExpandList("CMAKE_CONFIGURATION_TYPES", configs);
-    return "";
+    return std::string{};
   }
-  const std::string& buildType = this->GetSafeDefinition("CMAKE_BUILD_TYPE");
-  if (singleConfig && !buildType.empty()) {
-    configs.push_back(buildType);
-  }
-  return buildType;
+  return this->GetSafeDefinition("CMAKE_BUILD_TYPE");
 }
 
-std::vector<std::string> cmMakefile::GetGeneratorConfigs() const
+std::vector<std::string> cmMakefile::GetGeneratorConfigs(
+  GeneratorConfigQuery mode) const
 {
   std::vector<std::string> configs;
-  GetConfigurations(configs);
-  if (configs.empty()) {
+  if (this->GetGlobalGenerator()->IsMultiConfig() ||
+      mode == cmMakefile::OnlyMultiConfig) {
+    this->GetDefExpandList("CMAKE_CONFIGURATION_TYPES", configs);
+  } else {
+    const std::string& buildType = this->GetSafeDefinition("CMAKE_BUILD_TYPE");
+    if (!buildType.empty()) {
+      configs.emplace_back(buildType);
+    }
+  }
+  if (mode == cmMakefile::IncludeEmptyConfig && configs.empty()) {
     configs.emplace_back();
   }
   return configs;
@@ -3725,7 +3693,7 @@
   if (cmakeArgs) {
     // FIXME: Workaround to ignore unused CLI variables in try-compile.
     //
-    // Ideally we should use SetArgs to honor options like --warn-unused-vars.
+    // Ideally we should use SetArgs for options like --no-warn-unused-cli.
     // However, there is a subtle problem when certain arguments are passed to
     // a macro wrapping around try_compile or try_run that does not escape
     // semicolons in its parameters but just passes ${ARGV} or ${ARGN}.  In
@@ -3744,7 +3712,7 @@
     // the value VAR=a is sufficient for the try_compile or try_run to get the
     // correct result.  Calling SetArgs here would break such projects that
     // previously built.  Instead we work around the issue by never reporting
-    // unused arguments and ignoring options such as --warn-unused-vars.
+    // unused arguments and ignoring options such as --no-warn-unused-cli.
     cm.SetWarnUnusedCli(false);
     // cm.SetArgs(*cmakeArgs, true);
 
@@ -3998,6 +3966,7 @@
 int cmMakefile::ConfigureFile(const std::string& infile,
                               const std::string& outfile, bool copyonly,
                               bool atOnly, bool escapeQuotes,
+                              bool use_source_permissions,
                               cmNewLineStyle newLine)
 {
   int res = 1;
@@ -4021,7 +3990,13 @@
   this->AddCMakeOutputFile(soutfile);
 
   mode_t perm = 0;
-  cmSystemTools::GetPermissions(sinfile, perm);
+  if (!use_source_permissions) {
+    perm = perm | mode_owner_read | mode_owner_write | mode_group_read |
+      mode_world_read;
+  } else {
+    cmSystemTools::GetPermissions(sinfile, perm);
+  }
+
   std::string::size_type pos = soutfile.rfind('/');
   if (pos != std::string::npos) {
     std::string path = soutfile.substr(0, pos);
@@ -4030,6 +4005,13 @@
 
   if (copyonly) {
     if (!cmSystemTools::CopyFileIfDifferent(sinfile, soutfile)) {
+      this->IssueMessage(MessageType::FATAL_ERROR,
+                         cmSystemTools::GetLastSystemError());
+      return 0;
+    }
+    if (!cmSystemTools::SetPermissions(soutfile, perm)) {
+      this->IssueMessage(MessageType::FATAL_ERROR,
+                         cmSystemTools::GetLastSystemError());
       return 0;
     }
   } else {
@@ -4080,9 +4062,15 @@
     fin.close();
     fout.close();
     if (!cmSystemTools::CopyFileIfDifferent(tempOutputFile, soutfile)) {
+      this->IssueMessage(MessageType::FATAL_ERROR,
+                         cmSystemTools::GetLastSystemError());
       res = 0;
     } else {
-      cmSystemTools::SetPermissions(soutfile, perm);
+      if (!cmSystemTools::SetPermissions(soutfile, perm)) {
+        this->IssueMessage(MessageType::FATAL_ERROR,
+                           cmSystemTools::GetLastSystemError());
+        res = 0;
+      }
     }
     cmSystemTools::RemoveFile(tempOutputFile);
   }
@@ -4127,8 +4115,7 @@
 
 bool cmMakefile::GetPropertyAsBool(const std::string& prop) const
 {
-  cmProp p = this->GetProperty(prop);
-  return p && cmIsOn(*p);
+  return cmIsOn(this->GetProperty(prop));
 }
 
 std::vector<std::string> cmMakefile::GetPropertyKeys() const
@@ -4240,8 +4227,6 @@
 
   this->PopLoopBlockBarrier();
 
-  this->CheckForUnusedVariables();
-
   this->PopSnapshot();
 }
 
@@ -4557,7 +4542,7 @@
 
   // Deprecate old policies, especially those that require a lot
   // of code to maintain the old behavior.
-  if (status == cmPolicies::OLD && id <= cmPolicies::CMP0071 &&
+  if (status == cmPolicies::OLD && id <= cmPolicies::CMP0072 &&
       !(this->GetCMakeInstance()->GetIsInTryCompile() &&
         (
           // Policies set by cmCoreTryCompile::TryCompileCode.
@@ -4599,7 +4584,7 @@
   // cmStateSnapshot manages nested policy scopes within it.
   // Since the scope corresponding to the snapshot is closing,
   // reject any still-open nested policy scopes with an error.
-  while (!this->StateSnapshot.CanPopPolicyScope()) {
+  while (this->StateSnapshot.CanPopPolicyScope()) {
     if (reportError) {
       this->IssueMessage(MessageType::FATAL_ERROR,
                          "cmake_policy PUSH without matching POP");
@@ -4615,7 +4600,8 @@
 bool cmMakefile::SetPolicyVersion(std::string const& version_min,
                                   std::string const& version_max)
 {
-  return cmPolicies::ApplyPolicyVersion(this, version_min, version_max);
+  return cmPolicies::ApplyPolicyVersion(this, version_min, version_max,
+                                        cmPolicies::WarnCompat::On);
 }
 
 bool cmMakefile::HasCMP0054AlreadyBeenReported(
@@ -4651,674 +4637,6 @@
   return ignoreErrors;
 }
 
-#define FEATURE_STRING(F) , #F
-static const char* const C_FEATURES[] = { nullptr FOR_EACH_C_FEATURE(
-  FEATURE_STRING) };
-
-static const char* const CXX_FEATURES[] = { nullptr FOR_EACH_CXX_FEATURE(
-  FEATURE_STRING) };
-
-static const char* const CUDA_FEATURES[] = { nullptr FOR_EACH_CUDA_FEATURE(
-  FEATURE_STRING) };
-#undef FEATURE_STRING
-
-static const char* const C_STANDARDS[] = { "90", "99", "11" };
-static const char* const CXX_STANDARDS[] = { "98", "11", "14", "17", "20" };
-static const char* const CUDA_STANDARDS[] = { "03", "11", "14", "17", "20" };
-
-bool cmMakefile::AddRequiredTargetFeature(cmTarget* target,
-                                          const std::string& feature,
-                                          std::string* error) const
-{
-  if (cmGeneratorExpression::Find(feature) != std::string::npos) {
-    target->AppendProperty("COMPILE_FEATURES", feature);
-    return true;
-  }
-
-  std::string lang;
-  if (!this->CompileFeatureKnown(target, feature, lang, error)) {
-    return false;
-  }
-
-  const char* features = this->CompileFeaturesAvailable(lang, error);
-  if (!features) {
-    return false;
-  }
-
-  std::vector<std::string> availableFeatures = cmExpandedList(features);
-  if (!cm::contains(availableFeatures, feature)) {
-    std::ostringstream e;
-    e << "The compiler feature \"" << feature << "\" is not known to " << lang
-      << " compiler\n\""
-      << this->GetDefinition("CMAKE_" + lang + "_COMPILER_ID")
-      << "\"\nversion "
-      << this->GetDefinition("CMAKE_" + lang + "_COMPILER_VERSION") << ".";
-    if (error) {
-      *error = e.str();
-    } else {
-      this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR, e.str(),
-                                             this->Backtrace);
-    }
-    return false;
-  }
-
-  target->AppendProperty("COMPILE_FEATURES", feature);
-
-  if (lang == "C" || lang == "OBJC") {
-    return this->AddRequiredTargetCFeature(target, feature, lang, error);
-  }
-  if (lang == "CUDA") {
-    return this->AddRequiredTargetCudaFeature(target, feature, lang, error);
-  }
-  return this->AddRequiredTargetCxxFeature(target, feature, lang, error);
-}
-
-bool cmMakefile::CompileFeatureKnown(cmTarget const* target,
-                                     const std::string& feature,
-                                     std::string& lang,
-                                     std::string* error) const
-{
-  assert(cmGeneratorExpression::Find(feature) == std::string::npos);
-
-  bool isCFeature =
-    std::find_if(cm::cbegin(C_FEATURES) + 1, cm::cend(C_FEATURES),
-                 cmStrCmp(feature)) != cm::cend(C_FEATURES);
-  if (isCFeature) {
-    lang = "C";
-    return true;
-  }
-  bool isCxxFeature =
-    std::find_if(cm::cbegin(CXX_FEATURES) + 1, cm::cend(CXX_FEATURES),
-                 cmStrCmp(feature)) != cm::cend(CXX_FEATURES);
-  if (isCxxFeature) {
-    lang = "CXX";
-    return true;
-  }
-  bool isCudaFeature =
-    std::find_if(cm::cbegin(CUDA_FEATURES) + 1, cm::cend(CUDA_FEATURES),
-                 cmStrCmp(feature)) != cm::cend(CUDA_FEATURES);
-  if (isCudaFeature) {
-    lang = "CUDA";
-    return true;
-  }
-  std::ostringstream e;
-  if (error) {
-    e << "specified";
-  } else {
-    e << "Specified";
-  }
-  e << " unknown feature \"" << feature
-    << "\" for "
-       "target \""
-    << target->GetName() << "\".";
-  if (error) {
-    *error = e.str();
-  } else {
-    this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR, e.str(),
-                                           this->Backtrace);
-  }
-  return false;
-}
-
-const char* cmMakefile::CompileFeaturesAvailable(const std::string& lang,
-                                                 std::string* error) const
-{
-  if (!this->GlobalGenerator->GetLanguageEnabled(lang)) {
-    std::ostringstream e;
-    if (error) {
-      e << "cannot";
-    } else {
-      e << "Cannot";
-    }
-    e << " use features from non-enabled language " << lang;
-    if (error) {
-      *error = e.str();
-    } else {
-      this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR, e.str(),
-                                             this->Backtrace);
-    }
-    return nullptr;
-  }
-
-  const char* featuresKnown =
-    this->GetDefinition("CMAKE_" + lang + "_COMPILE_FEATURES");
-
-  if (!featuresKnown || !*featuresKnown) {
-    std::ostringstream e;
-    if (error) {
-      e << "no";
-    } else {
-      e << "No";
-    }
-    e << " known features for " << lang << " compiler\n\""
-      << this->GetSafeDefinition("CMAKE_" + lang + "_COMPILER_ID")
-      << "\"\nversion "
-      << this->GetSafeDefinition("CMAKE_" + lang + "_COMPILER_VERSION") << ".";
-    if (error) {
-      *error = e.str();
-    } else {
-      this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR, e.str(),
-                                             this->Backtrace);
-    }
-    return nullptr;
-  }
-  return featuresKnown;
-}
-
-bool cmMakefile::HaveStandardAvailable(cmTarget const* target,
-                                       std::string const& lang,
-                                       const std::string& feature) const
-{
-  if (lang == "C" || lang == "OBJC") {
-    return this->HaveCStandardAvailable(target, feature, lang);
-  }
-  if (lang == "CUDA") {
-    return this->HaveCudaStandardAvailable(target, feature, lang);
-  }
-  return this->HaveCxxStandardAvailable(target, feature, lang);
-}
-
-bool cmMakefile::HaveCStandardAvailable(cmTarget const* target,
-                                        const std::string& feature,
-                                        std::string const& lang) const
-{
-  cmProp defaultCStandard =
-    this->GetDef(cmStrCat("CMAKE_", lang, "_STANDARD_DEFAULT"));
-  if (!defaultCStandard) {
-    this->IssueMessage(
-      MessageType::INTERNAL_ERROR,
-      cmStrCat("CMAKE_", lang,
-               "_STANDARD_DEFAULT is not set.  COMPILE_FEATURES support "
-               "not fully configured for this compiler."));
-    // Return true so the caller does not try to lookup the default standard.
-    return true;
-  }
-  if (std::find_if(cm::cbegin(C_STANDARDS), cm::cend(C_STANDARDS),
-                   cmStrCmp(*defaultCStandard)) == cm::cend(C_STANDARDS)) {
-    const std::string e = cmStrCat("The CMAKE_", lang,
-                                   "_STANDARD_DEFAULT variable contains an "
-                                   "invalid value: \"",
-                                   *defaultCStandard, "\".");
-    this->IssueMessage(MessageType::INTERNAL_ERROR, e);
-    return false;
-  }
-
-  bool needC90 = false;
-  bool needC99 = false;
-  bool needC11 = false;
-
-  this->CheckNeededCLanguage(feature, lang, needC90, needC99, needC11);
-
-  cmProp existingCStandard = target->GetProperty(cmStrCat(lang, "_STANDARD"));
-  if (!existingCStandard) {
-    existingCStandard = defaultCStandard;
-  }
-
-  if (std::find_if(cm::cbegin(C_STANDARDS), cm::cend(C_STANDARDS),
-                   cmStrCmp(*existingCStandard)) == cm::cend(C_STANDARDS)) {
-    const std::string e = cmStrCat(
-      "The ", lang, "_STANDARD property on target \"", target->GetName(),
-      "\" contained an invalid value: \"", *existingCStandard, "\".");
-    this->IssueMessage(MessageType::FATAL_ERROR, e);
-    return false;
-  }
-
-  const char* const* existingCIt = existingCStandard
-    ? std::find_if(cm::cbegin(C_STANDARDS), cm::cend(C_STANDARDS),
-                   cmStrCmp(*existingCStandard))
-    : cm::cend(C_STANDARDS);
-
-  if (needC11 && existingCStandard &&
-      existingCIt < std::find_if(cm::cbegin(C_STANDARDS),
-                                 cm::cend(C_STANDARDS), cmStrCmp("11"))) {
-    return false;
-  }
-  if (needC99 && existingCStandard &&
-      existingCIt < std::find_if(cm::cbegin(C_STANDARDS),
-                                 cm::cend(C_STANDARDS), cmStrCmp("99"))) {
-    return false;
-  }
-  if (needC90 && existingCStandard &&
-      existingCIt < std::find_if(cm::cbegin(C_STANDARDS),
-                                 cm::cend(C_STANDARDS), cmStrCmp("90"))) {
-    return false;
-  }
-  return true;
-}
-
-bool cmMakefile::IsLaterStandard(std::string const& lang,
-                                 std::string const& lhs,
-                                 std::string const& rhs)
-{
-  if (lang == "C" || lang == "OBJC") {
-    const char* const* rhsIt = std::find_if(
-      cm::cbegin(C_STANDARDS), cm::cend(C_STANDARDS), cmStrCmp(rhs));
-
-    return std::find_if(rhsIt, cm::cend(C_STANDARDS), cmStrCmp(lhs)) !=
-      cm::cend(C_STANDARDS);
-  }
-  if (lang == "CUDA") {
-    const char* const* rhsIt = std::find_if(
-      cm::cbegin(CUDA_STANDARDS), cm::cend(CUDA_STANDARDS), cmStrCmp(rhs));
-
-    return std::find_if(rhsIt, cm::cend(CUDA_STANDARDS), cmStrCmp(lhs)) !=
-      cm::cend(CUDA_STANDARDS);
-  }
-
-  const char* const* rhsIt = std::find_if(
-    cm::cbegin(CXX_STANDARDS), cm::cend(CXX_STANDARDS), cmStrCmp(rhs));
-
-  return std::find_if(rhsIt, cm::cend(CXX_STANDARDS), cmStrCmp(lhs)) !=
-    cm::cend(CXX_STANDARDS);
-}
-
-bool cmMakefile::HaveCxxStandardAvailable(cmTarget const* target,
-                                          const std::string& feature,
-                                          std::string const& lang) const
-{
-  cmProp defaultCxxStandard =
-    this->GetDef(cmStrCat("CMAKE_", lang, "_STANDARD_DEFAULT"));
-  if (!defaultCxxStandard) {
-    this->IssueMessage(
-      MessageType::INTERNAL_ERROR,
-      cmStrCat("CMAKE_", lang,
-               "_STANDARD_DEFAULT is not set.  COMPILE_FEATURES support "
-               "not fully configured for this compiler."));
-    // Return true so the caller does not try to lookup the default standard.
-    return true;
-  }
-  if (std::find_if(cm::cbegin(CXX_STANDARDS), cm::cend(CXX_STANDARDS),
-                   cmStrCmp(*defaultCxxStandard)) == cm::cend(CXX_STANDARDS)) {
-    const std::string e =
-      cmStrCat("The CMAKE_", lang, "_STANDARD_DEFAULT variable contains an ",
-               "invalid value: \"", *defaultCxxStandard, "\".");
-    this->IssueMessage(MessageType::INTERNAL_ERROR, e);
-    return false;
-  }
-
-  bool needCxx98 = false;
-  bool needCxx11 = false;
-  bool needCxx14 = false;
-  bool needCxx17 = false;
-  bool needCxx20 = false;
-  this->CheckNeededCxxLanguage(feature, lang, needCxx98, needCxx11, needCxx14,
-                               needCxx17, needCxx20);
-
-  cmProp existingCxxStandard =
-    target->GetProperty(cmStrCat(lang, "_STANDARD"));
-  if (!existingCxxStandard) {
-    existingCxxStandard = defaultCxxStandard;
-  }
-
-  const char* const* existingCxxLevel =
-    std::find_if(cm::cbegin(CXX_STANDARDS), cm::cend(CXX_STANDARDS),
-                 cmStrCmp(*existingCxxStandard));
-  if (existingCxxLevel == cm::cend(CXX_STANDARDS)) {
-    const std::string e = cmStrCat(
-      "The ", lang, "_STANDARD property on target \"", target->GetName(),
-      "\" contained an invalid value: \"", *existingCxxStandard, "\".");
-    this->IssueMessage(MessageType::FATAL_ERROR, e);
-    return false;
-  }
-
-  /* clang-format off */
-  const char* const* needCxxLevel =
-    needCxx20 ? &CXX_STANDARDS[4]
-    : needCxx17 ? &CXX_STANDARDS[3]
-    : needCxx14 ? &CXX_STANDARDS[2]
-    : needCxx11 ? &CXX_STANDARDS[1]
-    : needCxx98 ? &CXX_STANDARDS[0]
-    : nullptr;
-  /* clang-format on */
-
-  return !needCxxLevel || needCxxLevel <= existingCxxLevel;
-}
-
-void cmMakefile::CheckNeededCxxLanguage(const std::string& feature,
-                                        std::string const& lang,
-                                        bool& needCxx98, bool& needCxx11,
-                                        bool& needCxx14, bool& needCxx17,
-                                        bool& needCxx20) const
-{
-  if (const char* propCxx98 =
-        this->GetDefinition(cmStrCat("CMAKE_", lang, "98_COMPILE_FEATURES"))) {
-    std::vector<std::string> props = cmExpandedList(propCxx98);
-    needCxx98 = cm::contains(props, feature);
-  }
-  if (const char* propCxx11 =
-        this->GetDefinition(cmStrCat("CMAKE_", lang, "11_COMPILE_FEATURES"))) {
-    std::vector<std::string> props = cmExpandedList(propCxx11);
-    needCxx11 = cm::contains(props, feature);
-  }
-  if (const char* propCxx14 =
-        this->GetDefinition(cmStrCat("CMAKE_", lang, "14_COMPILE_FEATURES"))) {
-    std::vector<std::string> props = cmExpandedList(propCxx14);
-    needCxx14 = cm::contains(props, feature);
-  }
-  if (const char* propCxx17 =
-        this->GetDefinition(cmStrCat("CMAKE_", lang, "17_COMPILE_FEATURES"))) {
-    std::vector<std::string> props = cmExpandedList(propCxx17);
-    needCxx17 = cm::contains(props, feature);
-  }
-  if (const char* propCxx20 =
-        this->GetDefinition(cmStrCat("CMAKE_", lang, "20_COMPILE_FEATURES"))) {
-    std::vector<std::string> props = cmExpandedList(propCxx20);
-    needCxx20 = cm::contains(props, feature);
-  }
-}
-
-bool cmMakefile::AddRequiredTargetCxxFeature(cmTarget* target,
-                                             const std::string& feature,
-                                             std::string const& lang,
-                                             std::string* error) const
-{
-  bool needCxx98 = false;
-  bool needCxx11 = false;
-  bool needCxx14 = false;
-  bool needCxx17 = false;
-  bool needCxx20 = false;
-
-  this->CheckNeededCxxLanguage(feature, lang, needCxx98, needCxx11, needCxx14,
-                               needCxx17, needCxx20);
-
-  cmProp existingCxxStandard =
-    target->GetProperty(cmStrCat(lang, "_STANDARD"));
-  if (existingCxxStandard == nullptr) {
-    cmProp defaultCxxStandard =
-      this->GetDef(cmStrCat("CMAKE_", lang, "_STANDARD_DEFAULT"));
-    if (defaultCxxStandard && !defaultCxxStandard->empty()) {
-      existingCxxStandard = defaultCxxStandard;
-    }
-  }
-  const char* const* existingCxxLevel = nullptr;
-  if (existingCxxStandard) {
-    existingCxxLevel =
-      std::find_if(cm::cbegin(CXX_STANDARDS), cm::cend(CXX_STANDARDS),
-                   cmStrCmp(*existingCxxStandard));
-    if (existingCxxLevel == cm::cend(CXX_STANDARDS)) {
-      const std::string e = cmStrCat(
-        "The ", lang, "_STANDARD property on target \"", target->GetName(),
-        "\" contained an invalid value: \"", *existingCxxStandard, "\".");
-      if (error) {
-        *error = e;
-      } else {
-        this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR, e,
-                                               this->Backtrace);
-      }
-      return false;
-    }
-  }
-
-  /* clang-format off */
-  const char* const* needCxxLevel =
-    needCxx20 ? &CXX_STANDARDS[4]
-    : needCxx17 ? &CXX_STANDARDS[3]
-    : needCxx14 ? &CXX_STANDARDS[2]
-    : needCxx11 ? &CXX_STANDARDS[1]
-    : needCxx98 ? &CXX_STANDARDS[0]
-    : nullptr;
-  /* clang-format on */
-
-  if (needCxxLevel) {
-    // Ensure the C++ language level is high enough to support
-    // the needed C++ features.
-    if (!existingCxxLevel || existingCxxLevel < needCxxLevel) {
-      target->SetProperty(cmStrCat(lang, "_STANDARD"), *needCxxLevel);
-    }
-  }
-
-  return true;
-}
-
-bool cmMakefile::HaveCudaStandardAvailable(cmTarget const* target,
-                                           const std::string& feature,
-                                           std::string const& lang) const
-{
-  cmProp defaultCudaStandard =
-    this->GetDef(cmStrCat("CMAKE_", lang, "_STANDARD_DEFAULT"));
-  if (!defaultCudaStandard) {
-    this->IssueMessage(
-      MessageType::INTERNAL_ERROR,
-      cmStrCat("CMAKE_", lang,
-               "_STANDARD_DEFAULT is not set.  COMPILE_FEATURES support "
-               "not fully configured for this compiler."));
-    // Return true so the caller does not try to lookup the default standard.
-    return true;
-  }
-  if (std::find_if(cm::cbegin(CUDA_STANDARDS), cm::cend(CUDA_STANDARDS),
-                   cmStrCmp(*defaultCudaStandard)) ==
-      cm::cend(CUDA_STANDARDS)) {
-    const std::string e =
-      cmStrCat("The CMAKE_", lang, "_STANDARD_DEFAULT variable contains an ",
-               "invalid value: \"", *defaultCudaStandard, "\".");
-    this->IssueMessage(MessageType::INTERNAL_ERROR, e);
-    return false;
-  }
-
-  bool needCuda03 = false;
-  bool needCuda11 = false;
-  bool needCuda14 = false;
-  bool needCuda17 = false;
-  bool needCuda20 = false;
-  this->CheckNeededCudaLanguage(feature, lang, needCuda03, needCuda11,
-                                needCuda14, needCuda17, needCuda20);
-
-  cmProp existingCudaStandard =
-    target->GetProperty(cmStrCat(lang, "_STANDARD"));
-  if (!existingCudaStandard) {
-    existingCudaStandard = defaultCudaStandard;
-  }
-
-  const char* const* existingCudaLevel =
-    std::find_if(cm::cbegin(CUDA_STANDARDS), cm::cend(CUDA_STANDARDS),
-                 cmStrCmp(*existingCudaStandard));
-  if (existingCudaLevel == cm::cend(CUDA_STANDARDS)) {
-    const std::string e = cmStrCat(
-      "The ", lang, "_STANDARD property on target \"", target->GetName(),
-      "\" contained an invalid value: \"", *existingCudaStandard, "\".");
-    this->IssueMessage(MessageType::FATAL_ERROR, e);
-    return false;
-  }
-
-  /* clang-format off */
-  const char* const* needCudaLevel =
-    needCuda20 ? &CUDA_STANDARDS[4]
-    : needCuda17 ? &CUDA_STANDARDS[3]
-    : needCuda14 ? &CUDA_STANDARDS[2]
-    : needCuda11 ? &CUDA_STANDARDS[1]
-    : needCuda03 ? &CUDA_STANDARDS[0]
-    : nullptr;
-  /* clang-format on */
-
-  return !needCudaLevel || needCudaLevel <= existingCudaLevel;
-}
-
-void cmMakefile::CheckNeededCudaLanguage(const std::string& feature,
-                                         std::string const& lang,
-                                         bool& needCuda03, bool& needCuda11,
-                                         bool& needCuda14, bool& needCuda17,
-                                         bool& needCuda20) const
-{
-  if (const char* propCuda03 =
-        this->GetDefinition(cmStrCat("CMAKE_", lang, "03_COMPILE_FEATURES"))) {
-    std::vector<std::string> props = cmExpandedList(propCuda03);
-    needCuda03 = cm::contains(props, feature);
-  }
-  if (const char* propCuda11 =
-        this->GetDefinition(cmStrCat("CMAKE_", lang, "11_COMPILE_FEATURES"))) {
-    std::vector<std::string> props = cmExpandedList(propCuda11);
-    needCuda11 = cm::contains(props, feature);
-  }
-  if (const char* propCuda14 =
-        this->GetDefinition(cmStrCat("CMAKE_", lang, "14_COMPILE_FEATURES"))) {
-    std::vector<std::string> props = cmExpandedList(propCuda14);
-    needCuda14 = cm::contains(props, feature);
-  }
-  if (const char* propCuda17 =
-        this->GetDefinition(cmStrCat("CMAKE_", lang, "17_COMPILE_FEATURES"))) {
-    std::vector<std::string> props = cmExpandedList(propCuda17);
-    needCuda17 = cm::contains(props, feature);
-  }
-  if (const char* propCuda20 =
-        this->GetDefinition(cmStrCat("CMAKE_", lang, "20_COMPILE_FEATURES"))) {
-    std::vector<std::string> props = cmExpandedList(propCuda20);
-    needCuda20 = cm::contains(props, feature);
-  }
-}
-
-bool cmMakefile::AddRequiredTargetCudaFeature(cmTarget* target,
-                                              const std::string& feature,
-                                              std::string const& lang,
-                                              std::string* error) const
-{
-  bool needCuda03 = false;
-  bool needCuda11 = false;
-  bool needCuda14 = false;
-  bool needCuda17 = false;
-  bool needCuda20 = false;
-
-  this->CheckNeededCudaLanguage(feature, lang, needCuda03, needCuda11,
-                                needCuda14, needCuda17, needCuda20);
-
-  cmProp existingCudaStandard =
-    target->GetProperty(cmStrCat(lang, "_STANDARD"));
-  if (existingCudaStandard == nullptr) {
-    cmProp defaultCudaStandard =
-      this->GetDef(cmStrCat("CMAKE_", lang, "_STANDARD_DEFAULT"));
-    if (defaultCudaStandard && !defaultCudaStandard->empty()) {
-      existingCudaStandard = defaultCudaStandard;
-    }
-  }
-  const char* const* existingCudaLevel = nullptr;
-  if (existingCudaStandard) {
-    existingCudaLevel =
-      std::find_if(cm::cbegin(CUDA_STANDARDS), cm::cend(CUDA_STANDARDS),
-                   cmStrCmp(*existingCudaStandard));
-    if (existingCudaLevel == cm::cend(CUDA_STANDARDS)) {
-      const std::string e = cmStrCat(
-        "The ", lang, "_STANDARD property on target \"", target->GetName(),
-        "\" contained an invalid value: \"", *existingCudaStandard, "\".");
-      if (error) {
-        *error = e;
-      } else {
-        this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR, e,
-                                               this->Backtrace);
-      }
-      return false;
-    }
-  }
-
-  /* clang-format off */
-  const char* const* needCudaLevel =
-    needCuda20 ? &CUDA_STANDARDS[4]
-    : needCuda17 ? &CUDA_STANDARDS[3]
-    : needCuda14 ? &CUDA_STANDARDS[2]
-    : needCuda11 ? &CUDA_STANDARDS[1]
-    : needCuda03 ? &CUDA_STANDARDS[0]
-    : nullptr;
-  /* clang-format on */
-
-  if (needCudaLevel) {
-    // Ensure the CUDA language level is high enough to support
-    // the needed CUDA features.
-    if (!existingCudaLevel || existingCudaLevel < needCudaLevel) {
-      target->SetProperty("CUDA_STANDARD", *needCudaLevel);
-    }
-  }
-
-  return true;
-}
-
-void cmMakefile::CheckNeededCLanguage(const std::string& feature,
-                                      std::string const& lang, bool& needC90,
-                                      bool& needC99, bool& needC11) const
-{
-  if (const char* propC90 =
-        this->GetDefinition(cmStrCat("CMAKE_", lang, "90_COMPILE_FEATURES"))) {
-    std::vector<std::string> props = cmExpandedList(propC90);
-    needC90 = cm::contains(props, feature);
-  }
-  if (const char* propC99 =
-        this->GetDefinition(cmStrCat("CMAKE_", lang, "99_COMPILE_FEATURES"))) {
-    std::vector<std::string> props = cmExpandedList(propC99);
-    needC99 = cm::contains(props, feature);
-  }
-  if (const char* propC11 =
-        this->GetDefinition(cmStrCat("CMAKE_", lang, "11_COMPILE_FEATURES"))) {
-    std::vector<std::string> props = cmExpandedList(propC11);
-    needC11 = cm::contains(props, feature);
-  }
-}
-
-bool cmMakefile::AddRequiredTargetCFeature(cmTarget* target,
-                                           const std::string& feature,
-                                           std::string const& lang,
-                                           std::string* error) const
-{
-  bool needC90 = false;
-  bool needC99 = false;
-  bool needC11 = false;
-
-  this->CheckNeededCLanguage(feature, lang, needC90, needC99, needC11);
-
-  cmProp existingCStandard = target->GetProperty(cmStrCat(lang, "_STANDARD"));
-  if (existingCStandard == nullptr) {
-    cmProp defaultCStandard =
-      this->GetDef(cmStrCat("CMAKE_", lang, "_STANDARD_DEFAULT"));
-    if (defaultCStandard && !defaultCStandard->empty()) {
-      existingCStandard = defaultCStandard;
-    }
-  }
-  if (existingCStandard) {
-    if (std::find_if(cm::cbegin(C_STANDARDS), cm::cend(C_STANDARDS),
-                     cmStrCmp(*existingCStandard)) == cm::cend(C_STANDARDS)) {
-      const std::string e = cmStrCat(
-        "The ", lang, "_STANDARD property on target \"", target->GetName(),
-        "\" contained an invalid value: \"", *existingCStandard, "\".");
-      if (error) {
-        *error = e;
-      } else {
-        this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR, e,
-                                               this->Backtrace);
-      }
-      return false;
-    }
-  }
-  const char* const* existingCIt = existingCStandard
-    ? std::find_if(cm::cbegin(C_STANDARDS), cm::cend(C_STANDARDS),
-                   cmStrCmp(*existingCStandard))
-    : cm::cend(C_STANDARDS);
-
-  bool setC90 = needC90 && !existingCStandard;
-  bool setC99 = needC99 && !existingCStandard;
-  bool setC11 = needC11 && !existingCStandard;
-
-  if (needC11 && existingCStandard &&
-      existingCIt < std::find_if(cm::cbegin(C_STANDARDS),
-                                 cm::cend(C_STANDARDS), cmStrCmp("11"))) {
-    setC11 = true;
-  } else if (needC99 && existingCStandard &&
-             existingCIt < std::find_if(cm::cbegin(C_STANDARDS),
-                                        cm::cend(C_STANDARDS),
-                                        cmStrCmp("99"))) {
-    setC99 = true;
-  } else if (needC90 && existingCStandard &&
-             existingCIt < std::find_if(cm::cbegin(C_STANDARDS),
-                                        cm::cend(C_STANDARDS),
-                                        cmStrCmp("90"))) {
-    setC90 = true;
-  }
-
-  if (setC11) {
-    target->SetProperty(cmStrCat(lang, "_STANDARD"), "11");
-  } else if (setC99) {
-    target->SetProperty(cmStrCat(lang, "_STANDARD"), "99");
-  } else if (setC90) {
-    target->SetProperty(cmStrCat(lang, "_STANDARD"), "90");
-  }
-  return true;
-}
-
 cmMakefile::FunctionPushPop::FunctionPushPop(cmMakefile* mf,
                                              const std::string& fileName,
                                              cmPolicies::PolicyMap const& pm)
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index 45d7109..80d80d3 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -342,12 +342,19 @@
    */
   void SetProjectName(std::string const& name);
 
-  /** Get the configurations to be generated.  */
-  std::string GetConfigurations(std::vector<std::string>& configs,
-                                bool single = true) const;
+  /* Get the default configuration */
+  std::string GetDefaultConfiguration() const;
+
+  enum GeneratorConfigQuery
+  {
+    IncludeEmptyConfig, // Include "" aka noconfig
+    ExcludeEmptyConfig, // Exclude "" aka noconfig
+    OnlyMultiConfig,
+  };
 
   /** Get the configurations for dependency checking.  */
-  std::vector<std::string> GetGeneratorConfigs() const;
+  std::vector<std::string> GetGeneratorConfigs(
+    GeneratorConfigQuery mode) const;
 
   /**
    * Set the name of the library.
@@ -686,6 +693,7 @@
    */
   int ConfigureFile(const std::string& infile, const std::string& outfile,
                     bool copyonly, bool atOnly, bool escapeQuotes,
+                    bool use_source_permissions,
                     cmNewLineStyle = cmNewLineStyle());
 
   /**
@@ -925,21 +933,6 @@
 
   bool PolicyOptionalWarningEnabled(std::string const& var);
 
-  bool AddRequiredTargetFeature(cmTarget* target, const std::string& feature,
-                                std::string* error = nullptr) const;
-
-  bool CompileFeatureKnown(cmTarget const* target, const std::string& feature,
-                           std::string& lang, std::string* error) const;
-
-  const char* CompileFeaturesAvailable(const std::string& lang,
-                                       std::string* error) const;
-
-  bool HaveStandardAvailable(cmTarget const* target, std::string const& lang,
-                             const std::string& feature) const;
-
-  bool IsLaterStandard(std::string const& lang, std::string const& lhs,
-                       std::string const& rhs);
-
   void PushLoopBlock();
   void PopLoopBlock();
   bool IsLoopBlock() const;
@@ -985,9 +978,6 @@
   // add link libraries and directories to the target
   void AddGlobalLinkInformation(cmTarget& target);
 
-  // Check for a an unused variable
-  void LogUnused(const char* reason, const std::string& name) const;
-
   mutable std::set<cmListFileContext> CMP0054ReportedIds;
 
   // libraries, classes, and executables
@@ -1162,44 +1152,6 @@
    */
   bool MightHaveCustomCommand(const std::string& name) const;
 
-  bool AddRequiredTargetCFeature(cmTarget* target, const std::string& feature,
-                                 std::string const& lang,
-                                 std::string* error = nullptr) const;
-  bool AddRequiredTargetCxxFeature(cmTarget* target,
-                                   const std::string& feature,
-                                   std::string const& lang,
-                                   std::string* error = nullptr) const;
-  bool AddRequiredTargetCudaFeature(cmTarget* target,
-                                    const std::string& feature,
-                                    std::string const& lang,
-                                    std::string* error = nullptr) const;
-
-  void CheckNeededCLanguage(const std::string& feature,
-                            std::string const& lang, bool& needC90,
-                            bool& needC99, bool& needC11) const;
-  void CheckNeededCxxLanguage(const std::string& feature,
-                              std::string const& lang, bool& needCxx98,
-                              bool& needCxx11, bool& needCxx14,
-                              bool& needCxx17, bool& needCxx20) const;
-  void CheckNeededCudaLanguage(const std::string& feature,
-                               std::string const& lang, bool& needCuda03,
-                               bool& needCuda11, bool& needCuda14,
-                               bool& needCuda17, bool& needCuda20) const;
-
-  bool HaveCStandardAvailable(cmTarget const* target,
-                              const std::string& feature,
-                              std::string const& lang) const;
-  bool HaveCxxStandardAvailable(cmTarget const* target,
-                                const std::string& feature,
-                                std::string const& lang) const;
-  bool HaveCudaStandardAvailable(cmTarget const* target,
-                                 const std::string& feature,
-                                 std::string const& lang) const;
-
-  void CheckForUnusedVariables() const;
-
-  // Unused variable flags
-  bool WarnUnused;
   bool CheckSystemVars;
   bool CheckCMP0000;
   std::set<std::string> WarnedCMP0074;
diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx
index 446f225..bc288ac 100644
--- a/Source/cmMakefileExecutableTargetGenerator.cxx
+++ b/Source/cmMakefileExecutableTargetGenerator.cxx
@@ -218,7 +218,7 @@
 
     const char* val = this->LocalGenerator->GetRuleLauncher(
       this->GeneratorTarget, "RULE_LAUNCH_LINK");
-    if (val && *val) {
+    if (cmNonempty(val)) {
       launcher = cmStrCat(val, ' ');
     }
 
@@ -583,7 +583,7 @@
 
     const char* val = this->LocalGenerator->GetRuleLauncher(
       this->GeneratorTarget, "RULE_LAUNCH_LINK");
-    if (val && *val) {
+    if (cmNonempty(val)) {
       launcher = cmStrCat(val, ' ');
     }
 
diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx
index 5809b4a..1c25fc4 100644
--- a/Source/cmMakefileLibraryTargetGenerator.cxx
+++ b/Source/cmMakefileLibraryTargetGenerator.cxx
@@ -356,7 +356,7 @@
     std::string launcher;
     const char* val = this->LocalGenerator->GetRuleLauncher(
       this->GeneratorTarget, "RULE_LAUNCH_LINK");
-    if (val && *val) {
+    if (cmNonempty(val)) {
       launcher = cmStrCat(val, ' ');
     }
 
@@ -809,7 +809,7 @@
     std::string launcher;
     const char* val = this->LocalGenerator->GetRuleLauncher(
       this->GeneratorTarget, "RULE_LAUNCH_LINK");
-    if (val && *val) {
+    if (cmNonempty(val)) {
       launcher = cmStrCat(val, ' ');
     }
 
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index 8396fa3..fae1d76 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -71,6 +71,7 @@
     case cmStateEnums::OBJECT_LIBRARY:
       result = cm::make_unique<cmMakefileLibraryTargetGenerator>(tgt);
       break;
+    case cmStateEnums::INTERFACE_LIBRARY:
     case cmStateEnums::UTILITY:
       result = cm::make_unique<cmMakefileUtilityTargetGenerator>(tgt);
       break;
@@ -197,8 +198,7 @@
   }
 
   // add custom commands to the clean rules?
-  cmProp clean_no_custom = this->Makefile->GetProperty("CLEAN_NO_CUSTOM");
-  bool clean = clean_no_custom ? cmIsOff(*clean_no_custom) : true;
+  bool clean = cmIsOff(this->Makefile->GetProperty("CLEAN_NO_CUSTOM"));
 
   // First generate the object rule files.  Save a list of all object
   // files for this target.
@@ -532,6 +532,13 @@
   // Build the set of compiler flags.
   std::string flags;
 
+  // explicitly add the explicit language flag before any other flag
+  // this way backwards compatibility with user flags is maintained
+  if (source.GetProperty("LANGUAGE")) {
+    this->LocalGenerator->AppendFeatureOptions(flags, lang,
+                                               "EXPLICIT_LANGUAGE");
+  }
+
   // Add language-specific flags.
   std::string langFlags = cmStrCat("$(", lang, "_FLAGS", filterArch, ")");
   this->LocalGenerator->AppendFlags(flags, langFlags);
@@ -800,7 +807,7 @@
          lang == "OBJC" || lang == "OBJCXX")) {
       std::string const clauncher_prop = lang + "_COMPILER_LAUNCHER";
       cmProp clauncher = this->GeneratorTarget->GetProperty(clauncher_prop);
-      if (clauncher && !clauncher->empty()) {
+      if (cmNonempty(clauncher)) {
         compilerLauncher = *clauncher;
       }
     }
@@ -815,8 +822,8 @@
       cmProp cpplint = this->GeneratorTarget->GetProperty(cpplint_prop);
       std::string const cppcheck_prop = lang + "_CPPCHECK";
       cmProp cppcheck = this->GeneratorTarget->GetProperty(cppcheck_prop);
-      if ((iwyu && !iwyu->empty()) || (tidy && !tidy->empty()) ||
-          (cpplint && !cpplint->empty()) || (cppcheck && !cppcheck->empty())) {
+      if (cmNonempty(iwyu) || cmNonempty(tidy) || cmNonempty(cpplint) ||
+          cmNonempty(cppcheck)) {
         std::string run_iwyu = "$(CMAKE_COMMAND) -E __run_co_compile";
         if (!compilerLauncher.empty()) {
           // In __run_co_compile case the launcher command is supplied
@@ -825,30 +832,30 @@
           run_iwyu += this->LocalGenerator->EscapeForShell(compilerLauncher);
           compilerLauncher.clear();
         }
-        if (iwyu && !iwyu->empty()) {
+        if (cmNonempty(iwyu)) {
           run_iwyu += " --iwyu=";
           run_iwyu += this->LocalGenerator->EscapeForShell(*iwyu);
         }
-        if (tidy && !tidy->empty()) {
+        if (cmNonempty(tidy)) {
           run_iwyu += " --tidy=";
           const char* driverMode = this->Makefile->GetDefinition(
             "CMAKE_" + lang + "_CLANG_TIDY_DRIVER_MODE");
-          if (!(driverMode && *driverMode)) {
+          if (!cmNonempty(driverMode)) {
             driverMode = lang == "C" ? "gcc" : "g++";
           }
           run_iwyu += this->LocalGenerator->EscapeForShell(
             cmStrCat(*tidy, ";--extra-arg-before=--driver-mode=", driverMode));
         }
-        if (cpplint && !cpplint->empty()) {
+        if (cmNonempty(cpplint)) {
           run_iwyu += " --cpplint=";
           run_iwyu += this->LocalGenerator->EscapeForShell(*cpplint);
         }
-        if (cppcheck && !cppcheck->empty()) {
+        if (cmNonempty(cppcheck)) {
           run_iwyu += " --cppcheck=";
           run_iwyu += this->LocalGenerator->EscapeForShell(*cppcheck);
         }
-        if ((tidy && !tidy->empty()) || (cpplint && !cpplint->empty()) ||
-            (cppcheck && !cppcheck->empty())) {
+        if (cmNonempty(tidy) || (cmNonempty(cpplint)) ||
+            (cmNonempty(cppcheck))) {
           run_iwyu += " --source=";
           run_iwyu += sourceFile;
         }
@@ -875,7 +882,7 @@
     {
       const char* val = this->LocalGenerator->GetRuleLauncher(
         this->GeneratorTarget, "RULE_LAUNCH_COMPILE");
-      if (val && *val) {
+      if (cmNonempty(val)) {
         launcher = cmStrCat(val, ' ');
       }
     }
@@ -1851,7 +1858,7 @@
       this->LocalGenerator->GetCurrentBinaryDirectory(), objlist_file),
     cmOutputConverter::SHELL);
   const char* nm_executable = this->Makefile->GetDefinition("CMAKE_NM");
-  if (nm_executable && *nm_executable) {
+  if (cmNonempty(nm_executable)) {
     cmd += " --nm=";
     cmd += this->LocalCommonGenerator->ConvertToOutputFormat(
       nm_executable, cmOutputConverter::SHELL);
diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx
index 32ab9f8..bde5ee7 100644
--- a/Source/cmNinjaNormalTargetGenerator.cxx
+++ b/Source/cmNinjaNormalTargetGenerator.cxx
@@ -239,7 +239,7 @@
     std::string launcher;
     const char* val = this->GetLocalGenerator()->GetRuleLauncher(
       this->GetGeneratorTarget(), "RULE_LAUNCH_LINK");
-    if (val && *val) {
+    if (cmNonempty(val)) {
       launcher = cmStrCat(val, ' ');
     }
 
@@ -376,7 +376,7 @@
     std::string launcher;
     const char* val = this->GetLocalGenerator()->GetRuleLauncher(
       this->GetGeneratorTarget(), "RULE_LAUNCH_LINK");
-    if (val && *val) {
+    if (cmNonempty(val)) {
       launcher = cmStrCat(val, ' ');
     }
 
@@ -739,7 +739,8 @@
 
   // Gather order-only dependencies.
   this->GetLocalGenerator()->AppendTargetDepends(
-    this->GetGeneratorTarget(), build.OrderOnlyDeps, config, config);
+    this->GetGeneratorTarget(), build.OrderOnlyDeps, config, config,
+    DependOnTargetArtifact);
 
   // Write the build statement for this target.
   bool usedResponseFile = false;
@@ -1091,7 +1092,7 @@
       obj_list_file, cmOutputConverter::SHELL);
 
     const char* nm_executable = GetMakefile()->GetDefinition("CMAKE_NM");
-    if (nm_executable && *nm_executable) {
+    if (cmNonempty(nm_executable)) {
       cmd += " --nm=";
       cmd += this->LocalCommonGenerator->ConvertToOutputFormat(
         nm_executable, cmOutputConverter::SHELL);
@@ -1160,8 +1161,8 @@
              globalGen->IsMultiConfig() ? cmStrCat('.', config) : "", ".rsp"));
 
   // Gather order-only dependencies.
-  this->GetLocalGenerator()->AppendTargetDepends(gt, linkBuild.OrderOnlyDeps,
-                                                 config, fileConfig);
+  this->GetLocalGenerator()->AppendTargetDepends(
+    gt, linkBuild.OrderOnlyDeps, config, fileConfig, DependOnTargetArtifact);
 
   // Add order-only dependencies on versioning symlinks of shared libs we link.
   if (!this->GeneratorTarget->IsDLLPlatform()) {
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index d406c99..57f526e 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -51,6 +51,7 @@
       return cm::make_unique<cmNinjaNormalTargetGenerator>(target);
 
     case cmStateEnums::UTILITY:
+    case cmStateEnums::INTERFACE_LIBRARY:
     case cmStateEnums::GLOBAL_TARGET:
       return cm::make_unique<cmNinjaUtilityTargetGenerator>(target);
 
@@ -65,7 +66,8 @@
   , LocalGenerator(
       static_cast<cmLocalNinjaGenerator*>(target->GetLocalGenerator()))
 {
-  for (auto const& fileConfig : target->Makefile->GetGeneratorConfigs()) {
+  for (auto const& fileConfig :
+       target->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig)) {
     this->Configs[fileConfig].MacOSXContentGenerator =
       cm::make_unique<MacOSXContentGeneratorType>(this, fileConfig);
   }
@@ -188,7 +190,16 @@
     }
   }
 
-  std::string flags = this->GetFlags(language, config, filterArch);
+  std::string flags;
+  // explicitly add the explicit language flag before any other flag
+  // this way backwards compatibility with user flags is maintained
+  if (source->GetProperty("LANGUAGE")) {
+    this->LocalGenerator->AppendFeatureOptions(flags, language,
+                                               "EXPLICIT_LANGUAGE");
+    flags += " ";
+  }
+
+  flags += this->GetFlags(language, config, filterArch);
 
   // Add Fortran format flags.
   if (language == "Fortran") {
@@ -652,7 +663,7 @@
   std::string launcher;
   const char* val = this->GetLocalGenerator()->GetRuleLauncher(
     this->GetGeneratorTarget(), "RULE_LAUNCH_COMPILE");
-  if (val && *val) {
+  if (cmNonempty(val)) {
     launcher = cmStrCat(val, ' ');
   }
 
@@ -803,7 +814,7 @@
        lang == "OBJC" || lang == "OBJCXX")) {
     std::string const clauncher_prop = cmStrCat(lang, "_COMPILER_LAUNCHER");
     cmProp clauncher = this->GeneratorTarget->GetProperty(clauncher_prop);
-    if (clauncher && !clauncher->empty()) {
+    if (cmNonempty(clauncher)) {
       compilerLauncher = *clauncher;
     }
   }
@@ -818,8 +829,8 @@
     cmProp cpplint = this->GeneratorTarget->GetProperty(cpplint_prop);
     std::string const cppcheck_prop = cmStrCat(lang, "_CPPCHECK");
     cmProp cppcheck = this->GeneratorTarget->GetProperty(cppcheck_prop);
-    if ((iwyu && !iwyu->empty()) || (tidy && !tidy->empty()) ||
-        (cpplint && !cpplint->empty()) || (cppcheck && !cppcheck->empty())) {
+    if (cmNonempty(iwyu) || cmNonempty(tidy) || cmNonempty(cpplint) ||
+        cmNonempty(cppcheck)) {
       std::string run_iwyu = cmStrCat(cmakeCmd, " -E __run_co_compile");
       if (!compilerLauncher.empty()) {
         // In __run_co_compile case the launcher command is supplied
@@ -829,31 +840,30 @@
                    this->LocalGenerator->EscapeForShell(compilerLauncher));
         compilerLauncher.clear();
       }
-      if (iwyu && !iwyu->empty()) {
+      if (cmNonempty(iwyu)) {
         run_iwyu += cmStrCat(" --iwyu=",
                              this->GetLocalGenerator()->EscapeForShell(*iwyu));
       }
-      if (tidy && !tidy->empty()) {
+      if (cmNonempty(tidy)) {
         run_iwyu += " --tidy=";
         const char* driverMode = this->Makefile->GetDefinition(
           cmStrCat("CMAKE_", lang, "_CLANG_TIDY_DRIVER_MODE"));
-        if (!(driverMode && *driverMode)) {
+        if (!cmNonempty(driverMode)) {
           driverMode = lang == "C" ? "gcc" : "g++";
         }
         run_iwyu += this->GetLocalGenerator()->EscapeForShell(
           cmStrCat(*tidy, ";--extra-arg-before=--driver-mode=", driverMode));
       }
-      if (cpplint && !cpplint->empty()) {
+      if (cmNonempty(cpplint)) {
         run_iwyu += cmStrCat(
           " --cpplint=", this->GetLocalGenerator()->EscapeForShell(*cpplint));
       }
-      if (cppcheck && !cppcheck->empty()) {
+      if (cmNonempty(cppcheck)) {
         run_iwyu +=
           cmStrCat(" --cppcheck=",
                    this->GetLocalGenerator()->EscapeForShell(*cppcheck));
       }
-      if ((tidy && !tidy->empty()) || (cpplint && !cpplint->empty()) ||
-          (cppcheck && !cppcheck->empty())) {
+      if (cmNonempty(tidy) || cmNonempty(cpplint) || cmNonempty(cppcheck)) {
         run_iwyu += " --source=$in";
       }
       run_iwyu += " -- ";
diff --git a/Source/cmNinjaUtilityTargetGenerator.cxx b/Source/cmNinjaUtilityTargetGenerator.cxx
index 8d863c3..9508bb9 100644
--- a/Source/cmNinjaUtilityTargetGenerator.cxx
+++ b/Source/cmNinjaUtilityTargetGenerator.cxx
@@ -101,7 +101,8 @@
     lg->AppendTargetOutputs(genTarget, gg->GetByproductsForCleanTarget(),
                             config);
   }
-  lg->AppendTargetDepends(genTarget, deps, config, config);
+  lg->AppendTargetDepends(genTarget, deps, config, config,
+                          DependOnTargetArtifact);
 
   if (commands.empty()) {
     phonyBuild.Comment = "Utility command for " + this->GetTargetName();
diff --git a/Source/cmPolicies.cxx b/Source/cmPolicies.cxx
index dea3f8a..01e8c04 100644
--- a/Source/cmPolicies.cxx
+++ b/Source/cmPolicies.cxx
@@ -7,9 +7,11 @@
 #include <sstream>
 #include <vector>
 
+#include "cmListFileCache.h"
 #include "cmMakefile.h"
 #include "cmMessageType.h"
 #include "cmState.h"
+#include "cmStateSnapshot.h"
 #include "cmStateTypes.h"
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
@@ -157,7 +159,8 @@
 
 bool cmPolicies::ApplyPolicyVersion(cmMakefile* mf,
                                     std::string const& version_min,
-                                    std::string const& version_max)
+                                    std::string const& version_max,
+                                    WarnCompat warnCompat)
 {
   // Parse components of the minimum version.
   unsigned int minMajor = 2;
@@ -244,13 +247,34 @@
     polPatch = maxPatch;
   }
 
-  return cmPolicies::ApplyPolicyVersion(mf, polMajor, polMinor, polPatch);
+  return cmPolicies::ApplyPolicyVersion(mf, polMajor, polMinor, polPatch,
+                                        warnCompat);
 }
 
 bool cmPolicies::ApplyPolicyVersion(cmMakefile* mf, unsigned int majorVer,
                                     unsigned int minorVer,
-                                    unsigned int patchVer)
+                                    unsigned int patchVer,
+                                    WarnCompat warnCompat)
 {
+  // Warn about policy versions for which support will be removed.
+  if (warnCompat == WarnCompat::On &&
+      (majorVer < 2 || (majorVer == 2 && minorVer < 8) ||
+       (majorVer == 2 && minorVer == 8 && patchVer < 12)) &&
+      // Avoid warning on calls generated by install(EXPORT)
+      // in CMake versions prior to 3.18.
+      !(majorVer == 2 && minorVer == 6 && patchVer == 0 &&
+        mf->GetStateSnapshot().CanPopPolicyScope() &&
+        cmSystemTools::Strucmp(mf->GetBacktrace().Top().Name.c_str(),
+                               "cmake_policy") == 0)) {
+    mf->IssueMessage(
+      MessageType::DEPRECATION_WARNING,
+      "Compatibility with CMake < 2.8.12 will be removed from "
+      "a future version of CMake.\n"
+      "Update the VERSION argument <min> value or use a ...<max> suffix "
+      "to tell CMake that the project does not need compatibility with "
+      "older versions.");
+  }
+
   // now loop over all the policies and set them as appropriate
   std::vector<cmPolicies::PolicyID> ancientPolicies;
   for (PolicyID pid = cmPolicies::CMP0000; pid != cmPolicies::CMPCOUNT;
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index a82f421..bba8b03 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -320,7 +320,10 @@
   SELECT(POLICY, CMP0107, "An ALIAS target cannot overwrite another target.", \
          3, 18, 0, cmPolicies::WARN)                                          \
   SELECT(POLICY, CMP0108, "A target cannot link to itself through an alias.", \
-         3, 18, 0, cmPolicies::WARN)
+         3, 18, 0, cmPolicies::WARN)                                          \
+  SELECT(POLICY, CMP0109,                                                     \
+         "find_program() requires permission to execute but not to read.", 3, \
+         19, 0, cmPolicies::WARN)
 
 #define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
 #define CM_FOR_EACH_POLICY_ID(POLICY)                                         \
@@ -396,12 +399,20 @@
   //! Get the default status for a policy
   static cmPolicies::PolicyStatus GetPolicyStatus(cmPolicies::PolicyID id);
 
+  enum class WarnCompat
+  {
+    Off,
+    On
+  };
+
   //! Set a policy level for this listfile
   static bool ApplyPolicyVersion(cmMakefile* mf,
                                  std::string const& version_min,
-                                 std::string const& version_max);
+                                 std::string const& version_max,
+                                 WarnCompat warnCompat);
   static bool ApplyPolicyVersion(cmMakefile* mf, unsigned int majorVer,
-                                 unsigned int minorVer, unsigned int patchVer);
+                                 unsigned int minorVer, unsigned int patchVer,
+                                 WarnCompat warnCompat);
 
   //! return a warning string for a given policy
   static std::string GetPolicyWarning(cmPolicies::PolicyID id);
diff --git a/Source/cmProjectCommand.cxx b/Source/cmProjectCommand.cxx
index 2ec66d9..bb6db92 100644
--- a/Source/cmProjectCommand.cxx
+++ b/Source/cmProjectCommand.cxx
@@ -303,7 +303,7 @@
     std::string vw;
     for (std::string const& i : vv) {
       const char* const v = mf.GetDefinition(i);
-      if (v && *v) {
+      if (cmNonempty(v)) {
         if (cmp0048 == cmPolicies::WARN) {
           if (!injectedProjectCommand) {
             vw += "\n  ";
diff --git a/Source/cmQtAutoGenGlobalInitializer.cxx b/Source/cmQtAutoGenGlobalInitializer.cxx
index 3d4f5d7..fac2bbf 100644
--- a/Source/cmQtAutoGenGlobalInitializer.cxx
+++ b/Source/cmQtAutoGenGlobalInitializer.cxx
@@ -50,7 +50,7 @@
     {
       cmMakefile* makefile = localGen->GetMakefile();
       // Detect global autogen target name
-      if (cmIsOn(makefile->GetSafeDefinition("CMAKE_GLOBAL_AUTOGEN_TARGET"))) {
+      if (makefile->IsOn("CMAKE_GLOBAL_AUTOGEN_TARGET")) {
         std::string targetName =
           makefile->GetSafeDefinition("CMAKE_GLOBAL_AUTOGEN_TARGET_NAME");
         if (targetName.empty()) {
@@ -61,7 +61,7 @@
       }
 
       // Detect global autorcc target name
-      if (cmIsOn(makefile->GetSafeDefinition("CMAKE_GLOBAL_AUTORCC_TARGET"))) {
+      if (makefile->IsOn("CMAKE_GLOBAL_AUTORCC_TARGET")) {
         std::string targetName =
           makefile->GetSafeDefinition("CMAKE_GLOBAL_AUTORCC_TARGET_NAME");
         if (targetName.empty()) {
diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx
index 1132852..06957b0 100644
--- a/Source/cmQtAutoGenInitializer.cxx
+++ b/Source/cmQtAutoGenInitializer.cxx
@@ -315,10 +315,9 @@
 {
   // Configurations
   this->MultiConfig = this->GlobalGen->IsMultiConfig();
-  this->ConfigDefault = this->Makefile->GetConfigurations(this->ConfigsList);
-  if (this->ConfigsList.empty()) {
-    this->ConfigsList.push_back(this->ConfigDefault);
-  }
+  this->ConfigDefault = this->Makefile->GetDefaultConfiguration();
+  this->ConfigsList =
+    this->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
 
   // Verbosity
   {
@@ -490,7 +489,7 @@
 
     if (this->Moc.Enabled) {
       // Path prefix
-      if (cmIsOn(this->GenTarget->GetSafeProperty("AUTOMOC_PATH_PREFIX"))) {
+      if (cmIsOn(this->GenTarget->GetProperty("AUTOMOC_PATH_PREFIX"))) {
         this->Moc.PathPrefix = true;
       }
 
@@ -789,9 +788,9 @@
 
       // Register files that will be scanned by moc or uic
       if (this->MocOrUicEnabled()) {
-        if (cm->IsHeaderExtension(extLower)) {
+        if (cm->IsAHeaderExtension(extLower)) {
           addMUHeader(makeMUFile(sf, fullPath, true), extLower);
-        } else if (cm->IsSourceExtension(extLower)) {
+        } else if (cm->IsACLikeSourceExtension(extLower)) {
           addMUSource(makeMUFile(sf, fullPath, true));
         }
       }
@@ -863,7 +862,7 @@
 
             if (sf != nullptr) {
               auto eMuf = makeMUFile(sf, fullPath, true);
-              // Ony process moc/uic when the parent is processed as well
+              // Only process moc/uic when the parent is processed as well
               if (!muf.MocIt) {
                 eMuf->MocIt = false;
               }
@@ -895,14 +894,14 @@
       std::string const& extLower =
         cmSystemTools::LowerCase(sf->GetExtension());
 
-      if (cm->IsHeaderExtension(extLower)) {
+      if (cm->IsAHeaderExtension(extLower)) {
         if (!cm::contains(this->AutogenTarget.Headers, sf.get())) {
           auto muf = makeMUFile(sf.get(), fullPath, false);
           if (muf->SkipMoc || muf->SkipUic) {
             addMUHeader(std::move(muf), extLower);
           }
         }
-      } else if (cm->IsSourceExtension(extLower)) {
+      } else if (cm->IsACLikeSourceExtension(extLower)) {
         if (!cm::contains(this->AutogenTarget.Sources, sf.get())) {
           auto muf = makeMUFile(sf.get(), fullPath, false);
           if (muf->SkipMoc || muf->SkipUic) {
@@ -1654,7 +1653,7 @@
       };
       for (std::string const& prop : props) {
         cmProp propName = this->Makefile->GetState()->GetGlobalProperty(prop);
-        if (propName && !propName->empty()) {
+        if (cmNonempty(propName)) {
           groupName = *propName;
           property = prop;
           break;
diff --git a/Source/cmRulePlaceholderExpander.cxx b/Source/cmRulePlaceholderExpander.cxx
index 254131b..4ff81c1 100644
--- a/Source/cmRulePlaceholderExpander.cxx
+++ b/Source/cmRulePlaceholderExpander.cxx
@@ -261,7 +261,7 @@
       this->VariableMappings["CMAKE_" + compIt->second +
                              "_COMPILE_OPTIONS_SYSROOT"];
 
-    // if there is a required first argument to the compiler add it
+    // if there are required arguments to the compiler add it
     // to the compiler string
     if (!compilerArg1.empty()) {
       ret += " ";
diff --git a/Source/cmSearchPath.cxx b/Source/cmSearchPath.cxx
index 766d347..eb8fcaf 100644
--- a/Source/cmSearchPath.cxx
+++ b/Source/cmSearchPath.cxx
@@ -180,7 +180,7 @@
     if (subdir == "include" || subdir == "lib") {
       const char* arch =
         this->FC->Makefile->GetDefinition("CMAKE_LIBRARY_ARCHITECTURE");
-      if (arch && *arch) {
+      if (cmNonempty(arch)) {
         if (this->FC->Makefile->IsDefinitionSet("CMAKE_SYSROOT") &&
             this->FC->Makefile->IsDefinitionSet(
               "CMAKE_PREFIX_LIBRARY_ARCHITECTURE")) {
diff --git a/Source/cmServerProtocol.cxx b/Source/cmServerProtocol.cxx
index 4f7131f..e586fd9 100644
--- a/Source/cmServerProtocol.cxx
+++ b/Source/cmServerProtocol.cxx
@@ -136,6 +136,7 @@
   this->m_Server = server;
   this->m_CMakeInstance =
     cm::make_unique<cmake>(cmake::RoleProject, cmState::Project);
+  this->m_WarnUnused = false;
   const bool result = this->DoActivate(request, errorMessage);
   if (!result) {
     this->m_CMakeInstance = nullptr;
@@ -636,7 +637,7 @@
   obj[kTRACE_KEY] = cm->GetTrace();
   obj[kTRACE_EXPAND_KEY] = cm->GetTraceExpand();
   obj[kWARN_UNINITIALIZED_KEY] = cm->GetWarnUninitialized();
-  obj[kWARN_UNUSED_KEY] = cm->GetWarnUnused();
+  obj[kWARN_UNUSED_KEY] = m_WarnUnused;
   obj[kWARN_UNUSED_CLI_KEY] = cm->GetWarnUnusedCli();
   obj[kCHECK_SYSTEM_VARS_KEY] = cm->GetCheckSystemVars();
 
@@ -682,7 +683,7 @@
   setBool(request, kTRACE_EXPAND_KEY, [cm](bool e) { cm->SetTraceExpand(e); });
   setBool(request, kWARN_UNINITIALIZED_KEY,
           [cm](bool e) { cm->SetWarnUninitialized(e); });
-  setBool(request, kWARN_UNUSED_KEY, [cm](bool e) { cm->SetWarnUnused(e); });
+  setBool(request, kWARN_UNUSED_KEY, [this](bool e) { m_WarnUnused = e; });
   setBool(request, kWARN_UNUSED_CLI_KEY,
           [cm](bool e) { cm->SetWarnUnusedCli(e); });
   setBool(request, kCHECK_SYSTEM_VARS_KEY,
diff --git a/Source/cmServerProtocol.h b/Source/cmServerProtocol.h
index c71b7bf..6009e23 100644
--- a/Source/cmServerProtocol.h
+++ b/Source/cmServerProtocol.h
@@ -94,6 +94,7 @@
   // Implement protocol specific activation tasks here. Called from Activate().
   virtual bool DoActivate(const cmServerRequest& request,
                           std::string* errorMessage);
+  bool m_WarnUnused = false; // storage for legacy option
 
 private:
   std::unique_ptr<cmake> m_CMakeInstance;
diff --git a/Source/cmSourceFile.cxx b/Source/cmSourceFile.cxx
index f525439..ef44a57 100644
--- a/Source/cmSourceFile.cxx
+++ b/Source/cmSourceFile.cxx
@@ -2,7 +2,6 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmSourceFile.h"
 
-#include <array>
 #include <utility>
 
 #include "cmGlobalGenerator.h"
@@ -130,13 +129,11 @@
   // Location path
   std::string const& lPath = this->Location.GetFullPath();
   // List of extension lists
-  std::array<std::vector<std::string> const*, 2> const extsLists = {
-    { &makefile->GetCMakeInstance()->GetSourceExtensions(),
-      &makefile->GetCMakeInstance()->GetHeaderExtensions() }
-  };
+  std::vector<std::string> exts =
+    makefile->GetCMakeInstance()->GetAllExtensions();
 
   // Tries to find the file in a given directory
-  auto findInDir = [this, &extsLists, &lPath](std::string const& dir) -> bool {
+  auto findInDir = [this, &exts, &lPath](std::string const& dir) -> bool {
     // Compute full path
     std::string const fullPath = cmSystemTools::CollapseFullPath(lPath, dir);
     // Try full path
@@ -145,14 +142,12 @@
       return true;
     }
     // Try full path with extension
-    for (auto& exts : extsLists) {
-      for (std::string const& ext : *exts) {
-        if (!ext.empty()) {
-          std::string extPath = cmStrCat(fullPath, '.', ext);
-          if (cmSystemTools::FileExists(extPath)) {
-            this->FullPath = extPath;
-            return true;
-          }
+    for (std::string const& ext : exts) {
+      if (!ext.empty()) {
+        std::string extPath = cmStrCat(fullPath, '.', ext);
+        if (cmSystemTools::FileExists(extPath)) {
+          this->FullPath = extPath;
+          return true;
         }
       }
     }
@@ -175,11 +170,9 @@
   // Compose error
   std::string err =
     cmStrCat("Cannot find source file:\n  ", lPath, "\nTried extensions");
-  for (auto exts : extsLists) {
-    for (std::string const& ext : *exts) {
-      err += " .";
-      err += ext;
-    }
+  for (std::string const& ext : exts) {
+    err += " .";
+    err += ext;
   }
   if (error != nullptr) {
     *error = std::move(err);
@@ -387,8 +380,7 @@
 
 bool cmSourceFile::GetPropertyAsBool(const std::string& prop) const
 {
-  cmProp p = this->GetProperty(prop);
-  return p && cmIsOn(*p);
+  return cmIsOn(this->GetProperty(prop));
 }
 
 void cmSourceFile::SetProperties(cmPropertyMap properties)
diff --git a/Source/cmSourceFileLocation.cxx b/Source/cmSourceFileLocation.cxx
index e852c05..222bafa 100644
--- a/Source/cmSourceFileLocation.cxx
+++ b/Source/cmSourceFileLocation.cxx
@@ -101,7 +101,7 @@
   cmMakefile const* mf = this->Makefile;
   auto cm = mf->GetCMakeInstance();
   if (!gg->GetLanguageFromExtension(ext.c_str()).empty() ||
-      cm->IsSourceExtension(ext) || cm->IsHeaderExtension(ext)) {
+      cm->IsAKnownExtension(ext)) {
     // This is a known extension.  Use the given filename with extension.
     this->Name = cmSystemTools::GetFilenameName(name);
     this->AmbiguousExtension = false;
@@ -157,7 +157,7 @@
   auto ext = cm::string_view(this->Name).substr(loc.Name.size() + 1);
   cmMakefile const* mf = this->Makefile;
   auto cm = mf->GetCMakeInstance();
-  return cm->IsSourceExtension(ext) || cm->IsHeaderExtension(ext);
+  return cm->IsAKnownExtension(ext);
 }
 
 bool cmSourceFileLocation::Matches(cmSourceFileLocation const& loc)
diff --git a/Source/cmStandardLevelResolver.cxx b/Source/cmStandardLevelResolver.cxx
new file mode 100644
index 0000000..6dbab98
--- /dev/null
+++ b/Source/cmStandardLevelResolver.cxx
@@ -0,0 +1,538 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file Copyright.txt or https://cmake.org/licensing for details.  */
+
+#include "cmStandardLevelResolver.h"
+
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <sstream>
+#include <stdexcept>
+#include <unordered_map>
+#include <utility>
+#include <vector>
+
+#include <cm/iterator>
+#include <cmext/algorithm>
+
+#include "cmGeneratorExpression.h"
+#include "cmGeneratorTarget.h"
+#include "cmGlobalGenerator.h"
+#include "cmMakefile.h"
+#include "cmMessageType.h"
+#include "cmProperty.h"
+#include "cmStringAlgorithms.h"
+#include "cmTarget.h"
+#include "cmake.h"
+
+namespace {
+
+#define FEATURE_STRING(F) , #F
+const char* const C_FEATURES[] = { nullptr FOR_EACH_C_FEATURE(
+  FEATURE_STRING) };
+
+const char* const CXX_FEATURES[] = { nullptr FOR_EACH_CXX_FEATURE(
+  FEATURE_STRING) };
+
+const char* const CUDA_FEATURES[] = { nullptr FOR_EACH_CUDA_FEATURE(
+  FEATURE_STRING) };
+#undef FEATURE_STRING
+
+struct StandardNeeded
+{
+  int index;
+  int value;
+};
+
+struct StanardLevelComputer
+{
+  explicit StanardLevelComputer(std::string lang, std::vector<int> levels,
+                                std::vector<std::string> levelsStr)
+    : Language(std::move(lang))
+    , Levels(std::move(levels))
+    , LevelsAsStrings(std::move(levelsStr))
+  {
+    assert(levels.size() == levelsStr.size());
+  }
+
+  std::string GetCompileOptionDef(cmMakefile* makefile,
+                                  cmGeneratorTarget const* target,
+                                  std::string const& config) const
+  {
+
+    const auto& stds = this->Levels;
+    const auto& stdsStrings = this->LevelsAsStrings;
+
+    const char* defaultStd = makefile->GetDefinition(
+      cmStrCat("CMAKE_", this->Language, "_STANDARD_DEFAULT"));
+    if (!cmNonempty(defaultStd)) {
+      // this compiler has no notion of language standard levels
+      return std::string{};
+    }
+
+    bool ext = true;
+    if (cmProp extPropValue = target->GetLanguageExtensions(this->Language)) {
+      if (cmIsOff(*extPropValue)) {
+        ext = false;
+      }
+    }
+
+    cmProp standardProp = target->GetLanguageStandard(this->Language, config);
+    if (!standardProp) {
+      if (ext) {
+        // No language standard is specified and extensions are not disabled.
+        // Check if this compiler needs a flag to enable extensions.
+        return cmStrCat("CMAKE_", this->Language, "_EXTENSION_COMPILE_OPTION");
+      }
+      return std::string{};
+    }
+
+    std::string const type = ext ? "EXTENSION" : "STANDARD";
+
+    if (target->GetLanguageStandardRequired(this->Language)) {
+      std::string option_flag = cmStrCat(
+        "CMAKE_", this->Language, *standardProp, "_", type, "_COMPILE_OPTION");
+
+      const char* opt =
+        target->Target->GetMakefile()->GetDefinition(option_flag);
+      if (!opt) {
+        std::ostringstream e;
+        e << "Target \"" << target->GetName()
+          << "\" requires the language "
+             "dialect \""
+          << this->Language << *standardProp << "\" "
+          << (ext ? "(with compiler extensions)" : "")
+          << ", but CMake "
+             "does not know the compile flags to use to enable it.";
+        makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+      }
+      return option_flag;
+    }
+
+    std::string standardStr(*standardProp);
+    if (this->Language == "CUDA" && standardStr == "98") {
+      standardStr = "03";
+    }
+
+    int standardValue = -1;
+    int defaultValue = -1;
+    try {
+      standardValue = std::stoi(standardStr);
+      defaultValue = std::stoi(defaultStd);
+    } catch (std::invalid_argument&) {
+      // fall through as we want an error
+      // when we can't find the bad value in the `stds` vector
+    }
+
+    auto stdIt = std::find(cm::cbegin(stds), cm::cend(stds), standardValue);
+    if (stdIt == cm::cend(stds)) {
+      std::string e =
+        cmStrCat(this->Language, "_STANDARD is set to invalid value '",
+                 standardStr, "'");
+      makefile->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR, e,
+                                                 target->GetBacktrace());
+      return std::string{};
+    }
+
+    auto defaultStdIt =
+      std::find(cm::cbegin(stds), cm::cend(stds), defaultValue);
+    if (defaultStdIt == cm::cend(stds)) {
+      std::string e = cmStrCat("CMAKE_", this->Language,
+                               "_STANDARD_DEFAULT is set to invalid value '",
+                               defaultStd, "'");
+      makefile->IssueMessage(MessageType::INTERNAL_ERROR, e);
+      return std::string{};
+    }
+
+    // If the standard requested is older than the compiler's default
+    // then we need to use a flag to change it.
+    if (stdIt <= defaultStdIt) {
+      auto offset = std::distance(cm::cbegin(stds), stdIt);
+      return cmStrCat("CMAKE_", this->Language, stdsStrings[offset], "_", type,
+                      "_COMPILE_OPTION");
+    }
+
+    // The standard requested is at least as new as the compiler's default,
+    // and the standard request is not required.  Decay to the newest standard
+    // for which a flag is defined.
+    for (; defaultStdIt < stdIt; --stdIt) {
+      auto offset = std::distance(cm::cbegin(stds), stdIt);
+      std::string option_flag =
+        cmStrCat("CMAKE_", this->Language, stdsStrings[offset], "_", type,
+                 "_COMPILE_OPTION");
+      if (target->Target->GetMakefile()->GetDefinition(option_flag)) {
+        return option_flag;
+      }
+    }
+
+    return std::string{};
+  }
+
+  bool GetNewRequiredStandard(cmMakefile* makefile,
+                              std::string const& targetName,
+                              const std::string& feature,
+                              cmProp currentLangStandardValue,
+                              std::string& newRequiredStandard,
+                              std::string* error) const
+  {
+    if (currentLangStandardValue) {
+      newRequiredStandard = *currentLangStandardValue;
+    } else {
+      newRequiredStandard.clear();
+    }
+
+    auto needed = this->HighestStandardNeeded(makefile, feature);
+
+    cmProp existingStandard = currentLangStandardValue;
+    if (existingStandard == nullptr) {
+      cmProp defaultStandard = makefile->GetDef(
+        cmStrCat("CMAKE_", this->Language, "_STANDARD_DEFAULT"));
+      if (cmNonempty(defaultStandard)) {
+        existingStandard = defaultStandard;
+      }
+    }
+
+    auto existingLevelIter = cm::cend(this->Levels);
+    if (existingStandard) {
+      existingLevelIter =
+        std::find(cm::cbegin(this->Levels), cm::cend(this->Levels),
+                  std::stoi(*existingStandard));
+      if (existingLevelIter == cm::cend(this->Levels)) {
+        const std::string e =
+          cmStrCat("The ", this->Language, "_STANDARD property on target \"",
+                   targetName, "\" contained an invalid value: \"",
+                   *existingStandard, "\".");
+        if (error) {
+          *error = e;
+        } else {
+          makefile->IssueMessage(MessageType::FATAL_ERROR, e);
+        }
+        return false;
+      }
+    }
+
+    if (needed.index != -1) {
+      // Ensure the C++ language level is high enough to support
+      // the needed C++ features.
+      if (existingLevelIter == cm::cend(this->Levels) ||
+          existingLevelIter < this->Levels.begin() + needed.index) {
+        newRequiredStandard = this->LevelsAsStrings[needed.index];
+      }
+    }
+
+    return true;
+  }
+
+  bool HaveStandardAvailable(cmMakefile* makefile,
+                             cmGeneratorTarget const* target,
+                             std::string const& config,
+                             std::string const& feature) const
+  {
+    cmProp defaultStandard = makefile->GetDef(
+      cmStrCat("CMAKE_", this->Language, "_STANDARD_DEFAULT"));
+    if (!defaultStandard) {
+      makefile->IssueMessage(
+        MessageType::INTERNAL_ERROR,
+        cmStrCat("CMAKE_", this->Language,
+                 "_STANDARD_DEFAULT is not set.  COMPILE_FEATURES support "
+                 "not fully configured for this compiler."));
+      // Return true so the caller does not try to lookup the default standard.
+      return true;
+    }
+    // convert defaultStandard to an integer
+    if (std::find(cm::cbegin(this->Levels), cm::cend(this->Levels),
+                  std::stoi(*defaultStandard)) == cm::cend(this->Levels)) {
+      const std::string e = cmStrCat("The CMAKE_", this->Language,
+                                     "_STANDARD_DEFAULT variable contains an "
+                                     "invalid value: \"",
+                                     *defaultStandard, "\".");
+      makefile->IssueMessage(MessageType::INTERNAL_ERROR, e);
+      return false;
+    }
+
+    cmProp existingStandard =
+      target->GetLanguageStandard(this->Language, config);
+    if (!existingStandard) {
+      existingStandard = defaultStandard;
+    }
+
+    auto existingLevelIter =
+      std::find(cm::cbegin(this->Levels), cm::cend(this->Levels),
+                std::stoi(*existingStandard));
+    if (existingLevelIter == cm::cend(this->Levels)) {
+      const std::string e =
+        cmStrCat("The ", this->Language, "_STANDARD property on target \"",
+                 target->GetName(), "\" contained an invalid value: \"",
+                 *existingStandard, "\".");
+      makefile->IssueMessage(MessageType::FATAL_ERROR, e);
+      return false;
+    }
+
+    auto needed = this->HighestStandardNeeded(makefile, feature);
+
+    return (needed.index == -1) ||
+      (this->Levels.begin() + needed.index) <= existingLevelIter;
+  }
+
+  StandardNeeded HighestStandardNeeded(cmMakefile* makefile,
+                                       std::string const& feature) const
+  {
+    std::string prefix = cmStrCat("CMAKE_", this->Language);
+    StandardNeeded maxLevel = { -1, -1 };
+    for (size_t i = 0; i < this->Levels.size(); ++i) {
+      if (const char* prop = makefile->GetDefinition(
+            cmStrCat(prefix, this->LevelsAsStrings[i], "_COMPILE_FEATURES"))) {
+        std::vector<std::string> props = cmExpandedList(prop);
+        if (cm::contains(props, feature)) {
+          maxLevel = { static_cast<int>(i), this->Levels[i] };
+        }
+      }
+    }
+    return maxLevel;
+  }
+
+  bool IsLaterStandard(int lhs, int rhs) const
+  {
+    auto rhsIt =
+      std::find(cm::cbegin(this->Levels), cm::cend(this->Levels), rhs);
+
+    return std::find(rhsIt, cm::cend(this->Levels), lhs) !=
+      cm::cend(this->Levels);
+  }
+
+  std::string Language;
+  std::vector<int> Levels;
+  std::vector<std::string> LevelsAsStrings;
+};
+
+std::unordered_map<std::string, StanardLevelComputer> StandardComputerMapping =
+  {
+    { "C",
+      StanardLevelComputer{ "C", std::vector<int>{ 90, 99, 11 },
+                            std::vector<std::string>{ "90", "99", "11" } } },
+    { "CXX",
+      StanardLevelComputer{
+        "CXX", std::vector<int>{ 98, 11, 14, 17, 20 },
+        std::vector<std::string>{ "98", "11", "14", "17", "20" } } },
+    { "CUDA",
+      StanardLevelComputer{
+        "CUDA", std::vector<int>{ 03, 11, 14, 17, 20 },
+        std::vector<std::string>{ "03", "11", "14", "17", "20" } } },
+    { "OBJC",
+      StanardLevelComputer{ "OBJC", std::vector<int>{ 90, 99, 11 },
+                            std::vector<std::string>{ "90", "99", "11" } } },
+    { "OBJCXX",
+      StanardLevelComputer{
+        "OBJCXX", std::vector<int>{ 98, 11, 14, 17, 20 },
+        std::vector<std::string>{ "98", "11", "14", "17", "20" } } },
+  };
+}
+
+std::string cmStandardLevelResolver::GetCompileOptionDef(
+  cmGeneratorTarget const* target, std::string const& lang,
+  std::string const& config) const
+{
+  const auto& mapping = StandardComputerMapping.find(lang);
+  if (mapping == cm::cend(StandardComputerMapping)) {
+    return std::string{};
+  }
+
+  return mapping->second.GetCompileOptionDef(this->Makefile, target, config);
+}
+
+bool cmStandardLevelResolver::AddRequiredTargetFeature(
+  cmTarget* target, const std::string& feature, std::string* error) const
+{
+  if (cmGeneratorExpression::Find(feature) != std::string::npos) {
+    target->AppendProperty("COMPILE_FEATURES", feature);
+    return true;
+  }
+
+  std::string lang;
+  if (!this->CheckCompileFeaturesAvailable(target->GetName(), feature, lang,
+                                           error)) {
+    return false;
+  }
+
+  target->AppendProperty("COMPILE_FEATURES", feature);
+
+  // FIXME: Add a policy to avoid updating the <LANG>_STANDARD target
+  // property due to COMPILE_FEATURES.  The language standard selection
+  // should be done purely at generate time based on whatever the project
+  // code put in these properties explicitly.  That is mostly true now,
+  // but for compatibility we need to continue updating the property here.
+  std::string newRequiredStandard;
+  bool newRequired = this->GetNewRequiredStandard(
+    target->GetName(), feature,
+    target->GetProperty(cmStrCat(lang, "_STANDARD")), newRequiredStandard,
+    error);
+  if (!newRequiredStandard.empty()) {
+    target->SetProperty(cmStrCat(lang, "_STANDARD"), newRequiredStandard);
+  }
+  return newRequired;
+}
+
+bool cmStandardLevelResolver::CheckCompileFeaturesAvailable(
+  const std::string& targetName, const std::string& feature, std::string& lang,
+  std::string* error) const
+{
+  if (!this->CompileFeatureKnown(targetName, feature, lang, error)) {
+    return false;
+  }
+
+  const char* features = this->CompileFeaturesAvailable(lang, error);
+  if (!features) {
+    return false;
+  }
+
+  std::vector<std::string> availableFeatures = cmExpandedList(features);
+  if (!cm::contains(availableFeatures, feature)) {
+    std::ostringstream e;
+    e << "The compiler feature \"" << feature << "\" is not known to " << lang
+      << " compiler\n\""
+      << this->Makefile->GetDefinition("CMAKE_" + lang + "_COMPILER_ID")
+      << "\"\nversion "
+      << this->Makefile->GetDefinition("CMAKE_" + lang + "_COMPILER_VERSION")
+      << ".";
+    if (error) {
+      *error = e.str();
+    } else {
+      this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+    }
+    return false;
+  }
+
+  return true;
+}
+
+bool cmStandardLevelResolver::CompileFeatureKnown(
+  const std::string& targetName, const std::string& feature, std::string& lang,
+  std::string* error) const
+{
+  assert(cmGeneratorExpression::Find(feature) == std::string::npos);
+
+  bool isCFeature =
+    std::find_if(cm::cbegin(C_FEATURES) + 1, cm::cend(C_FEATURES),
+                 cmStrCmp(feature)) != cm::cend(C_FEATURES);
+  if (isCFeature) {
+    lang = "C";
+    return true;
+  }
+  bool isCxxFeature =
+    std::find_if(cm::cbegin(CXX_FEATURES) + 1, cm::cend(CXX_FEATURES),
+                 cmStrCmp(feature)) != cm::cend(CXX_FEATURES);
+  if (isCxxFeature) {
+    lang = "CXX";
+    return true;
+  }
+  bool isCudaFeature =
+    std::find_if(cm::cbegin(CUDA_FEATURES) + 1, cm::cend(CUDA_FEATURES),
+                 cmStrCmp(feature)) != cm::cend(CUDA_FEATURES);
+  if (isCudaFeature) {
+    lang = "CUDA";
+    return true;
+  }
+  std::ostringstream e;
+  if (error) {
+    e << "specified";
+  } else {
+    e << "Specified";
+  }
+  e << " unknown feature \"" << feature
+    << "\" for "
+       "target \""
+    << targetName << "\".";
+  if (error) {
+    *error = e.str();
+  } else {
+    this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+  }
+  return false;
+}
+
+const char* cmStandardLevelResolver::CompileFeaturesAvailable(
+  const std::string& lang, std::string* error) const
+{
+  if (!this->Makefile->GetGlobalGenerator()->GetLanguageEnabled(lang)) {
+    std::ostringstream e;
+    if (error) {
+      e << "cannot";
+    } else {
+      e << "Cannot";
+    }
+    e << " use features from non-enabled language " << lang;
+    if (error) {
+      *error = e.str();
+    } else {
+      this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+    }
+    return nullptr;
+  }
+
+  const char* featuresKnown =
+    this->Makefile->GetDefinition("CMAKE_" + lang + "_COMPILE_FEATURES");
+
+  if (!cmNonempty(featuresKnown)) {
+    std::ostringstream e;
+    if (error) {
+      e << "no";
+    } else {
+      e << "No";
+    }
+    e << " known features for " << lang << " compiler\n\""
+      << this->Makefile->GetSafeDefinition("CMAKE_" + lang + "_COMPILER_ID")
+      << "\"\nversion "
+      << this->Makefile->GetSafeDefinition("CMAKE_" + lang +
+                                           "_COMPILER_VERSION")
+      << ".";
+    if (error) {
+      *error = e.str();
+    } else {
+      this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+    }
+    return nullptr;
+  }
+  return featuresKnown;
+}
+
+bool cmStandardLevelResolver::GetNewRequiredStandard(
+  const std::string& targetName, const std::string& feature,
+  cmProp currentLangStandardValue, std::string& newRequiredStandard,
+  std::string* error) const
+{
+  std::string lang;
+  if (!this->CheckCompileFeaturesAvailable(targetName, feature, lang, error)) {
+    return false;
+  }
+
+  auto mapping = StandardComputerMapping.find(lang);
+  if (mapping != cm::cend(StandardComputerMapping)) {
+    return mapping->second.GetNewRequiredStandard(
+      this->Makefile, targetName, feature, currentLangStandardValue,
+      newRequiredStandard, error);
+  }
+  return false;
+}
+
+bool cmStandardLevelResolver::HaveStandardAvailable(
+  cmGeneratorTarget const* target, std::string const& lang,
+  std::string const& config, const std::string& feature) const
+{
+  auto mapping = StandardComputerMapping.find(lang);
+  if (mapping != cm::cend(StandardComputerMapping)) {
+    return mapping->second.HaveStandardAvailable(this->Makefile, target,
+                                                 config, feature);
+  }
+  return false;
+}
+
+bool cmStandardLevelResolver::IsLaterStandard(std::string const& lang,
+                                              std::string const& lhs,
+                                              std::string const& rhs) const
+{
+  auto mapping = StandardComputerMapping.find(lang);
+  if (mapping != cm::cend(StandardComputerMapping)) {
+    return mapping->second.IsLaterStandard(std::stoi(lhs), std::stoi(rhs));
+  }
+  return false;
+}
diff --git a/Source/cmStandardLevelResolver.h b/Source/cmStandardLevelResolver.h
new file mode 100644
index 0000000..959a5f9
--- /dev/null
+++ b/Source/cmStandardLevelResolver.h
@@ -0,0 +1,59 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file Copyright.txt or https://cmake.org/licensing for details.  */
+#ifndef cmStandardLevelResolver_h
+#define cmStandardLevelResolver_h
+
+#include <string>
+
+#include "cmProperty.h"
+
+class cmMakefile;
+class cmGeneratorTarget;
+class cmTarget;
+
+class cmStandardLevelResolver
+{
+
+public:
+  explicit cmStandardLevelResolver(cmMakefile* makefile)
+    : Makefile(makefile)
+  {
+  }
+
+  std::string GetCompileOptionDef(cmGeneratorTarget const* target,
+                                  std::string const& lang,
+                                  std::string const& config) const;
+
+  bool AddRequiredTargetFeature(cmTarget* target, const std::string& feature,
+                                std::string* error = nullptr) const;
+
+  bool CompileFeatureKnown(const std::string& targetName,
+                           const std::string& feature, std::string& lang,
+                           std::string* error) const;
+
+  const char* CompileFeaturesAvailable(const std::string& lang,
+                                       std::string* error) const;
+
+  bool GetNewRequiredStandard(const std::string& targetName,
+                              const std::string& feature,
+                              cmProp currentLangStandardValue,
+                              std::string& newRequiredStandard,
+                              std::string* error = nullptr) const;
+
+  bool HaveStandardAvailable(cmGeneratorTarget const* target,
+                             std::string const& lang,
+                             std::string const& config,
+                             const std::string& feature) const;
+
+  bool IsLaterStandard(std::string const& lang, std::string const& lhs,
+                       std::string const& rhs) const;
+
+private:
+  bool CheckCompileFeaturesAvailable(const std::string& targetName,
+                                     const std::string& feature,
+                                     std::string& lang,
+                                     std::string* error) const;
+
+  cmMakefile* Makefile;
+};
+#endif
diff --git a/Source/cmState.cxx b/Source/cmState.cxx
index 0b6b40f..73f166c 100644
--- a/Source/cmState.cxx
+++ b/Source/cmState.cxx
@@ -623,8 +623,7 @@
 
 bool cmState::GetGlobalPropertyAsBool(const std::string& prop)
 {
-  cmProp p = this->GetGlobalProperty(prop);
-  return p && cmIsOn(*p);
+  return cmIsOn(this->GetGlobalProperty(prop));
 }
 
 void cmState::SetSourceDirectory(std::string const& sourceDirectory)
diff --git a/Source/cmStateDirectory.cxx b/Source/cmStateDirectory.cxx
index a4fe663..796bb1f 100644
--- a/Source/cmStateDirectory.cxx
+++ b/Source/cmStateDirectory.cxx
@@ -648,8 +648,7 @@
 
 bool cmStateDirectory::GetPropertyAsBool(const std::string& prop) const
 {
-  cmProp p = this->GetProperty(prop);
-  return p && cmIsOn(*p);
+  return cmIsOn(this->GetProperty(prop));
 }
 
 std::vector<std::string> cmStateDirectory::GetPropertyKeys() const
diff --git a/Source/cmStateSnapshot.cxx b/Source/cmStateSnapshot.cxx
index c223431..bf8e331 100644
--- a/Source/cmStateSnapshot.cxx
+++ b/Source/cmStateSnapshot.cxx
@@ -148,7 +148,7 @@
 
 bool cmStateSnapshot::CanPopPolicyScope()
 {
-  return this->Position->Policies == this->Position->PolicyScope;
+  return this->Position->Policies != this->Position->PolicyScope;
 }
 
 void cmStateSnapshot::SetPolicy(cmPolicies::PolicyID id,
@@ -232,11 +232,6 @@
   this->Position->Vars->Unset(name);
 }
 
-std::vector<std::string> cmStateSnapshot::UnusedKeys() const
-{
-  return this->Position->Vars->UnusedKeys();
-}
-
 std::vector<std::string> cmStateSnapshot::ClosureKeys() const
 {
   return cmDefinitions::ClosureKeys(this->Position->Vars,
@@ -328,7 +323,7 @@
 #if defined(__CYGWIN__)
   std::string legacy;
   if (cmSystemTools::GetEnv("CMAKE_LEGACY_CYGWIN_WIN32", legacy) &&
-      cmIsOn(legacy.c_str())) {
+      cmIsOn(legacy)) {
     this->SetDefinition("WIN32", "1");
     this->SetDefinition("CMAKE_HOST_WIN32", "1");
   }
diff --git a/Source/cmStateSnapshot.h b/Source/cmStateSnapshot.h
index 021fd53..c19f174 100644
--- a/Source/cmStateSnapshot.h
+++ b/Source/cmStateSnapshot.h
@@ -28,7 +28,6 @@
   bool IsInitialized(std::string const& name) const;
   void SetDefinition(std::string const& name, cm::string_view value);
   void RemoveDefinition(std::string const& name);
-  std::vector<std::string> UnusedKeys() const;
   std::vector<std::string> ClosureKeys() const;
   bool RaiseScope(std::string const& var, const char* varDef);
 
diff --git a/Source/cmString.cxx b/Source/cmString.cxx
index 2a0c125..898b828 100644
--- a/Source/cmString.cxx
+++ b/Source/cmString.cxx
@@ -17,7 +17,7 @@
 void String::internally_mutate_to_stable_string()
 {
   // We assume that only one thread mutates this instance at
-  // a time even if we point to a shared string buffer refernced
+  // a time even if we point to a shared string buffer referenced
   // by other threads.
   *this = String(data(), size());
 }
diff --git a/Source/cmString.hxx b/Source/cmString.hxx
index 87bfdff..40fe20d 100644
--- a/Source/cmString.hxx
+++ b/Source/cmString.hxx
@@ -383,7 +383,7 @@
       instance is mutated or destroyed.  */
   std::string const* str_if_stable() const;
 
-  /** Get a refernce to a normal std::string.  The reference
+  /** Get a reference to a normal std::string.  The reference
       is valid until this instance is mutated or destroyed.  */
   std::string const& str();
 
diff --git a/Source/cmStringAlgorithms.h b/Source/cmStringAlgorithms.h
index a5ecca7..4b0090b 100644
--- a/Source/cmStringAlgorithms.h
+++ b/Source/cmStringAlgorithms.h
@@ -20,6 +20,20 @@
 /** String range type.  */
 using cmStringRange = cmRange<std::vector<std::string>::const_iterator>;
 
+/** Check for non-empty string.  */
+inline bool cmNonempty(const char* str)
+{
+  return str && *str;
+}
+inline bool cmNonempty(cm::string_view str)
+{
+  return !str.empty();
+}
+inline bool cmNonempty(std::string const* str)
+{
+  return str && !str->empty();
+}
+
 /** Callable string comparison struct.  */
 struct cmStrCmp
 {
@@ -205,10 +219,11 @@
 bool cmIsOn(cm::string_view val);
 inline bool cmIsOn(const char* val)
 {
-  if (!val) {
-    return false;
-  }
-  return cmIsOn(cm::string_view(val));
+  return val && cmIsOn(cm::string_view(val));
+}
+inline bool cmIsOn(std::string const* val)
+{
+  return val && cmIsOn(*val);
 }
 
 /**
@@ -221,10 +236,11 @@
 bool cmIsOff(cm::string_view val);
 inline bool cmIsOff(const char* val)
 {
-  if (!val) {
-    return true;
-  }
-  return cmIsOff(cm::string_view(val));
+  return !val || cmIsOff(cm::string_view(val));
+}
+inline bool cmIsOff(std::string const* val)
+{
+  return !val || cmIsOff(*val);
 }
 
 /** Returns true if string @a str starts with the character @a prefix.  */
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index 1e78d36..798c29a 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -1213,7 +1213,7 @@
 {
 #  if !defined(HAVE_UNSETENV)
   std::string var = cmStrCat(value, '=');
-  return cmSystemTools::PutEnv(var.c_str());
+  return cmSystemTools::PutEnv(var);
 #  else
   unsetenv(value);
   return true;
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 36e1ad5..51b4e9e 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -7,6 +7,7 @@
 #include <cstring>
 #include <initializer_list>
 #include <iterator>
+#include <map>
 #include <set>
 #include <sstream>
 #include <unordered_set>
@@ -185,6 +186,7 @@
   std::vector<cmInstallTargetGenerator*> InstallGenerators;
   std::set<std::string> SystemIncludeDirectories;
   cmTarget::LinkLibraryVectorType OriginalLinkLibraries;
+  std::map<std::string, BTs<std::string>> LanguageStandardProperties;
   std::vector<std::string> IncludeDirectoriesEntries;
   std::vector<cmListFileBacktrace> IncludeDirectoriesBacktraces;
   std::vector<std::string> CompileOptionsEntries;
@@ -214,6 +216,15 @@
   std::string ProcessSourceItemCMP0049(const std::string& s);
 };
 
+namespace {
+#define SETUP_COMMON_LANGUAGE_PROPERTIES(lang)                                \
+  initProp(#lang "_COMPILER_LAUNCHER");                                       \
+  initProp(#lang "_STANDARD");                                                \
+  initProp(#lang "_STANDARD_REQUIRED");                                       \
+  initProp(#lang "_EXTENSIONS");                                              \
+  initProp(#lang "_VISIBILITY_PRESET")
+}
+
 cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
                    Visibility vis, cmMakefile* mf, PerConfig perConfig)
   : impl(cm::make_unique<cmTargetInternals>())
@@ -270,8 +281,14 @@
   };
 
   // Setup default property values.
-  if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY &&
-      this->GetType() != cmStateEnums::UTILITY) {
+  if (this->CanCompileSources()) {
+
+    SETUP_COMMON_LANGUAGE_PROPERTIES(C);
+    SETUP_COMMON_LANGUAGE_PROPERTIES(OBJC);
+    SETUP_COMMON_LANGUAGE_PROPERTIES(CXX);
+    SETUP_COMMON_LANGUAGE_PROPERTIES(OBJCXX);
+    SETUP_COMMON_LANGUAGE_PROPERTIES(CUDA);
+
     initProp("ANDROID_API");
     initProp("ANDROID_API_MIN");
     initProp("ANDROID_ARCH");
@@ -333,38 +350,22 @@
     initProp("NO_SYSTEM_FROM_IMPORTED");
     initProp("BUILD_WITH_INSTALL_NAME_DIR");
     initProp("C_CLANG_TIDY");
-    initProp("C_COMPILER_LAUNCHER");
     initProp("C_CPPLINT");
     initProp("C_CPPCHECK");
     initProp("C_INCLUDE_WHAT_YOU_USE");
     initProp("LINK_WHAT_YOU_USE");
-    initProp("C_STANDARD");
-    initProp("C_STANDARD_REQUIRED");
-    initProp("C_EXTENSIONS");
-    initProp("OBJC_COMPILER_LAUNCHER");
-    initProp("OBJC_STANDARD");
-    initProp("OBJC_STANDARD_REQUIRED");
-    initProp("OBJC_EXTENSIONS");
     initProp("CXX_CLANG_TIDY");
-    initProp("CXX_COMPILER_LAUNCHER");
     initProp("CXX_CPPLINT");
     initProp("CXX_CPPCHECK");
     initProp("CXX_INCLUDE_WHAT_YOU_USE");
-    initProp("CXX_STANDARD");
-    initProp("CXX_STANDARD_REQUIRED");
-    initProp("CXX_EXTENSIONS");
-    initProp("OBJCXX_COMPILER_LAUNCHER");
-    initProp("OBJCXX_STANDARD");
-    initProp("OBJCXX_STANDARD_REQUIRED");
-    initProp("OBJCXX_EXTENSIONS");
-    initProp("CUDA_STANDARD");
-    initProp("CUDA_STANDARD_REQUIRED");
-    initProp("CUDA_EXTENSIONS");
-    initProp("CUDA_COMPILER_LAUNCHER");
     initProp("CUDA_SEPARABLE_COMPILATION");
     initProp("CUDA_RESOLVE_DEVICE_SYMBOLS");
     initProp("CUDA_RUNTIME_LIBRARY");
     initProp("CUDA_ARCHITECTURES");
+    initProp("VISIBILITY_INLINES_HIDDEN");
+    initProp("JOB_POOL_COMPILE");
+    initProp("JOB_POOL_LINK");
+    initProp("JOB_POOL_PRECOMPILE_HEADER");
     initProp("LINK_SEARCH_START_STATIC");
     initProp("LINK_SEARCH_END_STATIC");
     initProp("Swift_LANGUAGE_VERSION");
@@ -375,6 +376,7 @@
     initPropValue("UNITY_BUILD_BATCH_SIZE", "8");
     initPropValue("UNITY_BUILD_MODE", "BATCH");
     initPropValue("PCH_WARN_INVALID", "ON");
+
 #ifdef __APPLE__
     if (this->GetGlobalGenerator()->IsXcode()) {
       initProp("XCODE_SCHEME_ADDRESS_SANITIZER");
@@ -399,16 +401,15 @@
 #endif
   }
 
-  if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY) {
-    initProp("FOLDER");
+  initProp("FOLDER");
 
-    if (this->GetGlobalGenerator()->IsXcode()) {
-      initProp("XCODE_GENERATE_SCHEME");
-    }
+  if (this->GetGlobalGenerator()->IsXcode()) {
+    initProp("XCODE_GENERATE_SCHEME");
   }
 
   // Setup per-configuration property default values.
-  if (this->GetType() != cmStateEnums::UTILITY) {
+  if (this->GetType() != cmStateEnums::UTILITY &&
+      this->GetType() != cmStateEnums::GLOBAL_TARGET) {
     static const auto configProps = {
       /* clang-format needs this comment to break after the opening brace */
       "ARCHIVE_OUTPUT_DIRECTORY_",     "LIBRARY_OUTPUT_DIRECTORY_",
@@ -417,8 +418,8 @@
       "INTERPROCEDURAL_OPTIMIZATION_"
     };
     // Collect the set of configuration types.
-    std::vector<std::string> configNames;
-    mf->GetConfigurations(configNames);
+    std::vector<std::string> configNames =
+      mf->GetGeneratorConfigs(cmMakefile::ExcludeEmptyConfig);
     for (std::string const& configName : configNames) {
       std::string configUpper = cmSystemTools::UpperCase(configName);
       for (auto const& prop : configProps) {
@@ -485,16 +486,6 @@
                impl->Makefile->GetLinkDirectoriesBacktraces());
   }
 
-  if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY &&
-      this->GetType() != cmStateEnums::UTILITY) {
-    initProp("C_VISIBILITY_PRESET");
-    initProp("CXX_VISIBILITY_PRESET");
-    initProp("OBJC_VISIBILITY_PRESET");
-    initProp("OBJCXX_VISIBILITY_PRESET");
-    initProp("CUDA_VISIBILITY_PRESET");
-    initProp("VISIBILITY_INLINES_HIDDEN");
-  }
-
   if (impl->TargetType == cmStateEnums::EXECUTABLE) {
     initProp("ANDROID_GUI");
     initProp("CROSSCOMPILING_EMULATOR");
@@ -503,6 +494,8 @@
   if (impl->TargetType == cmStateEnums::SHARED_LIBRARY ||
       impl->TargetType == cmStateEnums::MODULE_LIBRARY) {
     this->SetProperty("POSITION_INDEPENDENT_CODE", "True");
+  } else if (this->CanCompileSources()) {
+    initProp("POSITION_INDEPENDENT_CODE");
   }
   if (impl->TargetType == cmStateEnums::SHARED_LIBRARY ||
       impl->TargetType == cmStateEnums::EXECUTABLE) {
@@ -510,11 +503,6 @@
     initProp("WINDOWS_EXPORT_ALL_SYMBOLS");
   }
 
-  if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY &&
-      this->GetType() != cmStateEnums::UTILITY) {
-    initProp("POSITION_INDEPENDENT_CODE");
-  }
-
   // Record current policies for later use.
   impl->Makefile->RecordPolicies(impl->PolicyMap);
 
@@ -526,36 +514,26 @@
     impl->PolicyMap.Set(cmPolicies::CMP0022, cmPolicies::NEW);
   }
 
-  if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY &&
-      this->GetType() != cmStateEnums::UTILITY) {
-    initProp("JOB_POOL_COMPILE");
-    initProp("JOB_POOL_LINK");
-    initProp("JOB_POOL_PRECOMPILE_HEADER");
-  }
-
   if (impl->TargetType <= cmStateEnums::GLOBAL_TARGET) {
     initProp("DOTNET_TARGET_FRAMEWORK");
     initProp("DOTNET_TARGET_FRAMEWORK_VERSION");
   }
 
-  if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY) {
-
-    // check for "CMAKE_VS_GLOBALS" variable and set up target properties
-    // if any
-    const char* globals = mf->GetDefinition("CMAKE_VS_GLOBALS");
-    if (globals) {
-      const std::string genName = mf->GetGlobalGenerator()->GetName();
-      if (cmHasLiteralPrefix(genName, "Visual Studio")) {
-        std::vector<std::string> props = cmExpandedList(globals);
-        const std::string vsGlobal = "VS_GLOBAL_";
-        for (const std::string& i : props) {
-          // split NAME=VALUE
-          const std::string::size_type assignment = i.find('=');
-          if (assignment != std::string::npos) {
-            const std::string propName = vsGlobal + i.substr(0, assignment);
-            const std::string propValue = i.substr(assignment + 1);
-            initPropValue(propName, propValue.c_str());
-          }
+  // check for "CMAKE_VS_GLOBALS" variable and set up target properties
+  // if any
+  const char* globals = mf->GetDefinition("CMAKE_VS_GLOBALS");
+  if (globals) {
+    const std::string genName = mf->GetGlobalGenerator()->GetName();
+    if (cmHasLiteralPrefix(genName, "Visual Studio")) {
+      std::vector<std::string> props = cmExpandedList(globals);
+      const std::string vsGlobal = "VS_GLOBAL_";
+      for (const std::string& i : props) {
+        // split NAME=VALUE
+        const std::string::size_type assignment = i.find('=');
+        if (assignment != std::string::npos) {
+          const std::string propName = vsGlobal + i.substr(0, assignment);
+          const std::string propValue = i.substr(assignment + 1);
+          initPropValue(propName, propValue.c_str());
         }
       }
     }
@@ -598,6 +576,40 @@
   return impl->Makefile->GetGlobalGenerator();
 }
 
+BTs<std::string> const* cmTarget::GetLanguageStandardProperty(
+  const std::string& propertyName) const
+{
+  auto entry = impl->LanguageStandardProperties.find(propertyName);
+  if (entry != impl->LanguageStandardProperties.end()) {
+    return &entry->second;
+  }
+
+  return nullptr;
+}
+
+void cmTarget::SetLanguageStandardProperty(std::string const& lang,
+                                           std::string const& value,
+                                           const std::string& feature)
+{
+  cmListFileBacktrace featureBacktrace;
+  for (size_t i = 0; i < impl->CompileFeaturesEntries.size(); i++) {
+    if (impl->CompileFeaturesEntries[i] == feature) {
+      if (i < impl->CompileFeaturesBacktraces.size()) {
+        featureBacktrace = impl->CompileFeaturesBacktraces[i];
+      }
+      break;
+    }
+  }
+
+  BTs<std::string>& languageStandardProperty =
+    impl->LanguageStandardProperties[cmStrCat(lang, "_STANDARD")];
+  if (languageStandardProperty.Value != value) {
+    languageStandardProperty.Value = value;
+    languageStandardProperty.Backtraces.clear();
+  }
+  languageStandardProperty.Backtraces.emplace_back(featureBacktrace);
+}
+
 void cmTarget::AddUtility(std::string const& name, bool cross, cmMakefile* mf)
 {
   impl->Utilities.insert(BT<std::pair<std::string, bool>>(
@@ -636,6 +648,12 @@
           this->GetPropertyAsBool("MACOSX_BUNDLE"));
 }
 
+bool cmTarget::IsAndroidGuiExecutable() const
+{
+  return (this->GetType() == cmStateEnums::EXECUTABLE && impl->IsAndroid &&
+          this->GetPropertyAsBool("ANDROID_GUI"));
+}
+
 std::vector<cmCustomCommand> const& cmTarget::GetPreBuildCommands() const
 {
   return impl->PreBuildCommands;
@@ -1121,12 +1139,12 @@
 
 void cmTarget::SetProperty(const std::string& prop, const char* value)
 {
-  if (!cmTargetPropertyComputer::PassesWhitelist(
-        this->GetType(), prop, impl->Makefile->GetMessenger(),
-        impl->Makefile->GetBacktrace())) {
-    return;
-  }
 #define MAKE_STATIC_PROP(PROP) static const std::string prop##PROP = #PROP
+  MAKE_STATIC_PROP(C_STANDARD);
+  MAKE_STATIC_PROP(CXX_STANDARD);
+  MAKE_STATIC_PROP(CUDA_STANDARD);
+  MAKE_STATIC_PROP(OBJC_STANDARD);
+  MAKE_STATIC_PROP(OBJCXX_STANDARD);
   MAKE_STATIC_PROP(COMPILE_DEFINITIONS);
   MAKE_STATIC_PROP(COMPILE_FEATURES);
   MAKE_STATIC_PROP(COMPILE_OPTIONS);
@@ -1310,6 +1328,15 @@
     cmProp tmp = reusedTarget->GetProperty("COMPILE_PDB_NAME");
     this->SetProperty("COMPILE_PDB_NAME", tmp ? tmp->c_str() : nullptr);
     this->AddUtility(reusedFrom, false, impl->Makefile);
+  } else if (prop == propC_STANDARD || prop == propCXX_STANDARD ||
+             prop == propCUDA_STANDARD || prop == propOBJC_STANDARD ||
+             prop == propOBJCXX_STANDARD) {
+    if (value) {
+      impl->LanguageStandardProperties[prop] =
+        BTs<std::string>(value, impl->Makefile->GetBacktrace());
+    } else {
+      impl->LanguageStandardProperties.erase(prop);
+    }
   } else {
     impl->Properties.SetProperty(prop, value);
   }
@@ -1318,11 +1345,6 @@
 void cmTarget::AppendProperty(const std::string& prop,
                               const std::string& value, bool asString)
 {
-  if (!cmTargetPropertyComputer::PassesWhitelist(
-        this->GetType(), prop, impl->Makefile->GetMessenger(),
-        impl->Makefile->GetBacktrace())) {
-    return;
-  }
   if (prop == "NAME") {
     impl->Makefile->IssueMessage(MessageType::FATAL_ERROR,
                                  "NAME property is read-only\n");
@@ -1413,6 +1435,11 @@
   } else if (cmHasLiteralPrefix(prop, "IMPORTED_LIBNAME")) {
     impl->Makefile->IssueMessage(MessageType::FATAL_ERROR,
                                  prop + " property may not be APPENDed.");
+  } else if (prop == "C_STANDARD" || prop == "CXX_STANDARD" ||
+             prop == "CUDA_STANDARD" || prop == "OBJC_STANDARD" ||
+             prop == "OBJCXX_STANDARD") {
+    impl->Makefile->IssueMessage(MessageType::FATAL_ERROR,
+                                 prop + " property may not be appended.");
   } else {
     impl->Properties.AppendProperty(prop, value, asString);
   }
@@ -1626,6 +1653,11 @@
 cmProp cmTarget::GetProperty(const std::string& prop) const
 {
 #define MAKE_STATIC_PROP(PROP) static const std::string prop##PROP = #PROP
+  MAKE_STATIC_PROP(C_STANDARD);
+  MAKE_STATIC_PROP(CXX_STANDARD);
+  MAKE_STATIC_PROP(CUDA_STANDARD);
+  MAKE_STATIC_PROP(OBJC_STANDARD);
+  MAKE_STATIC_PROP(OBJCXX_STANDARD);
   MAKE_STATIC_PROP(LINK_LIBRARIES);
   MAKE_STATIC_PROP(TYPE);
   MAKE_STATIC_PROP(INCLUDE_DIRECTORIES);
@@ -1646,6 +1678,11 @@
   MAKE_STATIC_PROP(TRUE);
 #undef MAKE_STATIC_PROP
   static std::unordered_set<std::string> const specialProps{
+    propC_STANDARD,
+    propCXX_STANDARD,
+    propCUDA_STANDARD,
+    propOBJC_STANDARD,
+    propOBJCXX_STANDARD,
     propLINK_LIBRARIES,
     propTYPE,
     propINCLUDE_DIRECTORIES,
@@ -1664,6 +1701,15 @@
     propSOURCES
   };
   if (specialProps.count(prop)) {
+    if (prop == propC_STANDARD || prop == propCXX_STANDARD ||
+        prop == propCUDA_STANDARD || prop == propOBJC_STANDARD ||
+        prop == propOBJCXX_STANDARD) {
+      auto propertyIter = impl->LanguageStandardProperties.find(prop);
+      if (propertyIter == impl->LanguageStandardProperties.end()) {
+        return nullptr;
+      }
+      return &(propertyIter->second.Value);
+    }
     if (prop == propLINK_LIBRARIES) {
       if (impl->LinkImplementationPropertyEntries.empty()) {
         return nullptr;
@@ -1804,8 +1850,7 @@
 
 bool cmTarget::GetPropertyAsBool(const std::string& prop) const
 {
-  cmProp p = this->GetProperty(prop);
-  return p && cmIsOn(*p);
+  return cmIsOn(this->GetProperty(prop));
 }
 
 cmPropertyMap const& cmTarget::GetProperties() const
@@ -1838,6 +1883,27 @@
   return impl->PerConfig;
 }
 
+bool cmTarget::CanCompileSources() const
+{
+  if (this->IsImported()) {
+    return false;
+  }
+  switch (this->GetType()) {
+    case cmStateEnums::EXECUTABLE:
+    case cmStateEnums::STATIC_LIBRARY:
+    case cmStateEnums::SHARED_LIBRARY:
+    case cmStateEnums::MODULE_LIBRARY:
+    case cmStateEnums::OBJECT_LIBRARY:
+      return true;
+    case cmStateEnums::UTILITY:
+    case cmStateEnums::INTERFACE_LIBRARY:
+    case cmStateEnums::GLOBAL_TARGET:
+    case cmStateEnums::UNKNOWN_LIBRARY:
+      break;
+  }
+  return false;
+}
+
 const char* cmTarget::GetSuffixVariableInternal(
   cmStateEnums::ArtifactType artifact) const
 {
@@ -1865,7 +1931,7 @@
         case cmStateEnums::RuntimeBinaryArtifact:
           // Android GUI application packages store the native
           // binary as a shared library.
-          return (impl->IsAndroid && this->GetPropertyAsBool("ANDROID_GUI")
+          return (this->IsAndroidGuiExecutable()
                     ? "CMAKE_SHARED_LIBRARY_SUFFIX"
                     : "CMAKE_EXECUTABLE_SUFFIX");
         case cmStateEnums::ImportLibraryArtifact:
@@ -1906,7 +1972,7 @@
         case cmStateEnums::RuntimeBinaryArtifact:
           // Android GUI application packages store the native
           // binary as a shared library.
-          return (impl->IsAndroid && this->GetPropertyAsBool("ANDROID_GUI")
+          return (this->IsAndroidGuiExecutable()
                     ? "CMAKE_SHARED_LIBRARY_PREFIX"
                     : "");
         case cmStateEnums::ImportLibraryArtifact:
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index f0ddb68..43f1887 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -196,6 +196,7 @@
   bool IsImported() const;
   bool IsImportedGloballyVisible() const;
   bool IsPerConfig() const;
+  bool CanCompileSources() const;
 
   bool GetMappedConfig(std::string const& desired_config, cmProp& loc,
                        cmProp& imp, std::string& suffix) const;
@@ -209,6 +210,9 @@
   //! Return whether this target is an executable Bundle on Apple.
   bool IsAppBundleOnApple() const;
 
+  //! Return whether this target is a GUI executable on Android.
+  bool IsAndroidGuiExecutable() const;
+
   //! Get a backtrace from the creation of the target.
   cmListFileBacktrace const& GetBacktrace() const;
 
@@ -233,6 +237,13 @@
   void AddSystemIncludeDirectories(std::set<std::string> const& incs);
   std::set<std::string> const& GetSystemIncludeDirectories() const;
 
+  BTs<std::string> const* GetLanguageStandardProperty(
+    const std::string& propertyName) const;
+
+  void SetLanguageStandardProperty(std::string const& lang,
+                                   std::string const& value,
+                                   const std::string& feature);
+
   cmStringRange GetIncludeDirectoriesEntries() const;
   cmBacktraceRange GetIncludeDirectoriesBacktraces() const;
 
diff --git a/Source/cmTargetCompileFeaturesCommand.cxx b/Source/cmTargetCompileFeaturesCommand.cxx
index 06be4f0..aa1abdd 100644
--- a/Source/cmTargetCompileFeaturesCommand.cxx
+++ b/Source/cmTargetCompileFeaturesCommand.cxx
@@ -4,6 +4,7 @@
 
 #include "cmMakefile.h"
 #include "cmMessageType.h"
+#include "cmStandardLevelResolver.h"
 #include "cmStringAlgorithms.h"
 #include "cmTargetPropCommandBase.h"
 
@@ -29,9 +30,10 @@
                            const std::vector<std::string>& content,
                            bool /*prepend*/, bool /*system*/) override
   {
+    cmStandardLevelResolver standardResolver(this->Makefile);
     for (std::string const& it : content) {
       std::string error;
-      if (!this->Makefile->AddRequiredTargetFeature(tgt, it, &error)) {
+      if (!standardResolver.AddRequiredTargetFeature(tgt, it, &error)) {
         this->SetError(error);
         return false; // Not (successfully) handled.
       }
diff --git a/Source/cmTargetPropCommandBase.cxx b/Source/cmTargetPropCommandBase.cxx
index e714720..9e30136 100644
--- a/Source/cmTargetPropCommandBase.cxx
+++ b/Source/cmTargetPropCommandBase.cxx
@@ -123,7 +123,7 @@
   }
   if (!content.empty()) {
     if (this->Target->GetType() == cmStateEnums::INTERFACE_LIBRARY &&
-        scope != "INTERFACE") {
+        scope != "INTERFACE" && this->Property != "SOURCES") {
       this->SetError("may only set INTERFACE properties on INTERFACE targets");
       return false;
     }
diff --git a/Source/cmTargetPropertyComputer.cxx b/Source/cmTargetPropertyComputer.cxx
index f37995c..b9c9365 100644
--- a/Source/cmTargetPropertyComputer.cxx
+++ b/Source/cmTargetPropertyComputer.cxx
@@ -3,15 +3,12 @@
 
 #include "cmTargetPropertyComputer.h"
 
-#include <cctype>
 #include <sstream>
-#include <unordered_set>
 
 #include "cmMessageType.h"
 #include "cmMessenger.h"
 #include "cmPolicies.h"
 #include "cmStateSnapshot.h"
-#include "cmStringAlgorithms.h"
 
 bool cmTargetPropertyComputer::HandleLocationPropertyPolicy(
   std::string const& tgtName, cmMessenger* messenger,
@@ -44,69 +41,3 @@
 
   return messageType != MessageType::FATAL_ERROR;
 }
-
-bool cmTargetPropertyComputer::WhiteListedInterfaceProperty(
-  const std::string& prop)
-{
-  if (cmHasLiteralPrefix(prop, "INTERFACE_")) {
-    return true;
-  }
-  if (cmHasLiteralPrefix(prop, "_")) {
-    return true;
-  }
-  if (std::islower(prop[0])) {
-    return true;
-  }
-  static std::unordered_set<std::string> const builtIns{
-    "COMPATIBLE_INTERFACE_BOOL",
-    "COMPATIBLE_INTERFACE_NUMBER_MAX",
-    "COMPATIBLE_INTERFACE_NUMBER_MIN",
-    "COMPATIBLE_INTERFACE_STRING",
-    "DEPRECATION",
-    "EXPORT_NAME",
-    "EXPORT_PROPERTIES",
-    "IMPORTED",
-    "IMPORTED_GLOBAL",
-    "MANUALLY_ADDED_DEPENDENCIES",
-    "NAME",
-    "PRIVATE_HEADER",
-    "PUBLIC_HEADER",
-    "TYPE"
-  };
-
-  if (builtIns.count(prop)) {
-    return true;
-  }
-
-  if (prop == "IMPORTED_CONFIGURATIONS" || prop == "IMPORTED_LIBNAME" ||
-      cmHasLiteralPrefix(prop, "IMPORTED_LIBNAME_") ||
-      cmHasLiteralPrefix(prop, "MAP_IMPORTED_CONFIG_")) {
-    return true;
-  }
-
-  // This property should not be allowed but was incorrectly added in
-  // CMake 3.8.  We can't remove it from the whitelist without breaking
-  // projects that try to set it.  One day we could warn about this, but
-  // for now silently accept it.
-  if (prop == "NO_SYSTEM_FROM_IMPORTED") {
-    return true;
-  }
-
-  return false;
-}
-
-bool cmTargetPropertyComputer::PassesWhitelist(
-  cmStateEnums::TargetType tgtType, std::string const& prop,
-  cmMessenger* messenger, cmListFileBacktrace const& context)
-{
-  if (tgtType == cmStateEnums::INTERFACE_LIBRARY &&
-      !WhiteListedInterfaceProperty(prop)) {
-    std::ostringstream e;
-    e << "INTERFACE_LIBRARY targets may only have whitelisted properties.  "
-         "The property \""
-      << prop << "\" is not allowed.";
-    messenger->IssueMessage(MessageType::FATAL_ERROR, e.str(), context);
-    return false;
-  }
-  return true;
-}
diff --git a/Source/cmTargetPropertyComputer.h b/Source/cmTargetPropertyComputer.h
index f87b7c2..bafa43b 100644
--- a/Source/cmTargetPropertyComputer.h
+++ b/Source/cmTargetPropertyComputer.h
@@ -35,12 +35,6 @@
     return nullptr;
   }
 
-  static bool WhiteListedInterfaceProperty(const std::string& prop);
-
-  static bool PassesWhitelist(cmStateEnums::TargetType tgtType,
-                              std::string const& prop, cmMessenger* messenger,
-                              cmListFileBacktrace const& context);
-
 private:
   static bool HandleLocationPropertyPolicy(std::string const& tgtName,
                                            cmMessenger* messenger,
diff --git a/Source/cmTestGenerator.cxx b/Source/cmTestGenerator.cxx
index af91177..78b230c 100644
--- a/Source/cmTestGenerator.cxx
+++ b/Source/cmTestGenerator.cxx
@@ -102,7 +102,7 @@
 
     // Prepend with the emulator when cross compiling if required.
     cmProp emulator = target->GetProperty("CROSSCOMPILING_EMULATOR");
-    if (emulator != nullptr && !emulator->empty()) {
+    if (cmNonempty(emulator)) {
       std::vector<std::string> emulatorWithArgs = cmExpandedList(*emulator);
       std::string emulatorExe(emulatorWithArgs[0]);
       cmSystemTools::ConvertToUnixSlashes(emulatorExe);
diff --git a/Source/cmTimestamp.cxx b/Source/cmTimestamp.cxx
index 13f73dc..bd6bb3d 100644
--- a/Source/cmTimestamp.cxx
+++ b/Source/cmTimestamp.cxx
@@ -164,7 +164,7 @@
       break;
     case 's': // Seconds since UNIX epoch (midnight 1-jan-1970)
     {
-      // Build a time_t for UNIX epoch and substract from the input "timeT":
+      // Build a time_t for UNIX epoch and subtract from the input "timeT":
       struct tm tmUnixEpoch;
       memset(&tmUnixEpoch, 0, sizeof(tmUnixEpoch));
       tmUnixEpoch.tm_mday = 1;
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index a8e424d..db9dc53 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -232,15 +232,17 @@
   , LocalGenerator(
       (cmLocalVisualStudio10Generator*)target->GetLocalGenerator())
 {
-  this->Makefile->GetConfigurations(this->Configurations);
+  this->Configurations =
+    this->Makefile->GetGeneratorConfigs(cmMakefile::ExcludeEmptyConfig);
   this->NsightTegra = gg->IsNsightTegra();
+  this->Android = gg->TargetsAndroid();
   for (int i = 0; i < 4; ++i) {
     this->NsightTegraVersion[i] = 0;
   }
   sscanf(gg->GetNsightTegraVersion().c_str(), "%u.%u.%u.%u",
          &this->NsightTegraVersion[0], &this->NsightTegraVersion[1],
          &this->NsightTegraVersion[2], &this->NsightTegraVersion[3]);
-  this->MSTools = !this->NsightTegra;
+  this->MSTools = !this->NsightTegra && !this->Android;
   this->Managed = false;
   this->TargetCompileAsWinRT = false;
   this->IsMissingFiles = false;
@@ -313,8 +315,7 @@
 void cmVisualStudio10TargetGenerator::Generate()
 {
   // do not generate external ms projects
-  if (this->GeneratorTarget->GetType() == cmStateEnums::INTERFACE_LIBRARY ||
-      this->GeneratorTarget->GetProperty("EXTERNAL_MSPROJECT")) {
+  if (this->GeneratorTarget->GetProperty("EXTERNAL_MSPROJECT")) {
     return;
   }
   const std::string ProjectFileExtension =
@@ -333,6 +334,13 @@
     this->ProjectType = csproj;
     this->Managed = true;
   }
+
+  if (this->Android &&
+      this->GeneratorTarget->GetType() == cmStateEnums::EXECUTABLE &&
+      !this->GeneratorTarget->Target->IsAndroidGuiExecutable()) {
+    this->GlobalGenerator->AddAndroidExecutableWarning(this->Name);
+  }
+
   // Tell the global generator the name of the project file
   this->GeneratorTarget->Target->SetProperty("GENERATOR_FILE_NAME",
                                              this->Name);
@@ -427,8 +435,8 @@
       e1.Attribute("Label", "Globals");
       e1.Element("ProjectGuid", "{" + this->GUID + "}");
 
-      if (this->MSTools &&
-          this->GeneratorTarget->GetType() <= cmStateEnums::GLOBAL_TARGET) {
+      if ((this->MSTools || this->Android) &&
+          this->GeneratorTarget->IsInBuildSystem()) {
         this->WriteApplicationTypeSettings(e1);
         this->VerifyNecessaryFiles();
       }
@@ -469,7 +477,11 @@
       cmProp vsGlobalKeyword =
         this->GeneratorTarget->GetProperty("VS_GLOBAL_KEYWORD");
       if (!vsGlobalKeyword) {
-        e1.Element("Keyword", "Win32Proj");
+        if (this->GlobalGenerator->TargetsAndroid()) {
+          e1.Element("Keyword", "Android");
+        } else {
+          e1.Element("Keyword", "Win32Proj");
+        }
       } else {
         e1.Element("Keyword", *vsGlobalKeyword);
       }
@@ -592,11 +604,11 @@
             }
             break;
           case cmStateEnums::UTILITY:
+          case cmStateEnums::INTERFACE_LIBRARY:
           case cmStateEnums::GLOBAL_TARGET:
             outputType = "Utility";
             break;
           case cmStateEnums::UNKNOWN_LIBRARY:
-          case cmStateEnums::INTERFACE_LIBRARY:
             break;
         }
         e1.Element("OutputType", outputType);
@@ -658,7 +670,7 @@
           cmStrCat(this->DefaultArtifactDir, "\\nasm.props");
         ConvertToWindowsSlash(propsLocal);
         this->Makefile->ConfigureFile(propsTemplate, propsLocal, false, true,
-                                      true);
+                                      true, true);
         Elem(e1, "Import").Attribute("Project", propsLocal);
       }
     }
@@ -1134,14 +1146,17 @@
             break;
           case cmStateEnums::EXECUTABLE:
             if (this->NsightTegra &&
-                !this->GeneratorTarget->GetPropertyAsBool("ANDROID_GUI")) {
+                !this->GeneratorTarget->Target->IsAndroidGuiExecutable()) {
               // Android executables are .so too.
               configType = "DynamicLibrary";
+            } else if (this->Android) {
+              configType = "DynamicLibrary";
             } else {
               configType = "Application";
             }
             break;
           case cmStateEnums::UTILITY:
+          case cmStateEnums::INTERFACE_LIBRARY:
           case cmStateEnums::GLOBAL_TARGET:
             if (this->NsightTegra) {
               // Tegra-Android platform does not understand "Utility".
@@ -1151,7 +1166,6 @@
             }
             break;
           case cmStateEnums::UNKNOWN_LIBRARY:
-          case cmStateEnums::INTERFACE_LIBRARY:
             break;
         }
       }
@@ -1166,6 +1180,8 @@
       }
     } else if (this->NsightTegra) {
       this->WriteNsightTegraConfigurationValues(e1, c);
+    } else if (this->Android) {
+      this->WriteAndroidConfigurationValues(e1, c);
     }
   }
 }
@@ -1324,6 +1340,24 @@
   }
 }
 
+void cmVisualStudio10TargetGenerator::WriteAndroidConfigurationValues(
+  Elem& e1, std::string const&)
+{
+  cmGlobalVisualStudio10Generator* gg = this->GlobalGenerator;
+  if (cmProp projectToolsetOverride =
+        this->GeneratorTarget->GetProperty("VS_PLATFORM_TOOLSET")) {
+    e1.Element("PlatformToolset", *projectToolsetOverride);
+  } else if (const char* toolset = gg->GetPlatformToolset()) {
+    e1.Element("PlatformToolset", toolset);
+  }
+  if (cmProp stlType =
+        this->GeneratorTarget->GetProperty("ANDROID_STL_TYPE")) {
+    if (*stlType != "none") {
+      e1.Element("UseOfStl", *stlType);
+    }
+  }
+}
+
 void cmVisualStudio10TargetGenerator::WriteCustomCommands(Elem& e0)
 {
   this->CSharpCustomCommandNames.clear();
@@ -1941,7 +1975,7 @@
   }
 
   cmProp toolOverride = sf->GetProperty("VS_TOOL_OVERRIDE");
-  if (toolOverride && !toolOverride->empty()) {
+  if (cmNonempty(toolOverride)) {
     tool = toolOverride->c_str();
   }
 
@@ -1950,12 +1984,12 @@
   if (this->GlobalGenerator->TargetsWindowsPhone() ||
       this->GlobalGenerator->TargetsWindowsStore()) {
     cmProp content = sf->GetProperty("VS_DEPLOYMENT_CONTENT");
-    if (content && !content->empty()) {
+    if (cmNonempty(content)) {
       toolHasSettings = true;
       deployContent = *content;
 
       cmProp location = sf->GetProperty("VS_DEPLOYMENT_LOCATION");
-      if (location && !location->empty()) {
+      if (cmNonempty(location)) {
         deployLocation = *location;
       }
     }
@@ -2117,7 +2151,7 @@
 
 void cmVisualStudio10TargetGenerator::WriteAllSources(Elem& e0)
 {
-  if (this->GeneratorTarget->GetType() > cmStateEnums::UTILITY) {
+  if (this->GeneratorTarget->GetType() == cmStateEnums::GLOBAL_TARGET) {
     return;
   }
 
@@ -2258,7 +2292,7 @@
           e2.Attribute("UnityFilesDirectory", unityDir);
         } else {
           // Visual Studio versions prior to 2017 15.8 do not know about unity
-          // builds, thus we exclude the files alredy part of unity sources.
+          // builds, thus we exclude the files already part of unity sources.
           if (!si.Source->GetPropertyAsBool("SKIP_UNITY_BUILD_INCLUSION")) {
             exclude_configs = si.Configs;
           }
@@ -2915,7 +2949,9 @@
     }
   }
 
-  if (this->MSTools) {
+  if (this->Android) {
+    e2.Element("ObjectFileName", "$(IntDir)%(filename).o");
+  } else if (this->MSTools) {
     cmsys::RegularExpression clangToolset("v[0-9]+_clang_.*");
     const char* toolset = this->GlobalGenerator->GetPlatformToolset();
     if (toolset && clangToolset.find(toolset)) {
@@ -4021,8 +4057,7 @@
     //    output manifest flags  <Manifest></Manifest>
     this->WriteManifestOptions(e1, c);
     if (this->NsightTegra &&
-        this->GeneratorTarget->GetType() == cmStateEnums::EXECUTABLE &&
-        this->GeneratorTarget->GetPropertyAsBool("ANDROID_GUI")) {
+        this->GeneratorTarget->Target->IsAndroidGuiExecutable()) {
       this->WriteAntBuildOptions(e1, c);
     }
   }
@@ -4108,7 +4143,7 @@
   Elem e1(e0, "ItemGroup");
   e1.SetHasElements();
   for (cmGeneratorTarget const* dt : depends) {
-    if (dt->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+    if (!dt->IsInBuildSystem()) {
       continue;
     }
     // skip fortran targets as they can not be processed by MSBuild
@@ -4137,8 +4172,9 @@
     }
 
     // Don't reference targets that don't produce any output.
-    if (dt->GetManagedType(this->Configurations[0]) ==
-        cmGeneratorTarget::ManagedType::Undefined) {
+    if (this->Configurations.empty() ||
+        dt->GetManagedType(this->Configurations[0]) ==
+          cmGeneratorTarget::ManagedType::Undefined) {
       e2.Element("ReferenceOutputAssembly", "false");
       e2.Element("CopyToOutputDirectory", "Never");
     }
@@ -4354,6 +4390,7 @@
   bool isAppContainer = false;
   bool const isWindowsPhone = this->GlobalGenerator->TargetsWindowsPhone();
   bool const isWindowsStore = this->GlobalGenerator->TargetsWindowsStore();
+  bool const isAndroid = this->GlobalGenerator->TargetsAndroid();
   std::string const& rev = this->GlobalGenerator->GetApplicationTypeRevision();
   if (isWindowsPhone || isWindowsStore) {
     e1.Element("ApplicationType",
@@ -4391,13 +4428,19 @@
                    this->Name + "_$(Configuration)_$(Platform).xap");
       }
     }
+  } else if (isAndroid) {
+    e1.Element("ApplicationType", "Android");
+    e1.Element("ApplicationTypeRevision",
+               gg->GetAndroidApplicationTypeRevision());
   }
   if (isAppContainer) {
     e1.Element("AppContainerApplication", "true");
-  } else if (this->Platform == "ARM64") {
-    e1.Element("WindowsSDKDesktopARM64Support", "true");
-  } else if (this->Platform == "ARM") {
-    e1.Element("WindowsSDKDesktopARMSupport", "true");
+  } else if (!isAndroid) {
+    if (this->Platform == "ARM64") {
+      e1.Element("WindowsSDKDesktopARM64Support", "true");
+    } else if (this->Platform == "ARM") {
+      e1.Element("WindowsSDKDesktopARMSupport", "true");
+    }
   }
   std::string const& targetPlatformVersion =
     gg->GetWindowsTargetPlatformVersion();
diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h
index 7c71de3..c54057a 100644
--- a/Source/cmVisualStudio10TargetGenerator.h
+++ b/Source/cmVisualStudio10TargetGenerator.h
@@ -70,6 +70,7 @@
   void WriteExtraSource(Elem& e1, cmSourceFile const* sf);
   void WriteNsightTegraConfigurationValues(Elem& e1,
                                            std::string const& config);
+  void WriteAndroidConfigurationValues(Elem& e1, std::string const& config);
   void WriteSource(Elem& e2, cmSourceFile const* sf);
   void WriteExcludeFromBuild(Elem& e2,
                              std::vector<size_t> const& exclude_configs);
@@ -215,6 +216,7 @@
   bool MSTools;
   bool Managed;
   bool NsightTegra;
+  bool Android;
   unsigned int NsightTegraVersion[4];
   bool TargetCompileAsWinRT;
   std::set<std::string> IPOEnabledConfigurations;
diff --git a/Source/cmXCodeScheme.cxx b/Source/cmXCodeScheme.cxx
index f4c2f2d..55e941d 100644
--- a/Source/cmXCodeScheme.cxx
+++ b/Source/cmXCodeScheme.cxx
@@ -33,7 +33,7 @@
   // Create shared scheme sub-directory tree
   //
   std::string xcodeSchemeDir = cmStrCat(xcProjDir, "/xcshareddata/xcschemes");
-  cmSystemTools::MakeDirectory(xcodeSchemeDir.c_str());
+  cmSystemTools::MakeDirectory(xcodeSchemeDir);
 
   std::string xcodeSchemeFile =
     cmStrCat(xcodeSchemeDir, '/', this->TargetName, ".xcscheme");
@@ -324,8 +324,7 @@
   bool defaultValue)
 {
   cmProp property = Target->GetTarget()->GetProperty(varName);
-  bool isOn =
-    (property == nullptr && defaultValue) || (property && cmIsOn(*property));
+  bool isOn = (property == nullptr && defaultValue) || cmIsOn(property);
 
   if (isOn) {
     xout.Attribute(attrName.c_str(), "YES");
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index 162e807..dcb96f8 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -64,10 +64,6 @@
 #  include "cmVariableWatch.h"
 #endif
 
-#if !defined(CMAKE_BOOTSTRAP)
-#  define CMAKE_USE_ECLIPSE
-#endif
-
 #if defined(__MINGW32__) && defined(CMAKE_BOOTSTRAP)
 #  define CMAKE_BOOT_MINGW
 #endif
@@ -101,16 +97,13 @@
 #if !defined(CMAKE_BOOTSTRAP)
 #  include "cmGlobalNinjaGenerator.h"
 #endif
-#include "cmExtraCodeLiteGenerator.h"
 
-#if !defined(CMAKE_BOOT_MINGW)
+#if !defined(CMAKE_BOOTSTRAP)
 #  include "cmExtraCodeBlocksGenerator.h"
-#endif
-#include "cmExtraKateGenerator.h"
-#include "cmExtraSublimeTextGenerator.h"
-
-#ifdef CMAKE_USE_ECLIPSE
+#  include "cmExtraCodeLiteGenerator.h"
 #  include "cmExtraEclipseCDT4Generator.h"
+#  include "cmExtraKateGenerator.h"
+#  include "cmExtraSublimeTextGenerator.h"
 #endif
 
 #if defined(__linux__) || defined(_WIN32)
@@ -201,7 +194,7 @@
     };
 
     // The "c" extension MUST precede the "C" extension.
-    setupExts(this->SourceFileExtensions,
+    setupExts(this->CLikeSourceFileExtensions,
               { "c", "C", "c++", "cc", "cpp", "cxx", "cu", "m", "M", "mm" });
     setupExts(this->HeaderFileExtensions,
               { "h", "hh", "h++", "hm", "hpp", "hxx", "in", "txx" });
@@ -780,8 +773,7 @@
       std::cout << "Warn about uninitialized values.\n";
       this->SetWarnUninitialized(true);
     } else if (cmHasLiteralPrefix(arg, "--warn-unused-vars")) {
-      std::cout << "Finding unused variables.\n";
-      this->SetWarnUnused(true);
+      // Option was removed.
     } else if (cmHasLiteralPrefix(arg, "--no-warn-unused-cli")) {
       std::cout << "Not searching for unused variables given on the "
                 << "command line.\n";
@@ -1137,13 +1129,9 @@
 #if !defined(CMAKE_BOOTSTRAP)
   this->ExtraGenerators.push_back(cmExtraCodeBlocksGenerator::GetFactory());
   this->ExtraGenerators.push_back(cmExtraCodeLiteGenerator::GetFactory());
-  this->ExtraGenerators.push_back(cmExtraSublimeTextGenerator::GetFactory());
-  this->ExtraGenerators.push_back(cmExtraKateGenerator::GetFactory());
-
-#  ifdef CMAKE_USE_ECLIPSE
   this->ExtraGenerators.push_back(cmExtraEclipseCDT4Generator::GetFactory());
-#  endif
-
+  this->ExtraGenerators.push_back(cmExtraKateGenerator::GetFactory());
+  this->ExtraGenerators.push_back(cmExtraSublimeTextGenerator::GetFactory());
 #endif
 }
 
@@ -1383,7 +1371,7 @@
 
 int cmake::HandleDeleteCacheVariables(const std::string& var)
 {
-  std::vector<std::string> argsSplit = cmExpandedList(std::string(var), true);
+  std::vector<std::string> argsSplit = cmExpandedList(var, true);
   // erase the property to avoid infinite recursion
   this->State->SetGlobalProperty("__CMAKE_DELETE_CACHE_CHANGE_VARS_", "");
   if (this->State->GetIsInTryCompile()) {
@@ -1402,8 +1390,13 @@
     save.key = *i;
     warning << *i << "= ";
     i++;
-    save.value = *i;
-    warning << *i << "\n";
+    if (i != argsSplit.end()) {
+      save.value = *i;
+      warning << *i << "\n";
+    } else {
+      warning << "\n";
+      i -= 1;
+    }
     cmProp existingValue = this->State->GetCacheEntryValue(save.key);
     if (existingValue) {
       save.type = this->State->GetCacheEntryType(save.key);
@@ -1499,10 +1492,10 @@
   this->Messenger->SetSuppressDeprecatedWarnings(value && cmIsOff(*value));
 
   value = this->State->GetCacheEntryValue("CMAKE_ERROR_DEPRECATED");
-  this->Messenger->SetDeprecatedWarningsAsErrors(value && cmIsOn(*value));
+  this->Messenger->SetDeprecatedWarningsAsErrors(cmIsOn(value));
 
   value = this->State->GetCacheEntryValue("CMAKE_SUPPRESS_DEVELOPER_WARNINGS");
-  this->Messenger->SetSuppressDevWarnings(value && cmIsOn(*value));
+  this->Messenger->SetSuppressDevWarnings(cmIsOn(value));
 
   value = this->State->GetCacheEntryValue("CMAKE_SUPPRESS_DEVELOPER_ERRORS");
   this->Messenger->SetDevWarningsAsErrors(value && cmIsOff(*value));
@@ -1970,6 +1963,17 @@
                                  backtrace);
 }
 
+std::vector<std::string> cmake::GetAllExtensions() const
+{
+  std::vector<std::string> allExt = this->CLikeSourceFileExtensions.ordered;
+  allExt.insert(allExt.end(), this->HeaderFileExtensions.ordered.begin(),
+                this->HeaderFileExtensions.ordered.end());
+  // cuda extensions are also in SourceFileExtensions so we ignore it here
+  allExt.insert(allExt.end(), this->FortranFileExtensions.ordered.begin(),
+                this->FortranFileExtensions.ordered.end());
+  return allExt;
+}
+
 std::string cmake::StripExtension(const std::string& file) const
 {
   auto dotpos = file.rfind('.');
@@ -1979,7 +1983,7 @@
 #else
     auto ext = cm::string_view(file).substr(dotpos + 1);
 #endif
-    if (this->IsSourceExtension(ext) || this->IsHeaderExtension(ext)) {
+    if (this->IsAKnownExtension(ext)) {
       return file.substr(0, dotpos);
     }
   }
@@ -2269,7 +2273,7 @@
   if (this->ClearBuildSystem) {
     // Get the generator used for this build system.
     const char* genName = mf.GetDefinition("CMAKE_DEPENDS_GENERATOR");
-    if (!genName || genName[0] == '\0') {
+    if (!cmNonempty(genName)) {
       genName = "Unix Makefiles";
     }
 
@@ -2743,9 +2747,7 @@
   }
   projName = *cachedProjectName;
 
-  cmProp cachedVerbose =
-    this->State->GetCacheEntryValue("CMAKE_VERBOSE_MAKEFILE");
-  if (cachedVerbose && cmIsOn(*cachedVerbose)) {
+  if (cmIsOn(this->State->GetCacheEntryValue("CMAKE_VERBOSE_MAKEFILE"))) {
     verbose = true;
   }
 
diff --git a/Source/cmake.h b/Source/cmake.h
index 086ec87..0c4f429 100644
--- a/Source/cmake.h
+++ b/Source/cmake.h
@@ -264,46 +264,35 @@
     this->GeneratorToolsetSet = true;
   }
 
-  const std::vector<std::string>& GetSourceExtensions() const
+  bool IsAKnownSourceExtension(cm::string_view ext) const
   {
-    return this->SourceFileExtensions.ordered;
+    return this->CLikeSourceFileExtensions.Test(ext) ||
+      this->CudaFileExtensions.Test(ext) ||
+      this->FortranFileExtensions.Test(ext);
   }
 
-  bool IsSourceExtension(cm::string_view ext) const
+  bool IsACLikeSourceExtension(cm::string_view ext) const
   {
-    return this->SourceFileExtensions.Test(ext);
+    return this->CLikeSourceFileExtensions.Test(ext);
   }
 
+  bool IsAKnownExtension(cm::string_view ext) const
+  {
+    return this->IsAKnownSourceExtension(ext) || this->IsAHeaderExtension(ext);
+  }
+
+  std::vector<std::string> GetAllExtensions() const;
+
   const std::vector<std::string>& GetHeaderExtensions() const
   {
     return this->HeaderFileExtensions.ordered;
   }
 
-  bool IsHeaderExtension(cm::string_view ext) const
+  bool IsAHeaderExtension(cm::string_view ext) const
   {
     return this->HeaderFileExtensions.Test(ext);
   }
 
-  const std::vector<std::string>& GetCudaExtensions() const
-  {
-    return this->CudaFileExtensions.ordered;
-  }
-
-  bool IsCudaExtension(cm::string_view ext) const
-  {
-    return this->CudaFileExtensions.Test(ext);
-  }
-
-  const std::vector<std::string>& GetFortranExtensions() const
-  {
-    return this->FortranFileExtensions.ordered;
-  }
-
-  bool IsFortranExtension(cm::string_view ext) const
-  {
-    return this->FortranFileExtensions.Test(ext);
-  }
-
   // Strips the extension (if present and known) from a filename
   std::string StripExtension(const std::string& file) const;
 
@@ -461,8 +450,6 @@
 
   bool GetWarnUninitialized() { return this->WarnUninitialized; }
   void SetWarnUninitialized(bool b) { this->WarnUninitialized = b; }
-  bool GetWarnUnused() { return this->WarnUnused; }
-  void SetWarnUnused(bool b) { this->WarnUnused = b; }
   bool GetWarnUnusedCli() { return this->WarnUnusedCli; }
   void SetWarnUnusedCli(bool b) { this->WarnUnusedCli = b; }
   bool GetCheckSystemVars() { return this->CheckSystemVars; }
@@ -616,7 +603,6 @@
   TraceFormat TraceFormatVar = TRACE_HUMAN;
   cmGeneratedFileStream TraceFile;
   bool WarnUninitialized = false;
-  bool WarnUnused = false;
   bool WarnUnusedCli = true;
   bool CheckSystemVars = false;
   std::map<std::string, bool> UsedCliVariables;
@@ -628,7 +614,7 @@
   std::string CheckStampList;
   std::string VSSolutionFile;
   std::string EnvironmentGenerator;
-  FileExtensions SourceFileExtensions;
+  FileExtensions CLikeSourceFileExtensions;
   FileExtensions HeaderFileExtensions;
   FileExtensions CudaFileExtensions;
   FileExtensions FortranFileExtensions;
diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx
index d662a9a..4600fc5 100644
--- a/Source/cmakemain.cxx
+++ b/Source/cmakemain.cxx
@@ -3,11 +3,13 @@
 
 #include "cmConfigure.h" // IWYU pragma: keep
 
+#include <algorithm>
 #include <cassert>
 #include <cctype>
 #include <climits>
 #include <cstring>
 #include <iostream>
+#include <sstream>
 #include <string>
 #include <vector>
 
@@ -69,7 +71,7 @@
   { "--open <dir>", "Open generated project in the associated application." },
   { "-N", "View mode only." },
   { "-P <file>", "Process script mode." },
-  { "--find-package", "Run in pkg-config like mode." },
+  { "--find-package", "Legacy pkg-config like mode.  Do not use." },
   { "--graphviz=[file]",
     "Generate graphviz of dependencies, see "
     "CMakeGraphVizOptions.cmake for more." },
@@ -91,7 +93,6 @@
   { "--trace-redirect=<file>",
     "Redirect trace output to a file instead of stderr." },
   { "--warn-uninitialized", "Warn about uninitialized values." },
-  { "--warn-unused-vars", "Warn about unused variables." },
   { "--no-warn-unused-cli", "Don't warn about command line options." },
   { "--check-system-vars",
     "Find problems with variable usage in system "
@@ -519,6 +520,121 @@
 #endif
 }
 
+bool parse_default_directory_permissions(const std::string& permissions,
+                                         std::string& parsedPermissionsVar)
+{
+  std::vector<std::string> parsedPermissions;
+  enum Doing
+  {
+    DoingNone,
+    DoingOwner,
+    DoingGroup,
+    DoingWorld,
+    DoingOwnerAssignment,
+    DoingGroupAssignment,
+    DoingWorldAssignment,
+  };
+  Doing doing = DoingNone;
+
+  auto uniquePushBack = [&parsedPermissions](const std::string& e) {
+    if (std::find(parsedPermissions.begin(), parsedPermissions.end(), e) ==
+        parsedPermissions.end()) {
+      parsedPermissions.push_back(e);
+    }
+  };
+
+  for (auto const& e : permissions) {
+    switch (doing) {
+      case DoingNone:
+        if (e == 'u') {
+          doing = DoingOwner;
+        } else if (e == 'g') {
+          doing = DoingGroup;
+        } else if (e == 'o') {
+          doing = DoingWorld;
+        } else {
+          return false;
+        }
+        break;
+      case DoingOwner:
+        if (e == '=') {
+          doing = DoingOwnerAssignment;
+        } else {
+          return false;
+        }
+        break;
+      case DoingGroup:
+        if (e == '=') {
+          doing = DoingGroupAssignment;
+        } else {
+          return false;
+        }
+        break;
+      case DoingWorld:
+        if (e == '=') {
+          doing = DoingWorldAssignment;
+        } else {
+          return false;
+        }
+        break;
+      case DoingOwnerAssignment:
+        if (e == 'r') {
+          uniquePushBack("OWNER_READ");
+        } else if (e == 'w') {
+          uniquePushBack("OWNER_WRITE");
+        } else if (e == 'x') {
+          uniquePushBack("OWNER_EXECUTE");
+        } else if (e == ',') {
+          doing = DoingNone;
+        } else {
+          return false;
+        }
+        break;
+      case DoingGroupAssignment:
+        if (e == 'r') {
+          uniquePushBack("GROUP_READ");
+        } else if (e == 'w') {
+          uniquePushBack("GROUP_WRITE");
+        } else if (e == 'x') {
+          uniquePushBack("GROUP_EXECUTE");
+        } else if (e == ',') {
+          doing = DoingNone;
+        } else {
+          return false;
+        }
+        break;
+      case DoingWorldAssignment:
+        if (e == 'r') {
+          uniquePushBack("WORLD_READ");
+        } else if (e == 'w') {
+          uniquePushBack("WORLD_WRITE");
+        } else if (e == 'x') {
+          uniquePushBack("WORLD_EXECUTE");
+        } else if (e == ',') {
+          doing = DoingNone;
+        } else {
+          return false;
+        }
+        break;
+    }
+  }
+  if (doing != DoingOwnerAssignment && doing != DoingGroupAssignment &&
+      doing != DoingWorldAssignment) {
+    return false;
+  }
+
+  std::ostringstream oss;
+  for (auto i = 0u; i < parsedPermissions.size(); i++) {
+    if (i != 0) {
+      oss << ";";
+    }
+    oss << parsedPermissions[i];
+  }
+
+  parsedPermissionsVar = oss.str();
+  return true;
+}
+
 int do_install(int ac, char const* const* av)
 {
 #ifdef CMAKE_BOOTSTRAP
@@ -529,6 +645,7 @@
 
   std::string config;
   std::string component;
+  std::string defaultDirectoryPermissions;
   std::string prefix;
   std::string dir;
   bool strip = false;
@@ -541,6 +658,7 @@
     DoingConfig,
     DoingComponent,
     DoingPrefix,
+    DoingDefaultDirectoryPermissions,
   };
 
   Doing doing = DoingDir;
@@ -559,6 +677,8 @@
                (strcmp(av[i], "-v") == 0)) {
       verbose = true;
       doing = DoingNone;
+    } else if (strcmp(av[i], "--default-directory-permissions") == 0) {
+      doing = DoingDefaultDirectoryPermissions;
     } else {
       switch (doing) {
         case DoingDir:
@@ -577,6 +697,10 @@
           prefix = av[i];
           doing = DoingNone;
           break;
+        case DoingDefaultDirectoryPermissions:
+          defaultDirectoryPermissions = av[i];
+          doing = DoingNone;
+          break;
         default:
           std::cerr << "Unknown argument " << av[i] << std::endl;
           dir.clear();
@@ -593,6 +717,8 @@
       "  <dir>              = Project binary directory to install.\n"
       "  --config <cfg>     = For multi-configuration tools, choose <cfg>.\n"
       "  --component <comp> = Component-based install. Only install <comp>.\n"
+      "  --default-directory-permissions <permission> \n"
+      "     Default install permission. Use default permission <permission>.\n"
       "  --prefix <prefix>  = The installation prefix CMAKE_INSTALL_PREFIX.\n"
       "  --strip            = Performing install/strip.\n"
       "  -v --verbose       = Enable verbose output.\n"
@@ -633,6 +759,18 @@
     args.emplace_back("-DCMAKE_INSTALL_CONFIG_NAME=" + config);
   }
 
+  if (!defaultDirectoryPermissions.empty()) {
+    std::string parsedPermissionsVar;
+    if (!parse_default_directory_permissions(defaultDirectoryPermissions,
+                                             parsedPermissionsVar)) {
+      std::cerr << "--default-directory-permissions is in incorrect format"
+                << std::endl;
+      return 1;
+    }
+    args.emplace_back("-DCMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS=" +
+                      parsedPermissionsVar);
+  }
+
   args.emplace_back("-P");
   args.emplace_back(dir + "/cmake_install.cmake");
 
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx
index de76d73..a1c6771 100644
--- a/Source/cmcmd.cxx
+++ b/Source/cmcmd.cxx
@@ -126,6 +126,7 @@
     << "  touch <file>...           - touch a <file>.\n"
     << "  touch_nocreate <file>...  - touch a <file> but do not create it.\n"
     << "  create_symlink old new    - create a symbolic link new -> old\n"
+    << "  create_hardlink old new   - create a hard link new -> old\n"
     << "  true                      - do nothing with an exit code of 0\n"
     << "  false                     - do nothing with an exit code of 1\n"
 #if defined(_WIN32) && !defined(__CYGWIN__)
@@ -582,12 +583,10 @@
         filesDiffer = cmsys::SystemTools::TextFilesDiffer(args[3], args[4]);
       } else {
         ::CMakeCommandUsage(args[0].c_str());
-        return 1;
+        return 2;
       }
 
       if (filesDiffer) {
-        std::cerr << "Files \"" << args[args.size() - 2] << "\" to \""
-                  << args[args.size() - 1] << "\" are different.\n";
         return 1;
       }
       return 0;
@@ -602,8 +601,7 @@
       }
       cmsys::ifstream fin(args[3].c_str(), std::ios::in | std::ios::binary);
       if (!fin) {
-        std::cerr << "could not open object list file: " << args[3].c_str()
-                  << "\n";
+        std::cerr << "could not open object list file: " << args[3] << "\n";
         return 1;
       }
       std::vector<std::string> files;
@@ -626,13 +624,12 @@
       }
       FILE* fout = cmsys::SystemTools::Fopen(args[2], "w+");
       if (!fout) {
-        std::cerr << "could not open output .def file: " << args[2].c_str()
-                  << "\n";
+        std::cerr << "could not open output .def file: " << args[2] << "\n";
         return 1;
       }
       bindexplib deffile;
       if (args.size() >= 5) {
-        auto a = args[4];
+        std::string const& a = args[4];
         if (cmHasLiteralPrefix(a, "--nm=")) {
           deffile.SetNmPath(a.substr(5));
           std::cerr << a.substr(5) << "\n";
@@ -640,7 +637,7 @@
           std::cerr << "unknown argument: " << a << "\n";
         }
       }
-      for (auto const& file : files) {
+      for (std::string const& file : files) {
         std::string const& ext = cmSystemTools::GetFilenameLastExtension(file);
         if (cmSystemTools::LowerCase(ext) == ".def") {
           if (!deffile.AddDefinitionFile(file.c_str())) {
@@ -1022,7 +1019,7 @@
     // Command to create a symbolic link.  Fails on platforms not
     // supporting them.
     if (args[1] == "create_symlink" && args.size() == 4) {
-      const char* destinationFileName = args[3].c_str();
+      std::string const& destinationFileName = args[3];
       if ((cmSystemTools::FileExists(destinationFileName) ||
            cmSystemTools::FileIsSymlink(destinationFileName)) &&
           !cmSystemTools::RemoveFile(destinationFileName)) {
@@ -1038,6 +1035,34 @@
       return 0;
     }
 
+    // Command to create a hard link.  Fails on platforms not
+    // supporting them.
+    if (args[1] == "create_hardlink" && args.size() == 4) {
+      const char* SouceFileName = args[2].c_str();
+      const char* destinationFileName = args[3].c_str();
+
+      if (!cmSystemTools::FileExists(SouceFileName)) {
+        std::cerr << "failed to create hard link because source path '"
+                  << SouceFileName << "' does not exist \n";
+        return 1;
+      }
+
+      if ((cmSystemTools::FileExists(destinationFileName) ||
+           cmSystemTools::FileIsSymlink(destinationFileName)) &&
+          !cmSystemTools::RemoveFile(destinationFileName)) {
+        std::string emsg = cmSystemTools::GetLastSystemError();
+        std::cerr << "failed to create hard link '" << destinationFileName
+                  << "' because existing path cannot be removed: " << emsg
+                  << "\n";
+        return 1;
+      }
+
+      if (!cmSystemTools::CreateLink(args[2], args[3])) {
+        return 1;
+      }
+      return 0;
+    }
+
     // Command to do nothing with an exit code of 0.
     if (args[1] == "true") {
       return 0;
@@ -1379,15 +1404,12 @@
 #if defined(_WIN32) && !defined(__CYGWIN__)
     // Write registry value
     if (args[1] == "write_regv" && args.size() > 3) {
-      return cmSystemTools::WriteRegistryValue(args[2].c_str(),
-                                               args[3].c_str())
-        ? 0
-        : 1;
+      return cmSystemTools::WriteRegistryValue(args[2], args[3]) ? 0 : 1;
     }
 
     // Delete registry value
     if (args[1] == "delete_regv" && args.size() > 2) {
-      return cmSystemTools::DeleteRegistryValue(args[2].c_str()) ? 0 : 1;
+      return cmSystemTools::DeleteRegistryValue(args[2]) ? 0 : 1;
     }
 
     // Remove file
@@ -1750,7 +1772,7 @@
   //   args[2] == source_file_path
   //   args[3] == intermediate_file
   //   args[4..n] == preprocess+args
-  //   args[n+1] == --
+  //   args[n+1] == ++
   //   args[n+2...] == llvm-rc+args
   if (args.size() < 3) {
     std::cerr << "Invalid cmake_llvm_rc arguments";
@@ -1762,7 +1784,11 @@
   std::vector<std::string> resource_compile;
   std::vector<std::string>* pArgTgt = &preprocess;
   for (std::string const& arg : cmMakeRange(args).advance(4)) {
-    if (arg == "--") {
+    // We use ++ as seperator between the preprocessing step definition and the
+    // rc compilation step becase we need to prepend a -- to seperate the
+    // source file properly from other options when using clang-cl for
+    // preprocessing.
+    if (arg == "++") {
       pArgTgt = &resource_compile;
     } else {
       if (arg.find("SOURCE_DIR") != std::string::npos) {
diff --git a/Source/kwsys/CTestConfig.cmake b/Source/kwsys/CTestConfig.cmake
index 33ea84c..12347b6 100644
--- a/Source/kwsys/CTestConfig.cmake
+++ b/Source/kwsys/CTestConfig.cmake
@@ -3,7 +3,9 @@
 
 set(CTEST_PROJECT_NAME "KWSys")
 set(CTEST_NIGHTLY_START_TIME "21:00:00 EDT")
-set(CTEST_DROP_METHOD "http")
+if (NOT CTEST_DROP_METHOD STREQUAL "https")
+  set(CTEST_DROP_METHOD "http")
+endif ()
 set(CTEST_DROP_SITE "open.cdash.org")
 set(CTEST_DROP_LOCATION "/submit.php?project=PublicDashboard")
 set(CTEST_DROP_SITE_CDASH TRUE)
diff --git a/Source/kwsys/Glob.cxx b/Source/kwsys/Glob.cxx
index 5452f73..c6d4b19 100644
--- a/Source/kwsys/Glob.cxx
+++ b/Source/kwsys/Glob.cxx
@@ -27,7 +27,7 @@
 #include <cstdio>
 #include <cstring>
 namespace KWSYS_NAMESPACE {
-#if defined(_WIN32) || defined(__APPLE__) || defined(__CYGWIN__)
+#if defined(_WIN32) || defined(__APPLE__)
 // On Windows and Apple, no difference between lower and upper case
 #  define KWSYS_GLOB_CASE_INDEPENDENT
 #endif
diff --git a/Source/kwsys/Glob.hxx.in b/Source/kwsys/Glob.hxx.in
index b5a34d5..e8474e2 100644
--- a/Source/kwsys/Glob.hxx.in
+++ b/Source/kwsys/Glob.hxx.in
@@ -126,8 +126,8 @@
   bool RecurseListDirs;
 
 private:
-  Glob(const Glob&);           // Not implemented.
-  void operator=(const Glob&); // Not implemented.
+  Glob(const Glob&) = delete;
+  void operator=(const Glob&) = delete;
 };
 
 } // namespace @KWSYS_NAMESPACE@
diff --git a/Source/kwsys/ProcessUNIX.c b/Source/kwsys/ProcessUNIX.c
index cc45529..e1e7721 100644
--- a/Source/kwsys/ProcessUNIX.c
+++ b/Source/kwsys/ProcessUNIX.c
@@ -2128,17 +2128,17 @@
 #endif
 #ifdef SIGABRT
     case SIGABRT:
-      KWSYSPE_CASE(Other, "Child aborted");
+      KWSYSPE_CASE(Other, "Subprocess aborted");
       break;
 #endif
 #ifdef SIGKILL
     case SIGKILL:
-      KWSYSPE_CASE(Other, "Child killed");
+      KWSYSPE_CASE(Other, "Subprocess killed");
       break;
 #endif
 #ifdef SIGTERM
     case SIGTERM:
-      KWSYSPE_CASE(Other, "Child terminated");
+      KWSYSPE_CASE(Other, "Subprocess terminated");
       break;
 #endif
 #ifdef SIGHUP
diff --git a/Source/kwsys/SystemInformation.cxx b/Source/kwsys/SystemInformation.cxx
index ed1cdc0..9c34a56 100644
--- a/Source/kwsys/SystemInformation.cxx
+++ b/Source/kwsys/SystemInformation.cxx
@@ -863,7 +863,7 @@
 // Hide implementation details in an anonymous namespace.
 namespace {
 // *****************************************************************************
-#if defined(__linux) || defined(__APPLE__)
+#if defined(__linux) || defined(__APPLE__) || defined(__CYGWIN__)
 int LoadLines(FILE* file, std::vector<std::string>& lines)
 {
   // Load each line in the given file into a the vector.
@@ -893,7 +893,7 @@
   return nRead;
 }
 
-#  if defined(__linux)
+#  if defined(__linux) || defined(__CYGWIN__)
 // *****************************************************************************
 int LoadLines(const char* fileName, std::vector<std::string>& lines)
 {
@@ -926,7 +926,7 @@
 }
 #endif
 
-#if defined(__linux)
+#if defined(__linux) || defined(__CYGWIN__)
 // ****************************************************************************
 template <typename T>
 int GetFieldsFromFile(const char* fileName, const char** fieldNames, T* values)
@@ -3393,7 +3393,7 @@
     pos = buffer.find("processor\t", pos + 1);
   }
 
-#ifdef __linux
+#if defined(__linux) || defined(__CYGWIN__)
   // Count sockets.
   std::set<int> PhysicalIDs;
   std::string idc = this->ExtractValueFromCpuInfoFile(buffer, "physical id");
@@ -3414,8 +3414,8 @@
   this->NumberOfPhysicalCPU =
     NumberOfCoresPerSocket * (unsigned int)NumberOfSockets;
 
-#else // __CYGWIN__
-  // does not have "physical id" entries, neither "cpu cores"
+#else
+  // For systems which do not have "physical id" entries, neither "cpu cores"
   // this has to be fixed for hyper-threading.
   std::string cpucount =
     this->ExtractValueFromCpuInfoFile(buffer, "cpu count");
@@ -3597,7 +3597,7 @@
   GlobalMemoryStatusEx(&statex);
   return statex.ullTotalPhys / 1024;
 #  endif
-#elif defined(__linux)
+#elif defined(__linux) || defined(__CYGWIN__)
   long long memTotal = 0;
   int ierr = GetFieldFromFile("/proc/meminfo", "MemTotal:", memTotal);
   if (ierr) {
@@ -3712,6 +3712,16 @@
   GlobalMemoryStatusEx(&statex);
   return (statex.ullTotalPhys - statex.ullAvailPhys) / 1024;
 #  endif
+#elif defined(__CYGWIN__)
+  const char* names[3] = { "MemTotal:", "MemFree:", nullptr };
+  long long values[2] = { 0 };
+  int ierr = GetFieldsFromFile("/proc/meminfo", names, values);
+  if (ierr) {
+    return ierr;
+  }
+  long long& memTotal = values[0];
+  long long& memFree = values[1];
+  return memTotal - memFree;
 #elif defined(__linux)
   // First try to use MemAvailable, but it only works on newer kernels
   const char* names2[3] = { "MemTotal:", "MemAvailable:", nullptr };
@@ -3773,7 +3783,7 @@
     return -2;
   }
   return pmc.WorkingSetSize / 1024;
-#elif defined(__linux)
+#elif defined(__linux) || defined(__CYGWIN__)
   long long memUsed = 0;
   int ierr = GetFieldFromFile("/proc/self/status", "VmRSS:", memUsed);
   if (ierr) {
@@ -3850,7 +3860,8 @@
 #if defined(_WIN32)
   return GetCurrentProcessId();
 #elif defined(__linux) || defined(__APPLE__) || defined(__OpenBSD__) ||       \
-  defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
+  defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) ||    \
+  defined(__CYGWIN__)
   return getpid();
 #else
   return -1;
diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx
index 25705ea..6144d9c 100644
--- a/Source/kwsys/SystemTools.cxx
+++ b/Source/kwsys/SystemTools.cxx
@@ -96,19 +96,12 @@
 #  if defined(_MSC_VER) && _MSC_VER >= 1800
 #    define KWSYS_WINDOWS_DEPRECATED_GetVersionEx
 #  endif
-#elif defined(__CYGWIN__)
-#  include <windows.h>
-#  undef _WIN32
 #endif
 
 #if !KWSYS_CXX_HAS_ENVIRON_IN_STDLIB_H
 extern char** environ;
 #endif
 
-#ifdef __CYGWIN__
-#  include <sys/cygwin.h>
-#endif
-
 // getpwnam doesn't exist on Windows and Cray Xt3/Catamount
 // same for TIOCGWINSZ
 #if defined(_WIN32) || defined(__LIBCATAMOUNT__) ||                           \
@@ -1290,15 +1283,7 @@
   if (path.empty()) {
     return false;
   }
-#if defined(__CYGWIN__)
-  // Convert path to native windows path if possible.
-  char winpath[MAX_PATH];
-  if (SystemTools::PathCygwinToWin32(path.c_str(), winpath)) {
-    return (GetFileAttributesA(winpath) != INVALID_FILE_ATTRIBUTES);
-  }
-  struct stat st;
-  return lstat(path.c_str(), &st) == 0;
-#elif defined(_WIN32)
+#if defined(_WIN32)
   return (GetFileAttributesW(Encoding::ToWindowsExtendedPath(path).c_str()) !=
           INVALID_FILE_ATTRIBUTES);
 #else
@@ -1320,14 +1305,7 @@
   if (filename.empty()) {
     return false;
   }
-#if defined(__CYGWIN__)
-  // Convert filename to native windows path if possible.
-  char winpath[MAX_PATH];
-  if (SystemTools::PathCygwinToWin32(filename.c_str(), winpath)) {
-    return (GetFileAttributesA(winpath) != INVALID_FILE_ATTRIBUTES);
-  }
-  return access(filename.c_str(), R_OK) == 0;
-#elif defined(_WIN32)
+#if defined(_WIN32)
   DWORD attr =
     GetFileAttributesW(Encoding::ToWindowsExtendedPath(filename).c_str());
   if (attr == INVALID_FILE_ATTRIBUTES) {
@@ -1433,27 +1411,9 @@
 #endif
 }
 
-#ifdef __CYGWIN__
-bool SystemTools::PathCygwinToWin32(const char* path, char* win32_path)
-{
-  auto itr = SystemToolsStatics->Cyg2Win32Map.find(path);
-  if (itr != SystemToolsStatics->Cyg2Win32Map.end()) {
-    strncpy(win32_path, itr->second.c_str(), MAX_PATH);
-  } else {
-    if (cygwin_conv_path(CCP_POSIX_TO_WIN_A, path, win32_path, MAX_PATH) !=
-        0) {
-      win32_path[0] = 0;
-    }
-    SystemToolsStatics->Cyg2Win32Map.insert(
-      SystemToolsStatic::StringMap::value_type(path, win32_path));
-  }
-  return win32_path[0] != 0;
-}
-#endif
-
 bool SystemTools::Touch(const std::string& filename, bool create)
 {
-  if (!SystemTools::PathExists(filename)) {
+  if (!SystemTools::FileExists(filename)) {
     if (create) {
       FILE* file = Fopen(filename, "a+b");
       if (file) {
diff --git a/Source/kwsys/SystemTools.hxx.in b/Source/kwsys/SystemTools.hxx.in
index 5dbb726..74dc176 100644
--- a/Source/kwsys/SystemTools.hxx.in
+++ b/Source/kwsys/SystemTools.hxx.in
@@ -331,15 +331,6 @@
   static int Stat(const char* path, Stat_t* buf);
   static int Stat(const std::string& path, Stat_t* buf);
 
-/**
- * Converts Cygwin path to Win32 path. Uses dictionary container for
- * caching and calls to cygwin_conv_to_win32_path from Cygwin dll
- * for actual translation.  Returns true on success, else false.
- */
-#ifdef __CYGWIN__
-  static bool PathCygwinToWin32(const char* path, char* win32_path);
-#endif
-
   /**
    * Return file length
    */
diff --git a/Source/kwsys/testProcess.c b/Source/kwsys/testProcess.c
index 0c658f5..eed770c 100644
--- a/Source/kwsys/testProcess.c
+++ b/Source/kwsys/testProcess.c
@@ -450,24 +450,25 @@
       printf("The process is still executing.\n");
       break;
     case kwsysProcess_State_Expired:
-      printf("Child was killed when timeout expired.\n");
+      printf("Subprocess was killed when timeout expired.\n");
       break;
     case kwsysProcess_State_Exited:
-      printf("Child exited with value = %d\n", kwsysProcess_GetExitValue(kp));
+      printf("Subprocess exited with value = %d\n",
+             kwsysProcess_GetExitValue(kp));
       result = ((exception != kwsysProcess_GetExitException(kp)) ||
                 (value != kwsysProcess_GetExitValue(kp)));
       break;
     case kwsysProcess_State_Killed:
-      printf("Child was killed by parent.\n");
+      printf("Subprocess was killed by parent.\n");
       break;
     case kwsysProcess_State_Exception:
-      printf("Child terminated abnormally: %s\n",
+      printf("Subprocess terminated abnormally: %s\n",
              kwsysProcess_GetExceptionString(kp));
       result = ((exception != kwsysProcess_GetExitException(kp)) ||
                 (value != kwsysProcess_GetExitValue(kp)));
       break;
     case kwsysProcess_State_Disowned:
-      printf("Child was disowned.\n");
+      printf("Subprocess was disowned.\n");
       break;
     case kwsysProcess_State_Error:
       printf("Error in administrating child process: [%s]\n",
diff --git a/Source/kwsys/testSystemTools.cxx b/Source/kwsys/testSystemTools.cxx
index 1d34614..cfa420d 100644
--- a/Source/kwsys/testSystemTools.cxx
+++ b/Source/kwsys/testSystemTools.cxx
@@ -422,6 +422,28 @@
     res = false;
   }
 
+#if !defined(_WIN32)
+  std::string const testBadSymlink(testNewDir + "/badSymlink.txt");
+  std::string const testBadSymlinkTgt(testNewDir + "/missing/symlinkTgt.txt");
+  if (!kwsys::SystemTools::CreateSymlink(testBadSymlinkTgt, testBadSymlink)) {
+    std::cerr << "Problem with CreateSymlink for: " << testBadSymlink << " -> "
+              << testBadSymlinkTgt << std::endl;
+    res = false;
+  }
+
+  if (!kwsys::SystemTools::Touch(testBadSymlink, false)) {
+    std::cerr << "Problem with Touch (no create) for: " << testBadSymlink
+              << std::endl;
+    res = false;
+  }
+#endif
+
+  if (!kwsys::SystemTools::Touch(testNewDir, false)) {
+    std::cerr << "Problem with Touch (no create) for: " << testNewDir
+              << std::endl;
+    res = false;
+  }
+
   kwsys::SystemTools::Touch(testNewFile, true);
   if (!kwsys::SystemTools::RemoveADirectory(testNewDir)) {
     std::cerr << "Problem with RemoveADirectory for: " << testNewDir
diff --git a/Tests/CMakeLib/CMakeLists.txt b/Tests/CMakeLib/CMakeLists.txt
index bb50d76..0b2c8f6 100644
--- a/Tests/CMakeLib/CMakeLists.txt
+++ b/Tests/CMakeLib/CMakeLists.txt
@@ -29,6 +29,9 @@
   testCMExtMemory.cxx
   testCMExtAlgorithm.cxx
   )
+if (CMake_TEST_FILESYSTEM_PATH OR NOT CMake_HAVE_CXX_FILESYSTEM)
+  list(APPEND CMakeLib_TESTS testCMFilesystemPath.cxx)
+endif()
 
 add_executable(testUVProcessChainHelper testUVProcessChainHelper.cxx)
 
diff --git a/Tests/CMakeLib/PseudoMemcheck/CMakeLists.txt b/Tests/CMakeLib/PseudoMemcheck/CMakeLists.txt
index 7c84ee1..4bef6c5 100644
--- a/Tests/CMakeLib/PseudoMemcheck/CMakeLists.txt
+++ b/Tests/CMakeLib/PseudoMemcheck/CMakeLists.txt
@@ -15,6 +15,9 @@
 add_executable(pseudo_BC "${CMAKE_CURRENT_BINARY_DIR}/ret0.cxx")
 set_target_properties(pseudo_BC PROPERTIES OUTPUT_NAME BC)
 target_link_libraries(pseudo_BC CMakeLib)
+add_executable(pseudo_cuda-memcheck "${CMAKE_CURRENT_BINARY_DIR}/ret0.cxx")
+set_target_properties(pseudo_cuda-memcheck PROPERTIES OUTPUT_NAME cuda-memcheck)
+target_link_libraries(pseudo_cuda-memcheck CMakeLib)
 
 # binary to be used as pre- and post-memcheck command that fails
 add_executable(memcheck_fail "${CMAKE_CURRENT_BINARY_DIR}/ret1.cxx")
diff --git a/Tests/CMakeLib/PseudoMemcheck/memtester.cxx.in b/Tests/CMakeLib/PseudoMemcheck/memtester.cxx.in
index 3183bc0..f37ad59 100644
--- a/Tests/CMakeLib/PseudoMemcheck/memtester.cxx.in
+++ b/Tests/CMakeLib/PseudoMemcheck/memtester.cxx.in
@@ -1,8 +1,14 @@
-#include <cmSystemTools.h>
-#include "cmsys/Encoding.hxx"
 #include <string>
+#include <vector>
 
+#include "cmsys/Encoding.hxx"
+
+#include <cmSystemTools.h>
+
+// clang-format off
 #define RETVAL @_retval@
+#define CMAKE_COMMAND "@CMAKE_COMMAND@"
+// clang-format on
 
 int main(int ac, char** av)
 {
@@ -14,6 +20,9 @@
   std::string exename = argv[0];
   std::string logarg;
   bool nextarg = false;
+  // execute the part after the last argument?
+  // the logfile path gets passed as environment variable PSEUDO_LOGFILE
+  bool exec = false;
 
   if (exename.find("valgrind") != std::string::npos) {
     logarg = "--log-file=";
@@ -26,6 +35,10 @@
   } else if (exename.find("BC") != std::string::npos) {
     nextarg = true;
     logarg = "/X";
+  } else if (exename.find("cuda-memcheck") != std::string::npos) {
+    nextarg = true;
+    exec = true;
+    logarg = "--log-file";
   }
 
   if (!logarg.empty()) {
@@ -45,8 +58,25 @@
       }
     }
 
+    // find the last argument position
+    int lastarg_pos = 1;
+    for (int i = 1; i < argc; ++i) {
+      std::string arg = argv[i];
+      if (arg.find("--") == 0) {
+        lastarg_pos = i;
+      }
+    }
+
     if (!logfile.empty()) {
       cmSystemTools::Touch(logfile, true);
+      // execute everything after the last argument with additional environment
+      int callarg_pos = lastarg_pos + (nextarg ? 2 : 1);
+      if (exec && callarg_pos < argc) {
+        std::vector<std::string> callargs{ CMAKE_COMMAND, "-E", "env",
+                                           "PSEUDO_LOGFILE=" + logfile };
+        callargs.insert(callargs.end(), &argv[callarg_pos], &argv[argc]);
+        cmSystemTools::RunSingleCommand(callargs);
+      }
     }
   }
 
diff --git a/Tests/CMakeLib/testCMExtMemory.cxx b/Tests/CMakeLib/testCMExtMemory.cxx
index 6663c17..2aeaf7f 100644
--- a/Tests/CMakeLib/testCMExtMemory.cxx
+++ b/Tests/CMakeLib/testCMExtMemory.cxx
@@ -13,7 +13,7 @@
 class Derived : public Base
 {
 public:
-  ~Derived() = default;
+  ~Derived() override = default;
 
   void method() {}
 };
diff --git a/Tests/CMakeLib/testCMFilesystemPath.cxx b/Tests/CMakeLib/testCMFilesystemPath.cxx
new file mode 100644
index 0000000..1e84520
--- /dev/null
+++ b/Tests/CMakeLib/testCMFilesystemPath.cxx
@@ -0,0 +1,1006 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file Copyright.txt or https://cmake.org/licensing for details.  */
+
+#include <algorithm>
+#include <iostream>
+#include <sstream>
+#include <string>
+#include <vector>
+
+#include <cm/filesystem>
+#include <cm/iomanip>
+
+namespace {
+
+namespace fs = cm::filesystem;
+
+void checkResult(bool success)
+{
+  if (!success) {
+    std::cout << " => failed";
+  }
+  std::cout << std::endl;
+}
+
+bool testConstructors()
+{
+  std::cout << "testConstructors()";
+
+  bool result = true;
+
+  {
+    fs::path p;
+    if (p != fs::path()) {
+      result = false;
+    }
+  }
+  {
+    fs::path p1("/a/b/c");
+    fs::path p2("/a/b/c");
+    if (p1 != p2) {
+      result = false;
+    }
+    if (p1.string() != p2.string()) {
+      result = false;
+    }
+    if (p1.string() != "/a/b/c") {
+      result = false;
+    }
+  }
+  {
+    std::string s("/a/b/c");
+    fs::path p1(s);
+    fs::path p2(s.begin(), s.end());
+    if (p1 != p2) {
+      result = false;
+    }
+    if (p1.string() != s || p2.string() != s) {
+      result = false;
+    }
+#if CM_FILESYSTEM_SOURCE_TRAITS_ITERATOR
+    std::string s2(s);
+    s2 += '\0';
+    fs::path p3(s2.begin());
+    if (p1 != p3 || p3.string() != s) {
+      result = false;
+    }
+#endif
+  }
+  {
+    std::wstring s(L"/a/b/c");
+    fs::path p1(s);
+    fs::path p2(s.begin(), s.end());
+    if (p1 != p2) {
+      result = false;
+    }
+    if (p1.wstring() != s || p2.wstring() != s) {
+      result = false;
+    }
+#if CM_FILESYSTEM_SOURCE_TRAITS_ITERATOR
+    std::wstring s2(s);
+    s2 += L'\0';
+    fs::path p3(s2.begin());
+    if (p1 != p3 || p3.wstring() != s) {
+      result = false;
+    }
+#endif
+  }
+  {
+    std::string s("/a/b/c");
+    fs::path::string_type ws;
+    for (auto c : s) {
+      ws += fs::path::value_type(c);
+    }
+    fs::path p1(ws);
+    fs::path p2(ws.begin(), ws.end());
+    if (p1 != p2) {
+      result = false;
+    }
+    if (p1.native() != ws || p2.native() != ws) {
+      result = false;
+    }
+#if CM_FILESYSTEM_SOURCE_TRAITS_ITERATOR
+    fs::path::string_type ws2(ws);
+    ws2 += fs::path::value_type('\0');
+    fs::path p3(ws2.begin());
+    if (p1 != p3 || p3.native() != ws) {
+      result = false;
+    }
+#endif
+  }
+
+  checkResult(result);
+
+  return result;
+}
+
+bool testConcatenation()
+{
+  std::cout << "testConcatenation()";
+
+  bool result = true;
+
+  {
+    fs::path p("/a/b");
+    p /= "c";
+    if (!(p.string() == "/a/b/c" || p.string() == "/a/b\\c")) {
+      result = false;
+    }
+    p += "d";
+    if (!(p.string() == "/a/b/cd" || p.string() == "/a/b\\cd")) {
+      result = false;
+    }
+    fs::path p2("x/y");
+    p /= p2;
+    if (!(p.string() == "/a/b/cd/x/y" || p.string() == "/a/b\\cd\\x/y")) {
+      result = false;
+    }
+    p = p / p2;
+    if (!(p.string() == "/a/b/cd/x/y/x/y" ||
+          p.string() == "/a/b\\cd\\x/y\\x/y")) {
+      result = false;
+    }
+  }
+  {
+    fs::path p("a");
+    p /= "";
+    if (!(p.string() == "a/" || p.string() == "a\\")) {
+      result = false;
+    }
+    p /= "/b";
+    if (p.string() != "/b") {
+      result = false;
+    }
+  }
+#if defined(_WIN32)
+  {
+    fs::path p("a");
+    p /= "c:/b";
+    if (p.string() != "c:/b") {
+      result = false;
+    }
+    p = fs::path("a") / "c:";
+    if (p.string() != "c:") {
+      result = false;
+    }
+    p = fs::path("c:") / "";
+    if (p.string() != "c:") {
+      result = false;
+    }
+    p = fs::path("c:a") / "/b";
+    if (p.string() != "c:/b") {
+      result = false;
+    }
+    p = fs::path("c:a") / "c:b";
+    if (p.string() != "c:a\\b") {
+      result = false;
+    }
+    p = fs::path("//host") / "b";
+    if (p.string() != "//host\\b") {
+      result = false;
+    }
+    p = fs::path("//host/") / "b";
+    if (p.string() != "//host/b") {
+      result = false;
+    }
+  }
+#endif
+
+  checkResult(result);
+
+  return result;
+}
+
+bool testModifiers()
+{
+  std::cout << "testModifiers()";
+
+  bool result = true;
+
+  {
+    std::string s("a///b/");
+    fs::path p(s);
+    std::replace(
+      s.begin(), s.end(), '/',
+      static_cast<std::string::value_type>(fs::path::preferred_separator));
+    p.make_preferred();
+    if (p.string() != s) {
+      result = false;
+    }
+  }
+  {
+    fs::path p("a/b/c.e.f");
+    p.remove_filename();
+    if (p.string() != "a/b/") {
+      result = false;
+    }
+    p.remove_filename();
+    if (p.string() != "a/b/") {
+      result = false;
+    }
+  }
+  {
+    fs::path p("a/b/c.e.f");
+    p.replace_filename("x.y");
+    if (p.string() != "a/b/x.y") {
+      result = false;
+    }
+  }
+  {
+    fs::path p("a/b/c.e.f");
+    p.replace_extension(".x");
+    if (p.string() != "a/b/c.e.x") {
+      result = false;
+    }
+    p.replace_extension(".y");
+    if (p.string() != "a/b/c.e.y") {
+      result = false;
+    }
+    p.replace_extension();
+    if (p.string() != "a/b/c.e") {
+      result = false;
+    }
+    p = "/a/b";
+    p.replace_extension(".x");
+    if (p.string() != "/a/b.x") {
+      result = false;
+    }
+    p = "/a/b/";
+    p.replace_extension(".x");
+    if (p.string() != "/a/b/.x") {
+      result = false;
+    }
+  }
+
+  checkResult(result);
+
+  return result;
+}
+
+bool testObservers()
+{
+  std::cout << "testObservers()";
+
+  bool result = true;
+
+  {
+    std::string s("a/b/c");
+    fs::path p(s);
+    fs::path::string_type st;
+    for (auto c : s) {
+      st += static_cast<fs::path::value_type>(c);
+    }
+    if (p.native() != st || static_cast<fs::path::string_type>(p) != st ||
+        p.c_str() != st) {
+      result = false;
+    }
+  }
+  {
+    std::string s("a//b//c");
+    std::wstring ws(L"a//b//c");
+    fs::path p(s);
+    if (p.string() != s || p.wstring() != ws) {
+      result = false;
+    }
+  }
+  {
+    std::string s("a/b/c");
+    std::wstring ws;
+    for (auto c : s) {
+      ws += static_cast<std::wstring::value_type>(c);
+    }
+    std::string ns(s);
+    std::replace(
+      ns.begin(), ns.end(), '/',
+      static_cast<std::string::value_type>(fs::path::preferred_separator));
+    fs::path p(ns);
+    if (p.generic_string() != s || p.generic_wstring() != ws) {
+      result = false;
+    }
+  }
+
+  checkResult(result);
+
+  return result;
+}
+
+bool testCompare()
+{
+  std::cout << "testCompare()";
+
+  bool result = true;
+
+  {
+    std::string s("a/b/c");
+    fs::path p1(s);
+    fs::path p2(s);
+    if (p1.compare(p2) != 0) {
+      result = false;
+    }
+    p2 = "a/b";
+    if (p1.compare(p2) <= 0) {
+      result = false;
+    }
+    p2 = "a/d";
+    if (p1.compare(p2) >= 0) {
+      result = false;
+    }
+    p2 = "a/b/d";
+    if (p1.compare(p2) >= 0) {
+      result = false;
+    }
+    p2 = "a/b/a";
+    if (p1.compare(p2) <= 0) {
+      result = false;
+    }
+    p2 = "a/b/c/d";
+    if (p1.compare(p2) >= 0) {
+      result = false;
+    }
+    p1 = "a";
+    p2 = "b";
+    if (p1.compare(p2) == 0) {
+      result = false;
+    }
+  }
+  {
+    // LWG 3096 (https://cplusplus.github.io/LWG/issue3096)
+    // fs::path p1("/a/");
+    // fs::path p2("/a/.");
+    // if (p1.compare(p2) != 0) {
+    //   result = false;
+    // }
+  }
+
+  checkResult(result);
+
+  return result;
+}
+
+bool testGeneration()
+{
+  std::cout << "testGeneration()";
+
+  bool result = true;
+
+  {
+    fs::path p("a/./b/..");
+    if (p.lexically_normal().generic_string() != "a/") {
+      result = false;
+    }
+    p = "a/.///b/../";
+    if (p.lexically_normal().generic_string() != "a/") {
+      result = false;
+    }
+  }
+#if defined(_WIN32)
+  {
+    fs::path p("//host/./b/..");
+    if (p.lexically_normal().string() != "\\\\host\\") {
+      result = false;
+    }
+    p = "//host/.///b/../";
+    if (p.lexically_normal().string() != "\\\\host\\") {
+      result = false;
+    }
+    p = "c://a/.///b/../";
+    if (p.lexically_normal().string() != "c:\\a\\") {
+      result = false;
+    }
+  }
+#endif
+
+  {
+    if (fs::path("/a//d").lexically_relative("/a/b/c") != "../../d") {
+      result = false;
+    }
+    if (fs::path("/a//b///c").lexically_relative("/a/d") != "../b/c") {
+      result = false;
+    }
+    if (fs::path("a/b/c").lexically_relative("a") != "b/c") {
+      result = false;
+    }
+    if (fs::path("a/b/c").lexically_relative("a/b/c/x/y") != "../..") {
+      result = false;
+    }
+    if (fs::path("a/b/c").lexically_relative("a/b/c") != ".") {
+      result = false;
+    }
+    if (fs::path("a/b").lexically_relative("c/d") != "../../a/b") {
+      result = false;
+    }
+  }
+  {
+#if defined(_WIN32)
+    if (fs::path("/a/d").lexically_relative("e/d/c") != "/a/d") {
+      result = false;
+    }
+    if (!fs::path("c:/a/d").lexically_relative("e/d/c").empty()) {
+      result = false;
+    }
+#else
+    if (!fs::path("/a/d").lexically_relative("e/d/c").empty()) {
+      result = false;
+    }
+#endif
+  }
+  {
+#if defined(_WIN32)
+    if (fs::path("c:/a/d").lexically_proximate("e/d/c") != "c:/a/d") {
+      result = false;
+    }
+#else
+    if (fs::path("/a/d").lexically_proximate("e/d/c") != "/a/d") {
+      result = false;
+    }
+#endif
+    if (fs::path("/a/d").lexically_proximate("/a/b/c") != "../../d") {
+      result = false;
+    }
+  }
+  // LWG 3070
+  {
+#if defined(_WIN32)
+    if (!fs::path("/a:/b:").lexically_relative("/a:/c:").empty()) {
+      result = false;
+    }
+    if (fs::path("c:/a/b").lexically_relative("c:/a/d") != "../b") {
+      result = false;
+    }
+    if (!fs::path("c:/a/b:").lexically_relative("c:/a/d").empty()) {
+      result = false;
+    }
+    if (!fs::path("c:/a/b").lexically_relative("c:/a/d:").empty()) {
+      result = false;
+    }
+#else
+    if (fs::path("/a:/b:").lexically_relative("/a:/c:") != "../b:") {
+      result = false;
+    }
+#endif
+  }
+  // LWG 3096
+  {
+    if (fs::path("/a").lexically_relative("/a/.") != ".") {
+      result = false;
+    }
+    if (fs::path("/a").lexically_relative("/a/") != ".") {
+      result = false;
+    }
+    if (fs::path("a/b/c").lexically_relative("a/b/c") != ".") {
+      result = false;
+    }
+    if (fs::path("a/b/c").lexically_relative("a/b/c/") != ".") {
+      result = false;
+    }
+    if (fs::path("a/b/c").lexically_relative("a/b/c/.") != ".") {
+      result = false;
+    }
+    if (fs::path("a/b/c/").lexically_relative("a/b/c") != ".") {
+      result = false;
+    }
+    if (fs::path("a/b/c/.").lexically_relative("a/b/c") != ".") {
+      result = false;
+    }
+    if (fs::path("a/b/c/.").lexically_relative("a/b/c/") != ".") {
+      result = false;
+    }
+  }
+
+  checkResult(result);
+
+  return result;
+}
+
+bool testDecomposition()
+{
+  std::cout << "testDecomposition()";
+
+  bool result = true;
+
+  {
+    if (!fs::path("/a/b").root_name().empty()) {
+      result = false;
+    }
+#if defined(_WIN32)
+    if (fs::path("c:/a/b").root_name() != "c:") {
+      result = false;
+    }
+    if (fs::path("c:a/b").root_name() != "c:") {
+      result = false;
+    }
+    if (fs::path("c:").root_name() != "c:") {
+      result = false;
+    }
+    if (fs::path("//host/b").root_name() != "//host") {
+      result = false;
+    }
+    if (fs::path("//host").root_name() != "//host") {
+      result = false;
+    }
+#endif
+  }
+  {
+    if (!fs::path("a/b").root_directory().empty()) {
+      result = false;
+    }
+    if (fs::path("/a/b").root_directory() != "/") {
+      result = false;
+    }
+#if defined(_WIN32)
+    if (!fs::path("c:a/b").root_directory().empty()) {
+      result = false;
+    }
+    if (fs::path("/a/b").root_directory() != "/") {
+      result = false;
+    }
+    if (fs::path("c:/a/b").root_directory() != "/") {
+      result = false;
+    }
+    if (fs::path("//host/b").root_directory() != "/") {
+      result = false;
+    }
+#endif
+  }
+  {
+    if (!fs::path("a/b").root_path().empty()) {
+      result = false;
+    }
+    if (fs::path("/a/b").root_path() != "/") {
+      result = false;
+    }
+#if defined(_WIN32)
+    if (fs::path("c:a/b").root_path() != "c:") {
+      result = false;
+    }
+    if (fs::path("/a/b").root_path() != "/") {
+      result = false;
+    }
+    if (fs::path("c:/a/b").root_path() != "c:/") {
+      result = false;
+    }
+    if (fs::path("//host/b").root_path() != "//host/") {
+      result = false;
+    }
+#endif
+  }
+  {
+    if (!fs::path("/").relative_path().empty()) {
+      result = false;
+    }
+    if (fs::path("a/b").relative_path() != "a/b") {
+      result = false;
+    }
+    if (fs::path("/a/b").relative_path() != "a/b") {
+      result = false;
+    }
+#if defined(_WIN32)
+    if (fs::path("c:a/b").relative_path() != "a/b") {
+      result = false;
+    }
+    if (fs::path("/a/b").relative_path() != "a/b") {
+      result = false;
+    }
+    if (fs::path("c:/a/b").relative_path() != "a/b") {
+      result = false;
+    }
+    if (fs::path("//host/b").relative_path() != "b") {
+      result = false;
+    }
+#endif
+  }
+  {
+    if (fs::path("/a/b").parent_path() != "/a") {
+      result = false;
+    }
+    if (fs::path("/a/b/").parent_path() != "/a/b") {
+      result = false;
+    }
+    if (fs::path("/a/b/.").parent_path() != "/a/b") {
+      result = false;
+    }
+    if (fs::path("/").parent_path() != "/") {
+      result = false;
+    }
+#if defined(_WIN32)
+    if (fs::path("c:/a/b").parent_path() != "c:/a") {
+      result = false;
+    }
+    if (fs::path("c:/").parent_path() != "c:/") {
+      result = false;
+    }
+    if (fs::path("c:").parent_path() != "c:") {
+      result = false;
+    }
+    if (fs::path("//host/").parent_path() != "//host/") {
+      result = false;
+    }
+    if (fs::path("//host").parent_path() != "//host") {
+      result = false;
+    }
+#endif
+  }
+  {
+    if (fs::path("/a/b.txt").filename() != "b.txt") {
+      result = false;
+    }
+    if (fs::path("/a/.b").filename() != ".b") {
+      result = false;
+    }
+    if (fs::path("/foo/bar/").filename() != "") {
+      result = false;
+    }
+    if (fs::path("/foo/.").filename() != ".") {
+      result = false;
+    }
+    if (fs::path("/foo/..").filename() != "..") {
+      result = false;
+    }
+    if (fs::path(".").filename() != ".") {
+      result = false;
+    }
+    if (fs::path("..").filename() != "..") {
+      result = false;
+    }
+    if (!fs::path("/").filename().empty()) {
+      result = false;
+    }
+#if defined(_WIN32)
+    if (fs::path("c:a").filename() != "a") {
+      result = false;
+    }
+    if (fs::path("c:/a").filename() != "a") {
+      result = false;
+    }
+    if (!fs::path("c:").filename().empty()) {
+      result = false;
+    }
+    if (!fs::path("c:/").filename().empty()) {
+      result = false;
+    }
+    if (!fs::path("//host").filename().empty()) {
+      result = false;
+    }
+#endif
+  }
+  {
+    if (fs::path("/a/b.txt").stem() != "b") {
+      result = false;
+    }
+    if (fs::path("/a/b.c.txt").stem() != "b.c") {
+      result = false;
+    }
+    if (fs::path("/a/.b").stem() != ".b") {
+      result = false;
+    }
+    if (fs::path("/a/b").stem() != "b") {
+      result = false;
+    }
+    if (fs::path("/a/b/.").stem() != ".") {
+      result = false;
+    }
+    if (fs::path("/a/b/..").stem() != "..") {
+      result = false;
+    }
+    if (!fs::path("/a/b/").stem().empty()) {
+      result = false;
+    }
+#if defined(_WIN32)
+    if (!fs::path("c:/a/b/").stem().empty()) {
+      result = false;
+    }
+    if (!fs::path("c:/").stem().empty()) {
+      result = false;
+    }
+    if (!fs::path("c:").stem().empty()) {
+      result = false;
+    }
+    if (!fs::path("//host/").stem().empty()) {
+      result = false;
+    }
+    if (!fs::path("//host").stem().empty()) {
+      result = false;
+    }
+#endif
+  }
+  {
+    if (fs::path("/a/b.txt").extension() != ".txt") {
+      result = false;
+    }
+    if (fs::path("/a/b.").extension() != ".") {
+      result = false;
+    }
+    if (!fs::path("/a/b").extension().empty()) {
+      result = false;
+    }
+    if (fs::path("/a/b.txt/b.cc").extension() != ".cc") {
+      result = false;
+    }
+    if (fs::path("/a/b.txt/b.").extension() != ".") {
+      result = false;
+    }
+    if (!fs::path("/a/b.txt/b").extension().empty()) {
+      result = false;
+    }
+    if (!fs::path("/a/.").extension().empty()) {
+      result = false;
+    }
+    if (!fs::path("/a/..").extension().empty()) {
+      result = false;
+    }
+    if (!fs::path("/a/.hidden").extension().empty()) {
+      result = false;
+    }
+    if (fs::path("/a/..b").extension() != ".b") {
+      result = false;
+    }
+  }
+
+  checkResult(result);
+
+  return result;
+}
+
+bool testQueries()
+{
+  std::cout << "testQueries()";
+
+  bool result = true;
+
+  {
+    if (fs::path("/a/b").has_root_name()) {
+      result = false;
+    }
+    fs::path p("/a/b");
+    if (!p.has_root_directory() || !p.has_root_path()) {
+      result = false;
+    }
+    if (!fs::path("/a/b").has_root_path() || fs::path("a/b").has_root_path()) {
+      result = false;
+    }
+    if (!fs::path("/a/b").has_relative_path() ||
+        fs::path("/").has_relative_path()) {
+      result = false;
+    }
+    if (!fs::path("/a/b").has_parent_path() ||
+        !fs::path("/").has_parent_path() || fs::path("a").has_parent_path()) {
+      result = false;
+    }
+    if (!fs::path("/a/b").has_filename() || !fs::path("a.b").has_filename() ||
+        fs::path("/a/").has_filename() || fs::path("/").has_filename()) {
+      result = false;
+    }
+    if (!fs::path("/a/b").has_stem() || !fs::path("a.b").has_stem() ||
+        !fs::path("/.a").has_stem() || fs::path("/a/").has_stem() ||
+        fs::path("/").has_stem()) {
+      result = false;
+    }
+    if (!fs::path("/a/b.c").has_extension() ||
+        !fs::path("a.b").has_extension() || fs::path("/.a").has_extension() ||
+        fs::path("/a/").has_extension() || fs::path("/").has_extension()) {
+      result = false;
+    }
+#if defined(_WIN32)
+    p = "c:/a/b";
+    if (!fs::path("c:/a/b").has_root_name() || !p.has_root_directory() ||
+        !p.has_root_path()) {
+      result = false;
+    }
+    p = "c:a/b";
+    if (!p.has_root_name() || p.has_root_directory() || !p.has_root_path()) {
+      result = false;
+    }
+    p = "//host/b";
+    if (!p.has_root_name() || !p.has_root_directory() || !p.has_root_path()) {
+      result = false;
+    }
+    p = "//host";
+    if (!p.has_root_name() || p.has_root_directory() || !p.has_root_path()) {
+      result = false;
+    }
+    if (!fs::path("c:/a/b").has_relative_path() ||
+        !fs::path("c:a/b").has_relative_path() ||
+        !fs::path("//host/b").has_relative_path()) {
+      result = false;
+    }
+    if (!fs::path("c:/a/b").has_parent_path() ||
+        !fs::path("c:/").has_parent_path() ||
+        !fs::path("c:").has_parent_path() ||
+        !fs::path("//host/").has_parent_path() ||
+        !fs::path("//host").has_parent_path()) {
+      result = false;
+    }
+#endif
+  }
+  {
+#if defined(_WIN32)
+    fs::path p("c:/a");
+#else
+    fs::path p("/a");
+#endif
+    if (!p.is_absolute() || p.is_relative()) {
+      result = false;
+    }
+    p = "a/b";
+    if (p.is_absolute() || !p.is_relative()) {
+      result = false;
+    }
+#if defined(_WIN32)
+    p = "c:/a/b";
+    if (!p.is_absolute() || p.is_relative()) {
+      result = false;
+    }
+    p = "//host/b";
+    if (!p.is_absolute() || p.is_relative()) {
+      result = false;
+    }
+    p = "/a";
+    if (p.is_absolute() || !p.is_relative()) {
+      result = false;
+    }
+    p = "c:a";
+    if (p.is_absolute() || !p.is_relative()) {
+      result = false;
+    }
+#endif
+  }
+
+  checkResult(result);
+
+  return result;
+}
+
+bool testIterators()
+{
+  std::cout << "testIterators()";
+
+  bool result = true;
+
+  {
+    fs::path p("/a/b/");
+#if defined(_WIN32)
+    std::vector<fs::path::string_type> ref{ L"/", L"a", L"b", L"" };
+#else
+    std::vector<fs::path::string_type> ref{ "/", "a", "b", "" };
+#endif
+    std::vector<fs::path::string_type> res;
+    for (auto i = p.begin(), e = p.end(); i != e; ++i) {
+      res.push_back(*i);
+    }
+    if (res != ref) {
+      result = false;
+    }
+    res.clear();
+    for (const auto& e : p) {
+      res.push_back(e);
+    }
+    if (res != ref) {
+      result = false;
+    }
+  }
+  {
+    fs::path p("/a/b/");
+#if defined(_WIN32)
+    std::vector<fs::path::string_type> ref{ L"", L"b", L"a", L"/" };
+#else
+    std::vector<fs::path::string_type> ref{ "", "b", "a", "/" };
+#endif
+    std::vector<fs::path::string_type> res;
+    auto i = p.end(), b = p.begin();
+    do {
+      res.push_back(*--i);
+    } while (i != b);
+    if (res != ref) {
+      result = false;
+    }
+  }
+
+  checkResult(result);
+
+  return result;
+}
+
+bool testNonMemberFunctions()
+{
+  std::cout << "testNonMemberFunctions()";
+
+  bool result = true;
+
+  {
+    fs::path p1("/a/b/");
+    fs::path p2("/c/d");
+    fs::swap(p1, p2);
+    if (p1.string() != "/c/d" || p2.string() != "/a/b/")
+      result = false;
+  }
+  {
+    auto h1 = fs::hash_value(fs::path("/a//b//"));
+    auto h2 = fs::hash_value(fs::path("/a/b/"));
+    if (h1 != h2)
+      result = false;
+  }
+  {
+    fs::path p1("/a/b/");
+    fs::path p2("/c/d");
+    if (p1 == p2)
+      result = false;
+    p1 = "/a//b//";
+    p2 = "/a/b/";
+    if (p1 != p2)
+      result = false;
+  }
+  {
+    fs::path p = "/a";
+    p = p / "b" / "c";
+    if (p.generic_string() != "/a/b/c") {
+      result = false;
+    }
+    fs::path::string_type ref;
+    ref += fs::path::value_type('/');
+    ref += fs::path::value_type('a');
+    ref += fs::path::preferred_separator;
+    ref += fs::path::value_type('b');
+    ref += fs::path::preferred_separator;
+    ref += fs::path::value_type('c');
+    if (p.native() != ref) {
+      result = false;
+    }
+  }
+  {
+    fs::path p("/a b\\c/");
+    std::ostringstream oss;
+    oss << p;
+    if (oss.str() != "\"/a b\\\\c/\"") {
+      result = false;
+    }
+    std::istringstream iss(oss.str());
+    fs::path p2;
+    iss >> p2;
+    if (p2 != p) {
+      result = false;
+    }
+  }
+
+  checkResult(result);
+
+  return result;
+}
+}
+
+int testCMFilesystemPath(int /*unused*/, char* /*unused*/ [])
+{
+  int result = 0;
+
+  if (!testConstructors()) {
+    result = 1;
+  }
+  if (!testConcatenation()) {
+    result = 1;
+  }
+  if (!testModifiers()) {
+    result = 1;
+  }
+  if (!testObservers()) {
+    result = 1;
+  }
+  if (!testCompare()) {
+    result = 1;
+  }
+  if (!testGeneration()) {
+    result = 1;
+  }
+  if (!testDecomposition()) {
+    result = 1;
+  }
+  if (!testQueries()) {
+    result = 1;
+  }
+  if (!testIterators()) {
+    result = 1;
+  }
+  if (!testNonMemberFunctions()) {
+    result = 1;
+  }
+
+  return result;
+}
diff --git a/Tests/CMakeLib/testRST.expect b/Tests/CMakeLib/testRST.expect
index c19ee94..970adaa 100644
--- a/Tests/CMakeLib/testRST.expect
+++ b/Tests/CMakeLib/testRST.expect
@@ -5,7 +5,7 @@
 Command ``some_cmd()`` without target.
 Command ``some_cmd`` with target.
 Command ``some_cmd_<cmd>()`` placeholder without target.
-Command ``some_cmd_<cmd>`` placholder with target.
+Command ``some_cmd_<cmd>`` placeholder with target.
 Command ``some_cmd()`` with parens.
 Command ``some_cmd(SUB)`` with subcommand.
 Command ``some_cmd(SUB)`` with subcommand and target.
diff --git a/Tests/CMakeLib/testRST.rst b/Tests/CMakeLib/testRST.rst
index d2d1140..6462f1b 100644
--- a/Tests/CMakeLib/testRST.rst
+++ b/Tests/CMakeLib/testRST.rst
@@ -12,7 +12,7 @@
 Command :command:`some_cmd` without target.
 Command :command:`some_cmd <some_cmd>` with target.
 Command :command:`some_cmd_<cmd>` placeholder without target.
-Command :command:`some_cmd_<cmd> <some_cmd>` placholder with target.
+Command :command:`some_cmd_<cmd> <some_cmd>` placeholder with target.
 Command :command:`some_cmd()` with parens.
 Command :command:`some_cmd(SUB)` with subcommand.
 Command :command:`some_cmd(SUB) <some_cmd>` with subcommand and target.
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index db6dbf3..4a774dd 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -206,6 +206,26 @@
         set(${reg} 0)
       endif()
     endforeach()
+    if(COMMAND cmake_host_system_information)
+      set(info_vs15 "VS_15_DIR")
+      set(info_vs16 "VS_16_DIR")
+      set(vs_versions)
+      if(WIN32)
+        if(NOT CMAKE_VERSION VERSION_LESS 3.14)
+          set(vs_versions vs15 vs16)
+        elseif(NOT CMAKE_VERSION VERSION_LESS 3.8)
+          set(vs_versions vs15)
+        endif()
+      endif()
+      foreach(info ${vs_versions})
+        cmake_host_system_information(RESULT found QUERY "${info_${info}}")
+        if(found)
+          set(${info} 1)
+        else()
+          set(${info} 0)
+        endif()
+      endforeach()
+    endif()
   endif()
 
   #---------------------------------------------------------------------------
@@ -697,38 +717,28 @@
   # build the "Simple" test with the ExtraGenerators, if available
   # This doesn't test whether the generated project files work (unfortunately),
   # mainly it tests that cmake doesn't crash when generating these project files.
-  if(${CMAKE_GENERATOR} MATCHES "Unix Makefiles" OR ${CMAKE_GENERATOR} MATCHES "Ninja")
-
-    # check which generators we have
-    execute_process(COMMAND ${CMAKE_CMAKE_COMMAND} --help
-      OUTPUT_VARIABLE cmakeOutput ERROR_VARIABLE cmakeOutput)
-
-    set(extraGenerators
-      "CodeBlocks"
-      "CodeLite"
-      "Eclipse CDT4"
-      "Kate"
-      "Sublime Text 2")
-
-    foreach(extraGenerator ${extraGenerators})
-      if ("${cmakeOutput}" MATCHES "${extraGenerator} - ${CMAKE_GENERATOR}")
-        set(extraGeneratorTestName "Simple_${extraGenerator}Generator")
-        string(REPLACE " " "" extraGeneratorTestName ${extraGeneratorTestName})
-
-        add_test(${extraGeneratorTestName} ${CMAKE_CTEST_COMMAND}
-          --build-and-test
-          "${CMake_SOURCE_DIR}/Tests/Simple"
-          "${CMake_BINARY_DIR}/Tests/${extraGeneratorTestName}"
-          --build-two-config
-          --build-generator "${extraGenerator} - ${CMAKE_GENERATOR}"
-          --build-generator-platform "${CMAKE_GENERATOR_PLATFORM}"
-          --build-generator-toolset "${CMAKE_GENERATOR_TOOLSET}"
-          --build-project Simple
-          --test-command Simple)
-        list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/${extraGeneratorTestName}")
-      endif ()
-    endforeach(extraGenerator)
-
+  if(CMAKE_GENERATOR MATCHES "^(Unix Makefiles|Ninja)$"
+      AND NOT "${CMAKE_CURRENT_BINARY_DIR}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}")
+    foreach(extraGenerator
+        "CodeBlocks"
+        "CodeLite"
+        "Eclipse CDT4"
+        "Kate"
+        "Sublime Text 2"
+        )
+      string(REPLACE " " "" extraGeneratorTestName "Simple_${extraGenerator}Generator")
+      add_test(${extraGeneratorTestName} ${CMAKE_CTEST_COMMAND}
+        --build-and-test
+        "${CMake_SOURCE_DIR}/Tests/Simple"
+        "${CMake_BINARY_DIR}/Tests/${extraGeneratorTestName}"
+        --build-two-config
+        --build-generator "${extraGenerator} - ${CMAKE_GENERATOR}"
+        --build-generator-platform "${CMAKE_GENERATOR_PLATFORM}"
+        --build-generator-toolset "${CMAKE_GENERATOR_TOOLSET}"
+        --build-project Simple
+        --test-command Simple)
+      list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/${extraGeneratorTestName}")
+    endforeach()
   endif()
 
   # test for correct sub-project generation
@@ -1451,6 +1461,7 @@
             Patch
             PostgreSQL
             Protobuf
+            SDL
             SQLite3
             TIFF
             Vulkan
@@ -2315,32 +2326,41 @@
     endforeach()
   endif()
 
+  macro(add_test_VSAndroid name generator platform)
+    add_test(NAME "VSAndroid.${name}.${platform}" COMMAND ${CMAKE_CTEST_COMMAND}
+      --build-and-test
+      "${CMake_SOURCE_DIR}/Tests/VSAndroid"
+      "${CMake_BINARY_DIR}/Tests/VSAndroid/${name}/${platform}"
+      --build-generator "${generator}"
+      --build-project VSAndroid
+      --build-config $<CONFIGURATION>
+      --build-options -DCMAKE_SYSTEM_NAME=Android "-A${platform}"
+      )
+    list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/VSAndroid/${name}")
+  endmacro()
   if(tegra AND NOT "${CMake_SOURCE_DIR};${CMake_BINARY_DIR}" MATCHES " ")
-    macro(add_test_VSNsightTegra name generator)
-      add_test(NAME VSNsightTegra.${name} COMMAND ${CMAKE_CTEST_COMMAND}
-        --build-and-test
-        "${CMake_SOURCE_DIR}/Tests/VSNsightTegra"
-        "${CMake_BINARY_DIR}/Tests/VSNsightTegra/${name}"
-        --build-generator "${generator}"
-        --build-project VSNsightTegra
-        --build-config $<CONFIGURATION>
-        --build-options -DCMAKE_SYSTEM_NAME=Android
-        )
-      list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/VSNsightTegra/${name}")
-    endmacro()
     if(vs10)
-      add_test_VSNsightTegra(vs10 "Visual Studio 10 2010")
+      add_test_VSAndroid(vs10 "Visual Studio 10 2010" "Tegra-Android")
     endif()
     if(vs11)
-      add_test_VSNsightTegra(vs11 "Visual Studio 11 2012")
+      add_test_VSAndroid(vs11 "Visual Studio 11 2012" "Tegra-Android")
     endif()
     if(vs12)
-      add_test_VSNsightTegra(vs12 "Visual Studio 12 2013")
+      add_test_VSAndroid(vs12 "Visual Studio 12 2013" "Tegra-Android")
     endif()
     if(vs14)
-      add_test_VSNsightTegra(vs14 "Visual Studio 14 2015")
+      add_test_VSAndroid(vs14 "Visual Studio 14 2015" "Tegra-Android")
     endif()
   endif()
+  if(vs14 AND CMake_TEST_ANDROID_VS14)
+    add_test_VSAndroid(vs14 "Visual Studio 14 2015" "ARM")
+  endif()
+  if(vs15 AND CMake_TEST_ANDROID_VS15)
+    add_test_VSAndroid(vs15 "Visual Studio 15 2017" "ARM")
+  endif()
+  if(vs16 AND CMake_TEST_ANDROID_VS16)
+    add_test_VSAndroid(vs16 "Visual Studio 16 2019" "ARM")
+  endif()
 
   if (APPLE)
     if (CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
@@ -2397,36 +2417,6 @@
     list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/BundleGeneratorTest")
   endif()
 
-  add_test(WarnUnusedUnusedViaSet ${CMAKE_CTEST_COMMAND}
-    --build-and-test
-    "${CMake_SOURCE_DIR}/Tests/VariableUnusedViaSet"
-    "${CMake_BINARY_DIR}/Tests/WarnUnusedUnusedViaSet"
-    ${build_generator_args}
-    --build-noclean
-    --build-project WarnUnusedUnusedViaSet
-    --build-options
-      "--warn-unused-vars")
-  set_tests_properties(WarnUnusedUnusedViaSet PROPERTIES
-    PASS_REGULAR_EXPRESSION "unused variable \\(changing definition\\) 'UNUSED_VARIABLE'")
-  set_tests_properties(WarnUnusedUnusedViaSet PROPERTIES
-    FAIL_REGULAR_EXPRESSION "unused variable \\(unsetting\\) 'UNUSED_VARIABLE'")
-  list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/WarnUnusedUnusedViaSet")
-
-  add_test(WarnUnusedUnusedViaUnset ${CMAKE_CTEST_COMMAND}
-    --build-and-test
-    "${CMake_SOURCE_DIR}/Tests/VariableUnusedViaUnset"
-    "${CMake_BINARY_DIR}/Tests/WarnUnusedUnusedViaUnset"
-    ${build_generator_args}
-    --build-noclean
-    --build-project WarnUnusedUnusedViaUnset
-    --build-options
-      "--warn-unused-vars")
-  set_tests_properties(WarnUnusedUnusedViaUnset PROPERTIES
-    PASS_REGULAR_EXPRESSION "CMake Warning \\(dev\\) at CMakeLists.txt:7 \\(set\\):")
-  set_tests_properties(WarnUnusedUnusedViaUnset PROPERTIES
-    FAIL_REGULAR_EXPRESSION "CMakeLists.txt:5 \\(set\\):")
-  list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/WarnUnusedUnusedViaUnset")
-
   add_test(WarnUnusedCliUnused ${CMAKE_CTEST_COMMAND}
     --build-and-test
     "${CMake_SOURCE_DIR}/Tests/WarnUnusedCliUnused"
@@ -2916,7 +2906,7 @@
       PASS_REGULAR_EXPRESSION "Failed")
   else()
     set_tests_properties(CTestTestCrash PROPERTIES
-      PASS_REGULAR_EXPRESSION "(Illegal|SegFault|Child aborted)")
+      PASS_REGULAR_EXPRESSION "(Illegal|SegFault|Subprocess aborted)")
   endif()
 
   configure_file(
diff --git a/Tests/CMakeTests/CMakeLists.txt b/Tests/CMakeTests/CMakeLists.txt
index e32d693..348e6d0 100644
--- a/Tests/CMakeTests/CMakeLists.txt
+++ b/Tests/CMakeTests/CMakeLists.txt
@@ -35,7 +35,7 @@
 AddCMakeTest(FileDownload "")
 set_tests_properties(CMake.FileDownload PROPERTIES
   PASS_REGULAR_EXPRESSION "file already exists with expected MD5 sum"
-  FAIL_REGULAR_EXPRESSION "Unexpected status"
+  FAIL_REGULAR_EXPRESSION "Unexpected status|incorrectly interpreted"
   )
 AddCMakeTest(FileDownloadBadHash "")
 set_property(TEST CMake.FileDownloadBadHash PROPERTY
diff --git a/Tests/CMakeTests/FileDownloadTest.cmake.in b/Tests/CMakeTests/FileDownloadTest.cmake.in
index 76c0000..69d9a14 100644
--- a/Tests/CMakeTests/FileDownloadTest.cmake.in
+++ b/Tests/CMakeTests/FileDownloadTest.cmake.in
@@ -163,3 +163,16 @@
 if(NOT EXISTS file12.png)
   message(SEND_ERROR "file12.png not downloaded: ${status}")
 endif()
+
+message(STATUS "FileDownload:13")
+file(DOWNLOAD
+  ${url}
+  TIMEOUT ${timeout}
+  STATUS status
+  )
+__reportIfWrongStatus("${status}" 0)
+if(EXISTS TIMEOUT)
+  file(REMOVE TIMEOUT)
+  message(SEND_ERROR "TIMEOUT argument was incorrectly interpreted as a filename")
+endif()
+message(STATUS "${status}")
diff --git a/Tests/CMakeTests/FileTestScript.cmake b/Tests/CMakeTests/FileTestScript.cmake
index 145f28a..fc3c28a 100644
--- a/Tests/CMakeTests/FileTestScript.cmake
+++ b/Tests/CMakeTests/FileTestScript.cmake
@@ -10,7 +10,7 @@
   file(DIFFERENT ffff)
 
 elseif(testname STREQUAL download_not_enough_args) # fail
-  file(DOWNLOAD ffff)
+  file(DOWNLOAD)
 
 elseif(testname STREQUAL read_not_enough_args) # fail
   file(READ ffff)
@@ -181,7 +181,7 @@
   message("v='${v}'")
 
 elseif(testname STREQUAL download_wrong_number_of_args) # fail
-  file(DOWNLOAD zzzz://bogus/ffff)
+  file(DOWNLOAD)
 
 elseif(testname STREQUAL download_file_with_no_path) # pass
   file(DOWNLOAD zzzz://bogus/ffff ffff)
diff --git a/Tests/COnly/CMakeLists.txt b/Tests/COnly/CMakeLists.txt
index 20615fe..1c24017 100644
--- a/Tests/COnly/CMakeLists.txt
+++ b/Tests/COnly/CMakeLists.txt
@@ -1,5 +1,5 @@
 # a simple C only test case
-cmake_minimum_required (VERSION 2.6)
+cmake_minimum_required(VERSION 2.8.12)
 project (COnly C)
 
 set(CMAKE_DEBUG_POSTFIX "_test_debug_postfix")
diff --git a/Tests/CPackComponentsForAll/RunCPackVerifyResult.cmake b/Tests/CPackComponentsForAll/RunCPackVerifyResult.cmake
index 253d128..f3d3ad0 100644
--- a/Tests/CPackComponentsForAll/RunCPackVerifyResult.cmake
+++ b/Tests/CPackComponentsForAll/RunCPackVerifyResult.cmake
@@ -88,12 +88,14 @@
     set(expected_file_mask "${CPackComponentsForAll_BINARY_DIR}/MyLib-*.dmg")
     if(${CPackComponentWay} STREQUAL "default")
         set(expected_count 1)
+        set(expect_dmg_sla 1)
     elseif(${CPackComponentWay} STREQUAL "OnePackPerGroup")
         set(expected_count 3)
     elseif(${CPackComponentWay} STREQUAL "IgnoreGroup")
         set(expected_count 4)
     elseif(${CPackComponentWay} STREQUAL "AllInOne")
         set(expected_count 1)
+        set(expect_dmg_sla 1)
     endif()
 endif()
 
@@ -138,6 +140,36 @@
   if(NOT actual_count EQUAL expected_count)
     message(FATAL_ERROR "error: expected_count=${expected_count} does not match actual_count=${actual_count}: CPackComponents test fails. (CPack_output=${CPack_output}, CPack_error=${CPack_error})")
   endif()
+
+  if(expect_dmg_sla)
+    execute_process(COMMAND hdiutil udifderez -xml "${expected_file}" OUTPUT_VARIABLE out ERROR_VARIABLE err RESULT_VARIABLE res)
+    if(NOT res EQUAL 0)
+      string(REPLACE "\n" "\n  " err "  ${err}")
+      message(FATAL_ERROR "error: running 'hdiutil udifderez -xml' on\n  ${expected_file}\nfailed with:\n${err}")
+    endif()
+    foreach(key "LPic" "STR#" "TEXT")
+      if(NOT out MATCHES "<key>${key}</key>")
+        string(REPLACE "\n" "\n  " out "  ${out}")
+        message(FATAL_ERROR "error: running 'hdiutil udifderez -xml' on\n  ${expected_file}\ndid not show '${key}' key:\n${out}")
+      endif()
+    endforeach()
+    foreach(line
+        # LPic first and last base64 lines
+        "\tAAIAEQADAAEAAAAAAAIAAAAIAAMAAAABAAQAAAAEAAUAAAAOAAYA\n"
+        "\tAA0AAABbAAQAAAAzAA8AAQAMABAAAAALAA4AAA==\n"
+        # STR# first and last base64 lines
+        "\tAAkHRW5nbGlzaAVBZ3JlZQhEaXNhZ3JlZQVQcmludAdTYXZlLi4u\n"
+        "\tdGVkIGEgcHJpbnRlci4=\n"
+        # TEXT first and last base64 lines
+        "\tTElDRU5TRQ0tLS0tLS0tDVRoaXMgaXMgYW4gaW5zdGFsbGVyIGNy\n"
+        "\tTm8gbGljZW5zZSBwcm92aWRlZC4NDQ==\n"
+        )
+      if(NOT out MATCHES "${line}")
+        string(REPLACE "\n" "\n  " out "  ${out}")
+        message(FATAL_ERROR "error: running 'hdiutil udifderez -xml' on\n  ${expected_file}\ndid not show '${line}':\n${out}")
+      endif()
+    endforeach()
+  endif()
 endif()
 
 # Validate content
diff --git a/Tests/CSharpOnly/CMakeLists.txt b/Tests/CSharpOnly/CMakeLists.txt
index 42cbe2e..195af05 100644
--- a/Tests/CSharpOnly/CMakeLists.txt
+++ b/Tests/CSharpOnly/CMakeLists.txt
@@ -1,3 +1,4 @@
+cmake_minimum_required(VERSION 3.3)
 # a simple CSharp only test case
 project (CSharpOnly CSharp)
 
diff --git a/Tests/Cuda/MixedStandardLevels4/lib.cpp b/Tests/Cuda/MixedStandardLevels4/lib.cpp
index ef6fc20..2a65c77 100644
--- a/Tests/Cuda/MixedStandardLevels4/lib.cpp
+++ b/Tests/Cuda/MixedStandardLevels4/lib.cpp
@@ -3,7 +3,7 @@
 constexpr int func(int A, int B)
 {
 #if defined(_MSC_VER) && _MSC_VER < 1913
-  // no suppport for extended constexpr
+  // no support for extended constexpr
   return B * A;
 #else
   // Verify that we have at least c++14
diff --git a/Tests/CudaOnly/DontResolveDeviceSymbols/file1.cu b/Tests/CudaOnly/DontResolveDeviceSymbols/file1.cu
index 3924f67..90c70e2 100644
--- a/Tests/CudaOnly/DontResolveDeviceSymbols/file1.cu
+++ b/Tests/CudaOnly/DontResolveDeviceSymbols/file1.cu
@@ -61,7 +61,7 @@
   err = cudaGetLastError();
   std::cout << err << " " << cudaGetErrorString(err) << std::endl;
   if (err == cudaSuccess) {
-    // This kernel launch should failed as the device linking never occured
+    // This kernel launch should failed as the device linking never occurred
     std::cerr << "file1_kernel: kernel launch should have failed" << std::endl;
     return 1;
   }
diff --git a/Tests/CxxOnly/CMakeLists.txt b/Tests/CxxOnly/CMakeLists.txt
index 8207dd1..09689cb 100644
--- a/Tests/CxxOnly/CMakeLists.txt
+++ b/Tests/CxxOnly/CMakeLists.txt
@@ -1,4 +1,5 @@
 # a simple CXX only test case
+cmake_minimum_required(VERSION 2.8.12)
 project (CxxOnly CXX)
 
 set(CMAKE_DEBUG_POSTFIX "_test_debug_postfix")
diff --git a/Tests/ExportImport/Export/Interface/CMakeLists.txt b/Tests/ExportImport/Export/Interface/CMakeLists.txt
index 43b7217..ba2164b 100644
--- a/Tests/ExportImport/Export/Interface/CMakeLists.txt
+++ b/Tests/ExportImport/Export/Interface/CMakeLists.txt
@@ -1,11 +1,26 @@
-
-add_library(headeronly INTERFACE)
+set(headeronly_headers headeronly/headeronly.h)
+add_library(headeronly INTERFACE ${headeronly_headers})
 set_property(TARGET headeronly PROPERTY INTERFACE_INCLUDE_DIRECTORIES
   "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/headeronly>"
   "$<INSTALL_INTERFACE:${CMAKE_INSTALL_PREFIX}/include/headeronly>"
 )
 set_property(TARGET headeronly PROPERTY INTERFACE_COMPILE_DEFINITIONS "HEADERONLY_DEFINE")
 
+add_custom_command(OUTPUT headergen/headergen.h
+  COMMAND ${CMAKE_COMMAND} -E copy
+    ${CMAKE_CURRENT_SOURCE_DIR}/headergen.h.in
+    ${CMAKE_CURRENT_BINARY_DIR}/headergen/headergen.h
+  DEPENDS
+    ${CMAKE_CURRENT_SOURCE_DIR}/headergen.h.in
+  VERBATIM)
+
+add_library(headergen INTERFACE headergen/headergen.h)
+set_property(TARGET headergen PROPERTY INTERFACE_INCLUDE_DIRECTORIES
+  "$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/headergen>"
+)
+set_property(TARGET headergen PROPERTY PUBLIC_HEADER
+  ${CMAKE_CURRENT_BINARY_DIR}/headergen/headergen.h)
+
 add_library(pch_iface INTERFACE)
 target_precompile_headers(pch_iface INTERFACE
   "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/pch/pch.h>"
@@ -54,6 +69,11 @@
                 pch_iface cmakeonly
   EXPORT expInterface
 )
+install(TARGETS headergen
+  EXPORT expInterface
+  PUBLIC_HEADER DESTINATION include/headergen
+  INCLUDES DESTINATION include/headergen
+)
 install(TARGETS sharedlib
   EXPORT expInterface
   RUNTIME DESTINATION bin
@@ -63,7 +83,7 @@
   BUNDLE DESTINATION Applications
 )
 install(FILES
-  headeronly/headeronly.h
+  ${headeronly_headers}
   DESTINATION include/headeronly
 )
 install(FILES
diff --git a/Tests/ExportImport/Export/Interface/headergen.h.in b/Tests/ExportImport/Export/Interface/headergen.h.in
new file mode 100644
index 0000000..bda2b81
--- /dev/null
+++ b/Tests/ExportImport/Export/Interface/headergen.h.in
@@ -0,0 +1 @@
+#define HEADERGEN_H
diff --git a/Tests/ExportImport/Import/Interface/CMakeLists.txt b/Tests/ExportImport/Import/Interface/CMakeLists.txt
index ef666b1..202c23e 100644
--- a/Tests/ExportImport/Import/Interface/CMakeLists.txt
+++ b/Tests/ExportImport/Import/Interface/CMakeLists.txt
@@ -12,6 +12,9 @@
 add_executable(headeronlytest_bld headeronlytest.cpp)
 target_link_libraries(headeronlytest_bld bld::headeronly)
 
+add_executable(headergentest_bld headergentest.cpp)
+target_link_libraries(headergentest_bld bld::headergen)
+
 set_property(TARGET bld::sharediface APPEND PROPERTY INTERFACE_LINK_LIBRARIES define_iface)
 
 add_executable(interfacetest_bld interfacetest.cpp)
@@ -93,6 +96,9 @@
 add_executable(headeronlytest_exp headeronlytest.cpp)
 target_link_libraries(headeronlytest_exp exp::headeronly)
 
+add_executable(headergentest_exp headergentest.cpp)
+target_link_libraries(headergentest_exp exp::headergen)
+
 set_property(TARGET exp::sharediface APPEND PROPERTY INTERFACE_LINK_LIBRARIES define_iface)
 
 add_executable(interfacetest_exp interfacetest.cpp)
diff --git a/Tests/ExportImport/Import/Interface/headergentest.cpp b/Tests/ExportImport/Import/Interface/headergentest.cpp
new file mode 100644
index 0000000..88ff7f1
--- /dev/null
+++ b/Tests/ExportImport/Import/Interface/headergentest.cpp
@@ -0,0 +1,11 @@
+
+#include "headergen.h"
+
+#ifndef HEADERGEN_H
+#  error Expected HEADERGEN_H
+#endif
+
+int main()
+{
+  return 0;
+}
diff --git a/Tests/FindPackageModeMakefileTest/Makefile.in b/Tests/FindPackageModeMakefileTest/Makefile.in
index 5ef67d0..af9fa96 100644
--- a/Tests/FindPackageModeMakefileTest/Makefile.in
+++ b/Tests/FindPackageModeMakefileTest/Makefile.in
@@ -24,7 +24,7 @@
 pngtest: main.o
 	@$(CMAKE_FOO) -DMODE=LINK >$(tmp)
 	@foo="`cat $(tmp)`"; \
-	 printf '"%s" %s %s -o pngtest main.o %s\n' $(CMAKE_CXX_COMPILER) "$(CMAKE_CXX_FLAGS)" "$(LDFLAGS)" "$$foo" >$(tmp)
+	 printf '"%s" %s %s %s -o pngtest main.o %s\n' $(CMAKE_CXX_COMPILER) "$(CMAKE_CXX_FLAGS)" "$(__EXTRA_OSX_SYSROOT_FLAGS)" "$(LDFLAGS)" "$$foo" >$(tmp)
 	@cat $(tmp)
 	@sh $(tmp)
 	@rm -f $(tmp)
diff --git a/Tests/FindSDL/CMakeLists.txt b/Tests/FindSDL/CMakeLists.txt
new file mode 100644
index 0000000..e786204
--- /dev/null
+++ b/Tests/FindSDL/CMakeLists.txt
@@ -0,0 +1,10 @@
+add_test(NAME FindSDL.Test COMMAND
+  ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+  --build-and-test
+  "${CMake_SOURCE_DIR}/Tests/FindSDL/Test"
+  "${CMake_BINARY_DIR}/Tests/FindSDL/Test"
+  ${build_generator_args}
+  --build-project TestFindSDL
+  --build-options ${build_options}
+  --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+  )
diff --git a/Tests/FindSDL/Test/CMakeLists.txt b/Tests/FindSDL/Test/CMakeLists.txt
new file mode 100644
index 0000000..61d4f4b
--- /dev/null
+++ b/Tests/FindSDL/Test/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 3.1)
+project(TestFindSDL C)
+include(CTest)
+
+find_package(SDL)
+
+add_definitions(
+  -DCMAKE_EXPECTED_SDL_VERSION_MAJOR=${SDL_VERSION_MAJOR}
+  -DCMAKE_EXPECTED_SDL_VERSION_MINOR=${SDL_VERSION_MINOR}
+  -DCMAKE_EXPECTED_SDL_VERSION_PATCH=${SDL_VERSION_PATCH})
+
+add_executable(test_sdl_tgt main.c)
+target_link_libraries(test_sdl_tgt SDL::SDL)
+add_test(NAME test_sdl_tgt COMMAND test_sdl_tgt)
+
+add_executable(test_sdl_var main.c)
+target_include_directories(test_sdl_var PRIVATE ${SDL_INCLUDE_DIRS})
+target_link_libraries(test_sdl_var PRIVATE ${SDL_LIBRARIES})
+add_test(NAME test_sdl_var COMMAND test_sdl_var)
diff --git a/Tests/FindSDL/Test/main.c b/Tests/FindSDL/Test/main.c
new file mode 100644
index 0000000..057289c
--- /dev/null
+++ b/Tests/FindSDL/Test/main.c
@@ -0,0 +1,18 @@
+#include <SDL.h>
+
+int main()
+{
+  // Test 1 requires headers only.
+  SDL_version compiled;
+  SDL_VERSION(&compiled);
+  if (compiled.major != CMAKE_EXPECTED_SDL_VERSION_MAJOR ||
+      compiled.minor != CMAKE_EXPECTED_SDL_VERSION_MINOR ||
+      compiled.patch != CMAKE_EXPECTED_SDL_VERSION_PATCH)
+    return 1;
+
+  // Test 2 requires to link to the library.
+  if (SDL_WasInit(SDL_INIT_VIDEO | SDL_INIT_AUDIO) != 0)
+    return 2;
+
+  return 0;
+}
diff --git a/Tests/FindTIFF/Test/CMakeLists.txt b/Tests/FindTIFF/Test/CMakeLists.txt
index 85453ed..e235db3 100644
--- a/Tests/FindTIFF/Test/CMakeLists.txt
+++ b/Tests/FindTIFF/Test/CMakeLists.txt
@@ -1,14 +1,23 @@
 cmake_minimum_required(VERSION 3.1)
-project(TestFindTIFF C)
+project(TestFindTIFF)
 include(CTest)
 
-find_package(TIFF REQUIRED)
+find_package(TIFF REQUIRED COMPONENTS CXX)
 
 add_executable(test_tiff_tgt main.c)
 target_link_libraries(test_tiff_tgt TIFF::TIFF)
 add_test(NAME test_tiff_tgt COMMAND test_tiff_tgt)
 
+add_executable(test_tiffxx_tgt main.cxx)
+target_link_libraries(test_tiffxx_tgt TIFF::CXX)
+add_test(NAME test_tiffxx_tgt COMMAND test_tiffxx_tgt)
+
 add_executable(test_tiff_var main.c)
 target_include_directories(test_tiff_var PRIVATE ${TIFF_INCLUDE_DIRS})
 target_link_libraries(test_tiff_var PRIVATE ${TIFF_LIBRARIES})
 add_test(NAME test_tiff_var COMMAND test_tiff_var)
+
+add_executable(test_tiffxx_var main.cxx)
+target_include_directories(test_tiffxx_var PRIVATE ${TIFF_INCLUDE_DIRS})
+target_link_libraries(test_tiffxx_var PRIVATE ${TIFF_LIBRARIES})
+add_test(NAME test_tiffxx_var COMMAND test_tiffxx_var)
diff --git a/Tests/FindTIFF/Test/main.cxx b/Tests/FindTIFF/Test/main.cxx
new file mode 100644
index 0000000..f80a31f
--- /dev/null
+++ b/Tests/FindTIFF/Test/main.cxx
@@ -0,0 +1,16 @@
+#include <fstream>
+
+#include <assert.h>
+#include <tiffio.hxx>
+
+int main()
+{
+  /* Without any TIFF file to open, test that the call fails as
+     expected.  This tests that linking worked. */
+  TIFF* tiff = TIFFOpen("invalid.tiff", "r");
+  assert(!tiff);
+
+  std::ifstream s;
+  TIFF* tiffxx = TIFFStreamOpen("invalid.tiff", &s);
+  return 0;
+}
diff --git a/Tests/FindVulkan/Test/CMakeLists.txt b/Tests/FindVulkan/Test/CMakeLists.txt
index 0b13d53..9d36a0d 100644
--- a/Tests/FindVulkan/Test/CMakeLists.txt
+++ b/Tests/FindVulkan/Test/CMakeLists.txt
@@ -13,3 +13,12 @@
 target_include_directories(test_var PRIVATE ${Vulkan_INCLUDE_DIRS})
 target_link_libraries(test_var PRIVATE ${Vulkan_LIBRARIES})
 add_test(NAME test_var COMMAND test_var)
+
+if(Vulkan_GLSLC_EXECUTABLE)
+  add_test(NAME test_glslc
+    COMMAND ${CMAKE_COMMAND}
+    "-DVULKAN_GLSLC_EXECUTABLE=${Vulkan_GLSLC_EXECUTABLE}"
+    "-DVULKAN_GLSLC_EXECUTABLE_TARGET=$<TARGET_FILE:Vulkan::glslc>"
+    -P "${CMAKE_CURRENT_LIST_DIR}/Run-glslc.cmake"
+    )
+endif()
diff --git a/Tests/FindVulkan/Test/Run-glslc.cmake b/Tests/FindVulkan/Test/Run-glslc.cmake
new file mode 100644
index 0000000..086eb9d
--- /dev/null
+++ b/Tests/FindVulkan/Test/Run-glslc.cmake
@@ -0,0 +1,20 @@
+cmake_minimum_required(VERSION 3.12)
+
+function(run_glslc exe exe_display)
+  execute_process(COMMAND ${exe} --help
+    OUTPUT_VARIABLE output
+    OUTPUT_STRIP_TRAILING_WHITESPACE
+    RESULT_VARIABLE result
+    )
+
+  if(NOT result EQUAL 0)
+    message(SEND_ERROR "Result of ${exe_display} --help is ${result}, should be 0")
+  endif()
+
+  if(NOT output MATCHES "^glslc - Compile shaders into SPIR-V")
+    message(SEND_ERROR "Output of ${exe_display} --help is \"${output}\", should begin with \"glslc - Compile shaders into SPIR-V\"")
+  endif()
+endfunction()
+
+run_glslc("${VULKAN_GLSLC_EXECUTABLE}" "\${VULKAN_GLSLC_EXECUTABLE}")
+run_glslc("${VULKAN_GLSLC_EXECUTABLE_TARGET}" "Vulkan::glslc")
diff --git a/Tests/FindVulkan/Test/main.c b/Tests/FindVulkan/Test/main.c
index b29c9ec..1bff651 100644
--- a/Tests/FindVulkan/Test/main.c
+++ b/Tests/FindVulkan/Test/main.c
@@ -2,10 +2,10 @@
 
 int main()
 {
-  VkInstanceCreateInfo instanceCreateInfo = {};
+  VkInstanceCreateInfo instanceCreateInfo = { 0 };
   instanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
 
-  VkApplicationInfo applicationInfo = {};
+  VkApplicationInfo applicationInfo = { 0 };
   applicationInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
   applicationInfo.apiVersion = VK_API_VERSION_1_0;
   applicationInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
diff --git a/Tests/FindX11/Test/CMakeLists.txt b/Tests/FindX11/Test/CMakeLists.txt
index b2adfb2..7325b32 100644
--- a/Tests/FindX11/Test/CMakeLists.txt
+++ b/Tests/FindX11/Test/CMakeLists.txt
@@ -29,6 +29,7 @@
 set(X11_X11_FOUND ${X11_FOUND})
 test_x11_component(x11_components X11)
 test_x11_component(x11_components Xau)
+test_x11_component(x11_components Xaw)
 test_x11_component(x11_components xcb)
 test_x11_component(x11_components X11_xcb)
 test_x11_component(x11_components xcb_icccm)
@@ -67,6 +68,7 @@
 # Not included in X11_LIBRARIES.
 foreach(lib
     Xau
+    Xaw
     xcb
     X11_xcb
     xcb_icccm
diff --git a/Tests/FindX11/Test/main.c b/Tests/FindX11/Test/main.c
index c8144e0..f8c723c 100644
--- a/Tests/FindX11/Test/main.c
+++ b/Tests/FindX11/Test/main.c
@@ -308,6 +308,24 @@
 }
 #endif
 
+#ifdef HAVE_X11_Xaw
+#  include <X11/Intrinsic.h>
+#  include <X11/Xaw/Box.h>
+
+static void test_Xaw(void)
+{
+  XrmOptionDescRec opt_table[] = { { NULL } };
+
+  Widget toplevel;
+  toplevel =
+    XtInitialize("test", "test", opt_table, XtNumber(opt_table), NULL, NULL);
+  Widget box =
+    XtCreateManagedWidget("testbox", boxWidgetClass, toplevel, NULL, 0);
+  return;
+}
+
+#endif
+
 #include <stddef.h>
 
 int main(int argc, char* argv[])
@@ -392,6 +410,9 @@
 #ifdef HAVE_X11_Xv
     test_Xv,
 #endif
+#ifdef HAVE_X11_Xaw
+    test_Xaw,
+#endif
     NULL,
   };
 
diff --git a/Tests/FortranOnly/CMakeLists.txt b/Tests/FortranOnly/CMakeLists.txt
index d24df2d..637f581 100644
--- a/Tests/FortranOnly/CMakeLists.txt
+++ b/Tests/FortranOnly/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required (VERSION 2.8)
+cmake_minimum_required(VERSION 2.8.12)
 project(FortranOnly Fortran)
 message("CTEST_FULL_OUTPUT ")
 
diff --git a/Tests/GeneratorExpression/CMakeLists.txt b/Tests/GeneratorExpression/CMakeLists.txt
index 9d51342..ebbe288 100644
--- a/Tests/GeneratorExpression/CMakeLists.txt
+++ b/Tests/GeneratorExpression/CMakeLists.txt
@@ -40,9 +40,9 @@
     -Dtest_and_0_invalidcontent=$<AND:0,invalidcontent>
     -Dtest_config_0=$<CONFIG:$<CONFIGURATION>x>
     -Dtest_config_1=$<CONFIG:$<CONFIGURATION>>
-    -Dtest_config_debug=$<CONFIG:Debug>$<CONFIG:DEBUG>$<CONFIG:DeBuG>
-    -Dtest_config_release=$<CONFIG:Release>$<CONFIG:RELEASE>$<CONFIG:ReLeAsE>
-    -Dtest_config_relwithdebinfo=$<CONFIG:RelWithDebInfo>$<CONFIG:RELWITHDEBINFO>$<CONFIG:relwithdebinfo>
+    -Dtest_config_debug=$<CONFIG:Debug,DEBUG,DeBuG>
+    -Dtest_config_release=$<CONFIG:Release>$<CONFIG:RELEASE,ReLeAsE>
+    -Dtest_config_relwithdebinfo=$<CONFIG:RelWithDebInfo,RELWITHDEBINFO>$<CONFIG:relwithdebinfo>
     -Dtest_config_minsizerel=$<CONFIG:MinSizeRel>$<CONFIG:MINSIZEREL>$<CONFIG:minsizerel>
     -Dtest_not_0=$<NOT:0>
     -Dtest_not_1=$<NOT:1>
@@ -180,9 +180,7 @@
 set_property(TARGET imported3 APPEND PROPERTY
   INTERFACE_INCLUDE_DIRECTORIES $<$<CONFIG:DEBUG>:$<TARGET_PROPERTY:imported1,INTERFACE_INCLUDE_DIRECTORIES>>)
 set_property(TARGET imported3 APPEND PROPERTY
-  INTERFACE_INCLUDE_DIRECTORIES $<$<CONFIG:RELEASE>:$<TARGET_PROPERTY:imported2,INTERFACE_INCLUDE_DIRECTORIES>>)
-set_property(TARGET imported3 APPEND PROPERTY
-  INTERFACE_INCLUDE_DIRECTORIES $<$<CONFIG:RELWITHDEBINFO>:$<TARGET_PROPERTY:imported2,INTERFACE_INCLUDE_DIRECTORIES>>)
+  INTERFACE_INCLUDE_DIRECTORIES $<$<CONFIG:RELEASE,RELWITHDEBINFO>:$<TARGET_PROPERTY:imported2,INTERFACE_INCLUDE_DIRECTORIES>>)
 set_property(TARGET imported3 APPEND PROPERTY
   INTERFACE_INCLUDE_DIRECTORIES $<$<CONFIG:MINSIZEREL>:$<TARGET_PROPERTY:imported2,INTERFACE_INCLUDE_DIRECTORIES>>)
 
diff --git a/Tests/GeneratorExpression/check-part3.cmake b/Tests/GeneratorExpression/check-part3.cmake
index 4fb7308..5571c3d 100644
--- a/Tests/GeneratorExpression/check-part3.cmake
+++ b/Tests/GeneratorExpression/check-part3.cmake
@@ -9,11 +9,11 @@
 check(test_version_equal_2 "1")
 
 if(config AND NOT config STREQUAL NoConfig)
-  if(NOT "${test_imported_includes}" MATCHES "^;*/imported[12]/include/with space;*$")
+  if(NOT "${test_imported_includes}" MATCHES "^[^;]*/imported[12]/include/with space$")
     message(SEND_ERROR "test_imported_includes is not correct: ${test_imported_includes}")
   endif()
 else()
-  if(NOT "${test_imported_includes}" MATCHES "^;;;$")
+  if(NOT "${test_imported_includes}" MATCHES "^$")
     message(SEND_ERROR "test_imported_includes is not an empty list: ${test_imported_includes}")
   endif()
 endif()
diff --git a/Tests/GhsMulti/GhsMultiSrcGroups/standard.h b/Tests/GhsMulti/GhsMultiSrcGroups/standard.h
index 2773a55..66522d5 100644
--- a/Tests/GhsMulti/GhsMultiSrcGroups/standard.h
+++ b/Tests/GhsMulti/GhsMultiSrcGroups/standard.h
@@ -1 +1 @@
-#define somthing
+#define something
diff --git a/Tests/GhsMulti/GhsMultiSrcGroups/test3.h b/Tests/GhsMulti/GhsMultiSrcGroups/test3.h
index 2773a55..66522d5 100644
--- a/Tests/GhsMulti/GhsMultiSrcGroups/test3.h
+++ b/Tests/GhsMulti/GhsMultiSrcGroups/test3.h
@@ -1 +1 @@
-#define somthing
+#define something
diff --git a/Tests/InterfaceLibrary/CMakeLists.txt b/Tests/InterfaceLibrary/CMakeLists.txt
index 311ca2a..ec0a604 100644
--- a/Tests/InterfaceLibrary/CMakeLists.txt
+++ b/Tests/InterfaceLibrary/CMakeLists.txt
@@ -44,6 +44,7 @@
 target_link_libraries(InterfaceLibrary
   iface_nodepends
   headeriface
+  iface_genheader
   subiface
   intermediate
 
diff --git a/Tests/InterfaceLibrary/definetestexe.cpp b/Tests/InterfaceLibrary/definetestexe.cpp
index 9156426..6c53840 100644
--- a/Tests/InterfaceLibrary/definetestexe.cpp
+++ b/Tests/InterfaceLibrary/definetestexe.cpp
@@ -15,6 +15,12 @@
 #  error Expected IFACE_HEADER_BUILDDIR
 #endif
 
+#include "iface_genheader.h"
+
+#ifndef IFACE_GENHEADER
+#  error Expected IFACE_GENHEADER
+#endif
+
 extern int obj();
 extern int sub();
 extern int item();
diff --git a/Tests/InterfaceLibrary/headerdir/CMakeLists.txt b/Tests/InterfaceLibrary/headerdir/CMakeLists.txt
index 826a9ed..ae030d7 100644
--- a/Tests/InterfaceLibrary/headerdir/CMakeLists.txt
+++ b/Tests/InterfaceLibrary/headerdir/CMakeLists.txt
@@ -11,3 +11,12 @@
   VERBATIM
   )
 add_dependencies(headeriface headeriface_gen)
+
+add_custom_command(OUTPUT iface_genheader.h
+  COMMAND ${CMAKE_COMMAND} -E copy
+    ${CMAKE_CURRENT_SOURCE_DIR}/iface_genheader.h.in
+    ${CMAKE_CURRENT_BINARY_DIR}/iface_genheader.h
+  DEPENDS
+    ${CMAKE_CURRENT_SOURCE_DIR}/iface_genheader.h.in
+  VERBATIM)
+add_library(iface_genheader INTERFACE iface_genheader.h)
diff --git a/Tests/InterfaceLibrary/headerdir/iface_genheader.h.in b/Tests/InterfaceLibrary/headerdir/iface_genheader.h.in
new file mode 100644
index 0000000..0a21b62
--- /dev/null
+++ b/Tests/InterfaceLibrary/headerdir/iface_genheader.h.in
@@ -0,0 +1 @@
+#define IFACE_GENHEADER
diff --git a/Tests/LoadCommand/CMakeCommands/cmTestCommand.c b/Tests/LoadCommand/CMakeCommands/cmTestCommand.c
index 99f0de9..af7b092 100644
--- a/Tests/LoadCommand/CMakeCommands/cmTestCommand.c
+++ b/Tests/LoadCommand/CMakeCommands/cmTestCommand.c
@@ -91,7 +91,7 @@
 
   source_file = info->CAPI->CreateNewSourceFile(mf);
   cstr = info->CAPI->SourceFileGetSourceName(source_file);
-  sprintf(buffer, "Shold be empty (source file name): [%s]", cstr);
+  sprintf(buffer, "Should be empty (source file name): [%s]", cstr);
   info->CAPI->DisplaySatus(mf, buffer);
   cstr = info->CAPI->SourceFileGetFullPath(source_file);
   sprintf(buffer, "Should be empty (source file full path): [%s]", cstr);
diff --git a/Tests/LoadCommandOneConfig/CMakeCommands/cmTestCommand.c b/Tests/LoadCommandOneConfig/CMakeCommands/cmTestCommand.c
index 99f0de9..af7b092 100644
--- a/Tests/LoadCommandOneConfig/CMakeCommands/cmTestCommand.c
+++ b/Tests/LoadCommandOneConfig/CMakeCommands/cmTestCommand.c
@@ -91,7 +91,7 @@
 
   source_file = info->CAPI->CreateNewSourceFile(mf);
   cstr = info->CAPI->SourceFileGetSourceName(source_file);
-  sprintf(buffer, "Shold be empty (source file name): [%s]", cstr);
+  sprintf(buffer, "Should be empty (source file name): [%s]", cstr);
   info->CAPI->DisplaySatus(mf, buffer);
   cstr = info->CAPI->SourceFileGetFullPath(source_file);
   sprintf(buffer, "Should be empty (source file full path): [%s]", cstr);
diff --git a/Tests/Module/CheckTypeSize/CMakeLists.txt b/Tests/Module/CheckTypeSize/CMakeLists.txt
index 16989fe2..102cf0c 100644
--- a/Tests/Module/CheckTypeSize/CMakeLists.txt
+++ b/Tests/Module/CheckTypeSize/CMakeLists.txt
@@ -21,6 +21,8 @@
 
 # Check CXX types
 check_type_size(bool        SIZEOF_BOOL LANGUAGE CXX)
+check_type_size(uint8_t     SIZEOF_UINT8_T LANGUAGE CXX)
+check_type_size(std::uint8_t SIZEOF_STD_UINT8_T LANGUAGE CXX)
 
 set(CMAKE_EXTRA_INCLUDE_FILES someclass.hxx)
 check_type_size("((ns::someclass*)0)->someint" SIZEOF_NS_CLASSMEMBER_INT LANGUAGE CXX)
diff --git a/Tests/Module/CheckTypeSize/CheckTypeSize.cxx b/Tests/Module/CheckTypeSize/CheckTypeSize.cxx
index 15dc890..45cd393 100644
--- a/Tests/Module/CheckTypeSize/CheckTypeSize.cxx
+++ b/Tests/Module/CheckTypeSize/CheckTypeSize.cxx
@@ -11,6 +11,12 @@
 #ifdef HAVE_STDDEF_H
 #  include <stddef.h>
 #endif
+#ifdef HAVE_CSTDINT
+#  include <cstdint>
+#endif
+#ifdef HAVE_CSTDDEF
+#  include <cstddef>
+#endif
 
 #include <stdio.h>
 
@@ -122,6 +128,26 @@
   NODEF(SIZEOF_SSIZE_T);
 #endif
 
+/* uint8_t */
+#if defined(SIZEOF_UINT8_T)
+  CHECK(uint8_t, SIZEOF_UINT8_T);
+#  if !defined(HAVE_SIZEOF_UINT8_T)
+  NODEF(HAVE_SIZEOF_UINT8_T);
+#  endif
+#elif defined(HAVE_SIZEOF_UINT8_T)
+  NODEF(SIZEOF_UINT8_T);
+#endif
+
+/* std::uint8_t */
+#if defined(SIZEOF_STD_UINT8_T)
+  CHECK(std::uint8_t, SIZEOF_STD_UINT8_T);
+#  if !defined(HAVE_SIZEOF_STD_UINT8_T)
+  NODEF(HAVE_SIZEOF_STD_UINT8_T);
+#  endif
+#elif defined(HAVE_SIZEOF_STD_UINT8_T)
+  NODEF(SIZEOF_STD_UINT8_T);
+#endif
+
 /* ns::someclass::someint */
 #if defined(SIZEOF_NS_CLASSMEMBER_INT)
   CHECK(y.someint, SIZEOF_NS_CLASSMEMBER_INT);
diff --git a/Tests/Module/CheckTypeSize/config.hxx.in b/Tests/Module/CheckTypeSize/config.hxx.in
index 8c66ade..9a80689 100644
--- a/Tests/Module/CheckTypeSize/config.hxx.in
+++ b/Tests/Module/CheckTypeSize/config.hxx.in
@@ -1,11 +1,21 @@
 #cmakedefine HAVE_SYS_TYPES_H
 #cmakedefine HAVE_STDINT_H
 #cmakedefine HAVE_STDDEF_H
+#cmakedefine HAVE_CSTDINT
+#cmakedefine HAVE_CSTDDEF
 
 /* bool */
 #cmakedefine HAVE_SIZEOF_BOOL
 @SIZEOF_BOOL_CODE@
 
+/* uint8_t */
+#cmakedefine HAVE_SIZEOF_UINT8_T
+@SIZEOF_UINT8_T_CODE@
+
+/* std::uint8_t */
+#cmakedefine HAVE_SIZEOF_STD_UINT8_T
+@SIZEOF_STD_UINT8_T_CODE@
+
 /* struct ns::somestruct::someint */
 #cmakedefine HAVE_SIZEOF_NS_STRUCTMEMBER_INT
 @SIZEOF_NS_STRUCTMEMBER_INT_CODE@
diff --git a/Tests/RunCMake/Android/RunCMakeTest.cmake b/Tests/RunCMake/Android/RunCMakeTest.cmake
index 45798ce..81dd090 100644
--- a/Tests/RunCMake/Android/RunCMakeTest.cmake
+++ b/Tests/RunCMake/Android/RunCMakeTest.cmake
@@ -18,15 +18,33 @@
   file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
   file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
   run_cmake(${case})
-  run_cmake_command(${case}-build ${CMAKE_COMMAND} --build .)
+  set(configs ".")
+  if(RunCMake_GENERATOR_IS_MULTI_CONFIG)
+    set(configs Release Debug)
+  endif()
+  foreach(config IN LISTS configs)
+    set(build_suffix)
+    set(config_arg)
+    if(RunCMake_GENERATOR_IS_MULTI_CONFIG)
+      set(build_suffix "-${config}")
+      set(config_arg --config "${config}")
+    endif()
+    run_cmake_command(${case}-build${build_suffix} ${CMAKE_COMMAND} --build . ${config_arg})
+  endforeach()
 endfunction()
 
+set(RunCMake_GENERATOR_PLATFORM_OLD "${RunCMake_GENERATOR_PLATFORM}")
+
+if(RunCMake_GENERATOR MATCHES "Visual Studio")
+  set(RunCMake_GENERATOR_PLATFORM "ARM")
+endif()
 set(RunCMake_TEST_OPTIONS
   -DCMAKE_SYSTEM_NAME=Android
   -DCMAKE_SYSROOT=${CMAKE_CURRENT_SOURCE_DIR}
   )
 run_cmake(BadSYSROOT)
 unset(RunCMake_TEST_OPTIONS)
+set(RunCMake_GENERATOR_PLATFORM "${RunCMake_GENERATOR_PLATFORM_OLD}")
 
 foreach(ndk IN LISTS TEST_ANDROID_NDK)
   # Load available toolchain versions and abis.
@@ -70,6 +88,9 @@
   if(_versions MATCHES "clang")
     set(_versions "clang" ${_versions})
   endif()
+  if(RunCMake_GENERATOR MATCHES "Visual Studio")
+    set(_versions "clang")
+  endif()
   list(REMOVE_DUPLICATES _versions)
   list(SORT _versions)
   set(_versions ";${_versions}")
@@ -77,44 +98,58 @@
     list(REMOVE_DUPLICATES _abis_${vers})
   endforeach()
 
+  set(ndk_arg -DCMAKE_ANDROID_NDK=${ndk})
+  if(RunCMake_GENERATOR MATCHES "Visual Studio")
+    set(ndk_arg)
+  endif()
+
   # Test failure cases.
   message(STATUS "ndk='${ndk}'")
+  if(RunCMake_GENERATOR MATCHES "Visual Studio")
+    set(RunCMake_GENERATOR_PLATFORM "ARM")
+  endif()
   set(RunCMake_TEST_OPTIONS
     -DCMAKE_SYSTEM_NAME=Android
-    -DCMAKE_ANDROID_NDK=${ndk}
+    ${ndk_arg}
     -DCMAKE_ANDROID_ARCH_ABI=badabi
     )
   run_cmake(ndk-badabi)
+  if(RunCMake_GENERATOR MATCHES "Visual Studio")
+    set(RunCMake_GENERATOR_PLATFORM "x86")
+  endif()
   set(RunCMake_TEST_OPTIONS
     -DCMAKE_SYSTEM_NAME=Android
-    -DCMAKE_ANDROID_NDK=${ndk}
+    ${ndk_arg}
     -DCMAKE_ANDROID_ARCH_ABI=x86
     -DCMAKE_ANDROID_ARM_MODE=0
     )
   run_cmake(ndk-badarm)
+  if(RunCMake_GENERATOR MATCHES "Visual Studio")
+    set(RunCMake_GENERATOR_PLATFORM "ARM")
+  endif()
   if("armeabi" IN_LIST _abis_)
     set(RunCMake_TEST_OPTIONS
       -DCMAKE_SYSTEM_NAME=Android
-      -DCMAKE_ANDROID_NDK=${ndk}
+      ${ndk_arg}
       -DCMAKE_ANDROID_ARM_NEON=0
       )
     run_cmake(ndk-badneon)
   endif()
   set(RunCMake_TEST_OPTIONS
     -DCMAKE_SYSTEM_NAME=Android
-    -DCMAKE_ANDROID_NDK=${ndk}
+    ${ndk_arg}
     -DCMAKE_ANDROID_NDK_TOOLCHAIN_VERSION=badver
     )
   run_cmake(ndk-badver)
   set(RunCMake_TEST_OPTIONS
     -DCMAKE_SYSTEM_NAME=Android
-    -DCMAKE_ANDROID_NDK=${ndk}
+    ${ndk_arg}
     -DCMAKE_ANDROID_NDK_TOOLCHAIN_VERSION=1.0
     )
   run_cmake(ndk-badvernum)
   set(RunCMake_TEST_OPTIONS
     -DCMAKE_SYSTEM_NAME=Android
-    -DCMAKE_ANDROID_NDK=${ndk}
+    ${ndk_arg}
     -DCMAKE_ANDROID_STL_TYPE=badstl
     )
   run_cmake(ndk-badstl)
@@ -131,6 +166,7 @@
     run_cmake(ndk-sysroot-armeabi)
     unset(RunCMake_TEST_OPTIONS)
   endif()
+  set(RunCMake_GENERATOR_PLATFORM "${RunCMake_GENERATOR_PLATFORM_OLD}")
 
   # Find available STLs.
   set(stl_types
@@ -157,23 +193,41 @@
     armeabi-v6
     armeabi-v7a
     arm64-v8a
-    mips
-    mips64
     x86
     x86_64
     )
+  if(NOT RunCMake_GENERATOR MATCHES "Visual Studio")
+    list(APPEND abi_names mips mips64)
+  endif()
+  set(abi_to_arch_armeabi ARM)
+  set(abi_to_arch_armeabi-v6 ARM)
+  set(abi_to_arch_armeabi-v7a ARM)
+  set(abi_to_arch_arm64-v8a ARM64)
+  set(abi_to_arch_x86 x86)
+  set(abi_to_arch_x86_64 x64)
 
   # Test all combinations.
   foreach(vers IN LISTS _versions)
     foreach(stl IN LISTS stl_types)
-      foreach(config Release Debug)
+      set(configs Release Debug)
+      set(foreach_list "${configs}")
+      if(RunCMake_GENERATOR_IS_MULTI_CONFIG)
+        set(foreach_list ".")
+      endif()
+      foreach(config IN LISTS foreach_list)
         # Test this combination for all available abis.
-        message(STATUS "ndk='${ndk}' vers='${vers}' stl='${stl}' config='${config}'")
+        set(config_status " config='${config}'")
+        set(build_type_arg "-DCMAKE_BUILD_TYPE=${config}")
+        if(RunCMake_GENERATOR_IS_MULTI_CONFIG)
+          set(config_status)
+          string(REPLACE ";" "\\\\;" build_type_arg "-DCMAKE_CONFIGURATION_TYPES=${configs}")
+        endif()
+        message(STATUS "ndk='${ndk}' vers='${vers}' stl='${stl}'${config_status}")
         set(RunCMake_TEST_OPTIONS
-          -DCMAKE_ANDROID_NDK=${ndk}
+          ${ndk_arg}
           -DCMAKE_ANDROID_NDK_TOOLCHAIN_VERSION=${vers}
           -DCMAKE_ANDROID_STL_TYPE=${stl}
-          -DCMAKE_BUILD_TYPE=${config}
+          "${build_type_arg}"
           )
         foreach(abi IN LISTS abi_names)
           # Skip ABIs not supported by this compiler.
@@ -182,6 +236,9 @@
           endif()
 
           # Run the tests for this combination.
+          if(RunCMake_GENERATOR MATCHES "Visual Studio")
+            set(RunCMake_GENERATOR_PLATFORM "${abi_to_arch_${abi}}")
+          endif()
           if("${abi}" STREQUAL "armeabi")
             run_Android(ndk-armeabi-thumb) # default: -DCMAKE_ANDROID_ARCH_ABI=armeabi -DCMAKE_ANDROID_ARM_MODE=0
             run_Android(ndk-armeabi-arm -DCMAKE_ANDROID_ARM_MODE=1) # default: -DCMAKE_ANDROID_ARCH_ABI=armeabi
@@ -191,6 +248,7 @@
               run_Android(ndk-${abi}-neon -DCMAKE_ANDROID_ARCH_ABI=${abi} -DCMAKE_ANDROID_ARM_NEON=1)
             endif()
           endif()
+          set(RunCMake_GENERATOR_PLATFORM "${RunCMake_GENERATOR_PLATFORM_OLD}")
         endforeach()
         unset(RunCMake_TEST_OPTIONS)
       endforeach()
diff --git a/Tests/RunCMake/Android/common.cmake b/Tests/RunCMake/Android/common.cmake
index d96ab86..32412aa 100644
--- a/Tests/RunCMake/Android/common.cmake
+++ b/Tests/RunCMake/Android/common.cmake
@@ -96,7 +96,7 @@
 add_executable(android_cxx android.cxx)
 add_library(android_cxx_lib SHARED android_lib.cxx)
 
-set(objdump "${CMAKE_CXX_ANDROID_TOOLCHAIN_PREFIX}objdump")
+set(objdump "${CMAKE_CXX_ANDROID_TOOLCHAIN_PREFIX}objdump${CMAKE_CXX_ANDROID_TOOLCHAIN_SUFFIX}")
 if(NOT EXISTS "${objdump}")
   message(FATAL_ERROR "Expected tool missing:\n  ${objdump}")
 endif()
diff --git a/Tests/RunCMake/Android/ndk-arm64-v8a-stderr.txt b/Tests/RunCMake/Android/ndk-arm64-v8a-stderr.txt
new file mode 100644
index 0000000..a3b3634
--- /dev/null
+++ b/Tests/RunCMake/Android/ndk-arm64-v8a-stderr.txt
@@ -0,0 +1,7 @@
+^(CMake Warning:
+  You are using Visual Studio tools for Android, which does not support
+  standalone executables\.  However, the following executable targets do not
+  have the ANDROID_GUI property set, and thus will not be built as expected\.
+  They will be built as shared libraries with executable filenames:
+
+    android_c, android_cxx, android_sysinc_c, android_sysinc_cxx)?$
diff --git a/Tests/RunCMake/Android/ndk-armeabi-arm-stderr.txt b/Tests/RunCMake/Android/ndk-armeabi-arm-stderr.txt
new file mode 100644
index 0000000..a3b3634
--- /dev/null
+++ b/Tests/RunCMake/Android/ndk-armeabi-arm-stderr.txt
@@ -0,0 +1,7 @@
+^(CMake Warning:
+  You are using Visual Studio tools for Android, which does not support
+  standalone executables\.  However, the following executable targets do not
+  have the ANDROID_GUI property set, and thus will not be built as expected\.
+  They will be built as shared libraries with executable filenames:
+
+    android_c, android_cxx, android_sysinc_c, android_sysinc_cxx)?$
diff --git a/Tests/RunCMake/Android/ndk-armeabi-thumb-stderr.txt b/Tests/RunCMake/Android/ndk-armeabi-thumb-stderr.txt
new file mode 100644
index 0000000..a3b3634
--- /dev/null
+++ b/Tests/RunCMake/Android/ndk-armeabi-thumb-stderr.txt
@@ -0,0 +1,7 @@
+^(CMake Warning:
+  You are using Visual Studio tools for Android, which does not support
+  standalone executables\.  However, the following executable targets do not
+  have the ANDROID_GUI property set, and thus will not be built as expected\.
+  They will be built as shared libraries with executable filenames:
+
+    android_c, android_cxx, android_sysinc_c, android_sysinc_cxx)?$
diff --git a/Tests/RunCMake/Android/ndk-armeabi-v7a-neon-stderr.txt b/Tests/RunCMake/Android/ndk-armeabi-v7a-neon-stderr.txt
new file mode 100644
index 0000000..a3b3634
--- /dev/null
+++ b/Tests/RunCMake/Android/ndk-armeabi-v7a-neon-stderr.txt
@@ -0,0 +1,7 @@
+^(CMake Warning:
+  You are using Visual Studio tools for Android, which does not support
+  standalone executables\.  However, the following executable targets do not
+  have the ANDROID_GUI property set, and thus will not be built as expected\.
+  They will be built as shared libraries with executable filenames:
+
+    android_c, android_cxx, android_sysinc_c, android_sysinc_cxx)?$
diff --git a/Tests/RunCMake/Android/ndk-armeabi-v7a-stderr.txt b/Tests/RunCMake/Android/ndk-armeabi-v7a-stderr.txt
new file mode 100644
index 0000000..a3b3634
--- /dev/null
+++ b/Tests/RunCMake/Android/ndk-armeabi-v7a-stderr.txt
@@ -0,0 +1,7 @@
+^(CMake Warning:
+  You are using Visual Studio tools for Android, which does not support
+  standalone executables\.  However, the following executable targets do not
+  have the ANDROID_GUI property set, and thus will not be built as expected\.
+  They will be built as shared libraries with executable filenames:
+
+    android_c, android_cxx, android_sysinc_c, android_sysinc_cxx)?$
diff --git a/Tests/RunCMake/Android/ndk-x86-stderr.txt b/Tests/RunCMake/Android/ndk-x86-stderr.txt
new file mode 100644
index 0000000..a3b3634
--- /dev/null
+++ b/Tests/RunCMake/Android/ndk-x86-stderr.txt
@@ -0,0 +1,7 @@
+^(CMake Warning:
+  You are using Visual Studio tools for Android, which does not support
+  standalone executables\.  However, the following executable targets do not
+  have the ANDROID_GUI property set, and thus will not be built as expected\.
+  They will be built as shared libraries with executable filenames:
+
+    android_c, android_cxx, android_sysinc_c, android_sysinc_cxx)?$
diff --git a/Tests/RunCMake/Android/ndk-x86_64-stderr.txt b/Tests/RunCMake/Android/ndk-x86_64-stderr.txt
new file mode 100644
index 0000000..a3b3634
--- /dev/null
+++ b/Tests/RunCMake/Android/ndk-x86_64-stderr.txt
@@ -0,0 +1,7 @@
+^(CMake Warning:
+  You are using Visual Studio tools for Android, which does not support
+  standalone executables\.  However, the following executable targets do not
+  have the ANDROID_GUI property set, and thus will not be built as expected\.
+  They will be built as shared libraries with executable filenames:
+
+    android_c, android_cxx, android_sysinc_c, android_sysinc_cxx)?$
diff --git a/Tests/RunCMake/BundleUtilities/ExecutableScripts.cmake b/Tests/RunCMake/BundleUtilities/ExecutableScripts.cmake
new file mode 100644
index 0000000..78a9b66
--- /dev/null
+++ b/Tests/RunCMake/BundleUtilities/ExecutableScripts.cmake
@@ -0,0 +1,18 @@
+include(BundleUtilities)
+
+set(BU_CHMOD_BUNDLE_ITEMS ON)
+
+function(check_script script)
+  fixup_bundle_item(${script} ${script} "" "")
+endfunction()
+
+# Should not throw any errors
+# Shell script
+set(script_sh_EMBEDDED_ITEM ${CMAKE_CURRENT_LIST_DIR}/test.app/script.sh)
+check_script(${CMAKE_CURRENT_LIST_DIR}/test.app/script.sh)
+# Batch script
+set(script_bat_EMBEDDED_ITEM ${CMAKE_CURRENT_LIST_DIR}/test.app/script.bat)
+check_script(${CMAKE_CURRENT_LIST_DIR}/test.app/script.bat)
+# Shell script without extension
+set(script_EMBEDDED_ITEM ${CMAKE_CURRENT_LIST_DIR}/test.app/script)
+check_script(${CMAKE_CURRENT_LIST_DIR}/test.app/script)
diff --git a/Tests/RunCMake/BundleUtilities/RunCMakeTest.cmake b/Tests/RunCMake/BundleUtilities/RunCMakeTest.cmake
index 14aaff1..df28102 100644
--- a/Tests/RunCMake/BundleUtilities/RunCMakeTest.cmake
+++ b/Tests/RunCMake/BundleUtilities/RunCMakeTest.cmake
@@ -9,3 +9,4 @@
 run_cmake_command(CMP0080-COMMAND-OLD ${CMAKE_COMMAND} -DCMP0080_VALUE:STRING=OLD -P ${RunCMake_SOURCE_DIR}/CMP0080-COMMAND.cmake)
 run_cmake_command(CMP0080-COMMAND-NEW ${CMAKE_COMMAND} -DCMP0080_VALUE:STRING=NEW -P ${RunCMake_SOURCE_DIR}/CMP0080-COMMAND.cmake)
 run_cmake_command(CMP0080-COMMAND-WARN ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/CMP0080-COMMAND.cmake)
+run_cmake_command(ExecutableScripts ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/ExecutableScripts.cmake)
diff --git a/Tests/RunCMake/BundleUtilities/test.app/script b/Tests/RunCMake/BundleUtilities/test.app/script
new file mode 100755
index 0000000..23bf47c
--- /dev/null
+++ b/Tests/RunCMake/BundleUtilities/test.app/script
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+echo "Hello World"
diff --git a/Tests/RunCMake/BundleUtilities/test.app/script.bat b/Tests/RunCMake/BundleUtilities/test.app/script.bat
new file mode 100755
index 0000000..dbb0ec2
--- /dev/null
+++ b/Tests/RunCMake/BundleUtilities/test.app/script.bat
@@ -0,0 +1,3 @@
+@echo off
+
+echo "Hello world"
diff --git a/Tests/RunCMake/BundleUtilities/test.app/script.sh b/Tests/RunCMake/BundleUtilities/test.app/script.sh
new file mode 100755
index 0000000..23bf47c
--- /dev/null
+++ b/Tests/RunCMake/BundleUtilities/test.app/script.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+echo "Hello World"
diff --git a/Tests/RunCMake/CMP0019/CMP0019-NEW-stderr.txt b/Tests/RunCMake/CMP0019/CMP0019-NEW-stderr.txt
new file mode 100644
index 0000000..66a58fb
--- /dev/null
+++ b/Tests/RunCMake/CMP0019/CMP0019-NEW-stderr.txt
@@ -0,0 +1,6 @@
+^CMake Deprecation Warning at CMakeLists.txt:1 \(cmake_minimum_required\):
+  Compatibility with CMake < 2.8.12 will be removed from a future version of
+  CMake.
+
+  Update the VERSION argument <min> value or use a ...<max> suffix to tell
+  CMake that the project does not need compatibility with older versions.$
diff --git a/Tests/RunCMake/CMP0019/CMP0019-OLD-stderr.txt b/Tests/RunCMake/CMP0019/CMP0019-OLD-stderr.txt
index 048762d..a446211 100644
--- a/Tests/RunCMake/CMP0019/CMP0019-OLD-stderr.txt
+++ b/Tests/RunCMake/CMP0019/CMP0019-OLD-stderr.txt
@@ -1,4 +1,11 @@
-^CMake Deprecation Warning at CMP0019-OLD.cmake:[0-9]+ \(cmake_policy\):
+^CMake Deprecation Warning at CMakeLists.txt:1 \(cmake_minimum_required\):
+  Compatibility with CMake < 2.8.12 will be removed from a future version of
+  CMake.
+
+  Update the VERSION argument <min> value or use a ...<max> suffix to tell
+  CMake that the project does not need compatibility with older versions.
++
+CMake Deprecation Warning at CMP0019-OLD.cmake:[0-9]+ \(cmake_policy\):
   The OLD behavior for policy CMP0019 will be removed from a future version
   of CMake.
 
diff --git a/Tests/RunCMake/CMP0019/CMP0019-WARN-stderr.txt b/Tests/RunCMake/CMP0019/CMP0019-WARN-stderr.txt
index 1e4b47d..f7b9c0e 100644
--- a/Tests/RunCMake/CMP0019/CMP0019-WARN-stderr.txt
+++ b/Tests/RunCMake/CMP0019/CMP0019-WARN-stderr.txt
@@ -1,3 +1,10 @@
+^CMake Deprecation Warning at CMakeLists.txt:1 \(cmake_minimum_required\):
+  Compatibility with CMake < 2.8.12 will be removed from a future version of
+  CMake.
+
+  Update the VERSION argument <min> value or use a ...<max> suffix to tell
+  CMake that the project does not need compatibility with older versions.
++
 CMake Warning \(dev\) in CMakeLists.txt:
   Policy CMP0019 is not set: Do not re-expand variables in include and link
   information.  Run "cmake --help-policy CMP0019" for policy details.  Use
diff --git a/Tests/RunCMake/CMP0022/CMP0022-NOWARN-exe-stderr.txt b/Tests/RunCMake/CMP0022/CMP0022-NOWARN-exe-stderr.txt
new file mode 100644
index 0000000..66a58fb
--- /dev/null
+++ b/Tests/RunCMake/CMP0022/CMP0022-NOWARN-exe-stderr.txt
@@ -0,0 +1,6 @@
+^CMake Deprecation Warning at CMakeLists.txt:1 \(cmake_minimum_required\):
+  Compatibility with CMake < 2.8.12 will be removed from a future version of
+  CMake.
+
+  Update the VERSION argument <min> value or use a ...<max> suffix to tell
+  CMake that the project does not need compatibility with older versions.$
diff --git a/Tests/RunCMake/CMP0022/CMP0022-NOWARN-shared-stderr.txt b/Tests/RunCMake/CMP0022/CMP0022-NOWARN-shared-stderr.txt
new file mode 100644
index 0000000..66a58fb
--- /dev/null
+++ b/Tests/RunCMake/CMP0022/CMP0022-NOWARN-shared-stderr.txt
@@ -0,0 +1,6 @@
+^CMake Deprecation Warning at CMakeLists.txt:1 \(cmake_minimum_required\):
+  Compatibility with CMake < 2.8.12 will be removed from a future version of
+  CMake.
+
+  Update the VERSION argument <min> value or use a ...<max> suffix to tell
+  CMake that the project does not need compatibility with older versions.$
diff --git a/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static-NEW-stderr.txt b/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static-NEW-stderr.txt
new file mode 100644
index 0000000..66a58fb
--- /dev/null
+++ b/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static-NEW-stderr.txt
@@ -0,0 +1,6 @@
+^CMake Deprecation Warning at CMakeLists.txt:1 \(cmake_minimum_required\):
+  Compatibility with CMake < 2.8.12 will be removed from a future version of
+  CMake.
+
+  Update the VERSION argument <min> value or use a ...<max> suffix to tell
+  CMake that the project does not need compatibility with older versions.$
diff --git a/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static-link_libraries-stderr.txt b/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static-link_libraries-stderr.txt
new file mode 100644
index 0000000..66a58fb
--- /dev/null
+++ b/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static-link_libraries-stderr.txt
@@ -0,0 +1,6 @@
+^CMake Deprecation Warning at CMakeLists.txt:1 \(cmake_minimum_required\):
+  Compatibility with CMake < 2.8.12 will be removed from a future version of
+  CMake.
+
+  Update the VERSION argument <min> value or use a ...<max> suffix to tell
+  CMake that the project does not need compatibility with older versions.$
diff --git a/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static-stderr.txt b/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static-stderr.txt
new file mode 100644
index 0000000..66a58fb
--- /dev/null
+++ b/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static-stderr.txt
@@ -0,0 +1,6 @@
+^CMake Deprecation Warning at CMakeLists.txt:1 \(cmake_minimum_required\):
+  Compatibility with CMake < 2.8.12 will be removed from a future version of
+  CMake.
+
+  Update the VERSION argument <min> value or use a ...<max> suffix to tell
+  CMake that the project does not need compatibility with older versions.$
diff --git a/Tests/RunCMake/CMP0022/CMP0022-WARN-empty-old-stderr.txt b/Tests/RunCMake/CMP0022/CMP0022-WARN-empty-old-stderr.txt
index 6a6a0c7..87404d3 100644
--- a/Tests/RunCMake/CMP0022/CMP0022-WARN-empty-old-stderr.txt
+++ b/Tests/RunCMake/CMP0022/CMP0022-WARN-empty-old-stderr.txt
@@ -1,3 +1,10 @@
+^CMake Deprecation Warning at CMakeLists.txt:1 \(cmake_minimum_required\):
+  Compatibility with CMake < 2.8.12 will be removed from a future version of
+  CMake.
+
+  Update the VERSION argument <min> value or use a ...<max> suffix to tell
+  CMake that the project does not need compatibility with older versions.
++
 CMake Warning \(dev\) in CMakeLists.txt:
   Policy CMP0022 is not set: INTERFACE_LINK_LIBRARIES defines the link
   interface.  Run "cmake --help-policy CMP0022" for policy details.  Use the
diff --git a/Tests/RunCMake/CMP0022/CMP0022-WARN-stderr.txt b/Tests/RunCMake/CMP0022/CMP0022-WARN-stderr.txt
index 2f7dfbf..5d75720 100644
--- a/Tests/RunCMake/CMP0022/CMP0022-WARN-stderr.txt
+++ b/Tests/RunCMake/CMP0022/CMP0022-WARN-stderr.txt
@@ -1,4 +1,11 @@
-^CMake Warning \(dev\) in CMakeLists.txt:
+^CMake Deprecation Warning at CMakeLists.txt:1 \(cmake_minimum_required\):
+  Compatibility with CMake < 2.8.12 will be removed from a future version of
+  CMake.
+
+  Update the VERSION argument <min> value or use a ...<max> suffix to tell
+  CMake that the project does not need compatibility with older versions.
++
+CMake Warning \(dev\) in CMakeLists.txt:
   Policy CMP0022 is not set: INTERFACE_LINK_LIBRARIES defines the link
   interface.  Run "cmake --help-policy CMP0022" for policy details.  Use the
   cmake_policy command to set the policy and suppress this warning.
diff --git a/Tests/RunCMake/CMP0022/CMP0022-export-exe-stderr.txt b/Tests/RunCMake/CMP0022/CMP0022-export-exe-stderr.txt
new file mode 100644
index 0000000..66a58fb
--- /dev/null
+++ b/Tests/RunCMake/CMP0022/CMP0022-export-exe-stderr.txt
@@ -0,0 +1,6 @@
+^CMake Deprecation Warning at CMakeLists.txt:1 \(cmake_minimum_required\):
+  Compatibility with CMake < 2.8.12 will be removed from a future version of
+  CMake.
+
+  Update the VERSION argument <min> value or use a ...<max> suffix to tell
+  CMake that the project does not need compatibility with older versions.$
diff --git a/Tests/RunCMake/CMP0026/CMakeLists.txt b/Tests/RunCMake/CMP0026/CMakeLists.txt
index 12cd3c7..4b3de84 100644
--- a/Tests/RunCMake/CMP0026/CMakeLists.txt
+++ b/Tests/RunCMake/CMP0026/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 2.8.12)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CMP0027/CMakeLists.txt b/Tests/RunCMake/CMP0027/CMakeLists.txt
index 12cd3c7..4b3de84 100644
--- a/Tests/RunCMake/CMP0027/CMakeLists.txt
+++ b/Tests/RunCMake/CMP0027/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 2.8.12)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CMP0028/CMakeLists.txt b/Tests/RunCMake/CMP0028/CMakeLists.txt
index 144cdb4..4f867df 100644
--- a/Tests/RunCMake/CMP0028/CMakeLists.txt
+++ b/Tests/RunCMake/CMP0028/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 2.8.12)
 project(${RunCMake_TEST} CXX)
 include(${RunCMake_TEST}.cmake NO_POLICY_SCOPE) # policy used at end of dir
diff --git a/Tests/RunCMake/CMP0037/CMakeLists.txt b/Tests/RunCMake/CMP0037/CMakeLists.txt
index 12cd3c7..4b3de84 100644
--- a/Tests/RunCMake/CMP0037/CMakeLists.txt
+++ b/Tests/RunCMake/CMP0037/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 2.8.12)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CMP0041/CMakeLists.txt b/Tests/RunCMake/CMP0041/CMakeLists.txt
index f452db1..a06591c 100644
--- a/Tests/RunCMake/CMP0041/CMakeLists.txt
+++ b/Tests/RunCMake/CMP0041/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 2.8.12)
 project(${RunCMake_TEST} CXX)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CMP0042/CMakeLists.txt b/Tests/RunCMake/CMP0042/CMakeLists.txt
index f452db1..a06591c 100644
--- a/Tests/RunCMake/CMP0042/CMakeLists.txt
+++ b/Tests/RunCMake/CMP0042/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 2.8.12)
 project(${RunCMake_TEST} CXX)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CMP0043/CMakeLists.txt b/Tests/RunCMake/CMP0043/CMakeLists.txt
index d027f3e..cc8a6f8 100644
--- a/Tests/RunCMake/CMP0043/CMakeLists.txt
+++ b/Tests/RunCMake/CMP0043/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 2.8.12)
 project(${RunCMake_TEST} CXX)
 include(${RunCMake_TEST}.cmake NO_POLICY_SCOPE) # policy used at end of dir
 
diff --git a/Tests/RunCMake/CMP0045/CMakeLists.txt b/Tests/RunCMake/CMP0045/CMakeLists.txt
index f452db1..a06591c 100644
--- a/Tests/RunCMake/CMP0045/CMakeLists.txt
+++ b/Tests/RunCMake/CMP0045/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 2.8.12)
 project(${RunCMake_TEST} CXX)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index 5d00554..e08b30a 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -166,6 +166,7 @@
     -DPSEUDO_BC=$<TARGET_FILE:pseudo_BC>
     -DPSEUDO_PURIFY=$<TARGET_FILE:pseudo_purify>
     -DPSEUDO_VALGRIND=$<TARGET_FILE:pseudo_valgrind>
+    -DPSEUDO_CUDA_MEMCHECK=$<TARGET_FILE:pseudo_cuda-memcheck>
     -DPSEUDO_BC_NOLOG=$<TARGET_FILE:pseudonl_BC>
     -DPSEUDO_PURIFY_NOLOG=$<TARGET_FILE:pseudonl_purify>
     -DPSEUDO_VALGRIND_NOLOG=$<TARGET_FILE:pseudonl_valgrind>
@@ -209,6 +210,7 @@
 if("${CMAKE_GENERATOR}" MATCHES "Unix Makefiles|Ninja")
   add_RunCMake_test(ExportCompileCommands)
 endif()
+add_RunCMake_test(ExcludeFromAll)
 add_RunCMake_test(ExternalData)
 add_RunCMake_test(FeatureSummary)
 add_RunCMake_test(FPHSA)
@@ -394,7 +396,7 @@
 add_RunCMake_test(CMP0004)
 add_RunCMake_test(TargetPolicies)
 add_RunCMake_test(alias_targets)
-add_RunCMake_test(interface_library)
+add_RunCMake_test(InterfaceLibrary)
 add_RunCMake_test(no_install_prefix)
 add_RunCMake_test(configure_file)
 add_RunCMake_test(CTestTimeout -DTIMEOUT=${CTestTestTimeout_TIME})
@@ -624,6 +626,7 @@
   set_property(TEST RunCMake.CompilerLauncher APPEND
     PROPERTY LABELS "CUDA")
   add_RunCMake_test(ctest_labels_for_subprojects)
+  add_RunCMake_test(CompilerArgs)
 endif()
 
 set(cpack_tests
@@ -689,8 +692,8 @@
 add_RunCMake_test(AndroidMK)
 
 if(CMake_TEST_ANDROID_NDK OR CMake_TEST_ANDROID_STANDALONE_TOOLCHAIN)
-  if(NOT "${CMAKE_GENERATOR}" MATCHES "Make|Ninja")
-    message(FATAL_ERROR "Android tests supported only by Makefile and Ninja generators")
+  if(NOT "${CMAKE_GENERATOR}" MATCHES "Make|Ninja|Visual Studio 1[456]")
+    message(FATAL_ERROR "Android tests supported only by Makefile, Ninja, and Visual Studio >= 14 generators")
   endif()
   foreach(v TEST_ANDROID_NDK TEST_ANDROID_STANDALONE_TOOLCHAIN)
     if(CMake_${v})
diff --git a/Tests/RunCMake/CPack/DragNDrop/Accept.txt b/Tests/RunCMake/CPack/DragNDrop/Accept.txt
new file mode 100644
index 0000000..975fbec
--- /dev/null
+++ b/Tests/RunCMake/CPack/DragNDrop/Accept.txt
@@ -0,0 +1 @@
+y
diff --git a/Tests/RunCMake/CPack/DragNDrop/Helpers.cmake b/Tests/RunCMake/CPack/DragNDrop/Helpers.cmake
index 023e597..896fba7 100644
--- a/Tests/RunCMake/CPack/DragNDrop/Helpers.cmake
+++ b/Tests/RunCMake/CPack/DragNDrop/Helpers.cmake
@@ -5,6 +5,7 @@
   file(REMOVE_RECURSE "${path_}/content")
   file(MAKE_DIRECTORY "${path_}/content")
   execute_process(COMMAND ${HDIUTIL_EXECUTABLE} attach -mountroot ${path_}/content -nobrowse ${FILE}
+          INPUT_FILE "${src_dir}/DragNDrop/Accept.txt"
           RESULT_VARIABLE attach_result_
           ERROR_VARIABLE attach_error_
           OUTPUT_STRIP_TRAILING_WHITESPACE)
diff --git a/Tests/RunCMake/CPack/DragNDrop/packaging_MONOLITHIC_default.cmake b/Tests/RunCMake/CPack/DragNDrop/packaging_MONOLITHIC_default.cmake
new file mode 100644
index 0000000..ca27890
--- /dev/null
+++ b/Tests/RunCMake/CPack/DragNDrop/packaging_MONOLITHIC_default.cmake
@@ -0,0 +1,2 @@
+set(CPACK_DMG_DISABLE_APPLICATIONS_SYMLINK ON)
+set(CPACK_DMG_VOLUME_NAME "volume-name")
diff --git a/Tests/RunCMake/CPack/RunCMakeTest.cmake b/Tests/RunCMake/CPack/RunCMakeTest.cmake
index 064b4dc..530bcdf 100644
--- a/Tests/RunCMake/CPack/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CPack/RunCMakeTest.cmake
@@ -10,6 +10,7 @@
 run_cpack_test_subtests(DEFAULT_PERMISSIONS "CMAKE_var_set;CPACK_var_set;both_set;invalid_CMAKE_var;invalid_CPACK_var" "RPM.DEFAULT_PERMISSIONS;DEB.DEFAULT_PERMISSIONS" false "MONOLITHIC;COMPONENT")
 run_cpack_test(DEPENDENCIES "RPM.DEPENDENCIES;DEB.DEPENDENCIES" true "COMPONENT")
 run_cpack_test(DIST "RPM.DIST" false "MONOLITHIC")
+run_cpack_test(DMG_SLA "DragNDrop" false "MONOLITHIC")
 run_cpack_test(EMPTY_DIR "RPM.EMPTY_DIR;DEB.EMPTY_DIR;TGZ" true "MONOLITHIC;COMPONENT")
 run_cpack_test(VERSION "RPM.VERSION;DEB.VERSION" false "MONOLITHIC;COMPONENT")
 run_cpack_test(EXTRA "DEB.EXTRA" false "COMPONENT")
@@ -46,3 +47,4 @@
   "MONOLITHIC;COMPONENT"
 )
 run_cpack_test(PROJECT_META "RPM.PROJECT_META;DEB.PROJECT_META" false "MONOLITHIC;COMPONENT")
+run_cpack_test_package_target(PRE_POST_SCRIPTS "ZIP" false "MONOLITHIC;COMPONENT")
diff --git a/Tests/RunCMake/CPack/tests/DEB_DESCRIPTION/VerifyResult.cmake b/Tests/RunCMake/CPack/tests/DEB_DESCRIPTION/VerifyResult.cmake
index 70ad48b..6e841fc 100644
--- a/Tests/RunCMake/CPack/tests/DEB_DESCRIPTION/VerifyResult.cmake
+++ b/Tests/RunCMake/CPack/tests/DEB_DESCRIPTION/VerifyResult.cmake
@@ -34,7 +34,7 @@
   This is the Debian package multiline description.
   .
   It must be formatted properly! Otherwise, the result `*.deb`
-  package become broken and cant be installed!
+  package become broken and cannot be installed!
   .
   It may contains `;` characters (even like this `;;;;`). Example:
   .
diff --git a/Tests/RunCMake/CPack/tests/DEB_DESCRIPTION/test.cmake b/Tests/RunCMake/CPack/tests/DEB_DESCRIPTION/test.cmake
index 893eb01..2a27b46 100644
--- a/Tests/RunCMake/CPack/tests/DEB_DESCRIPTION/test.cmake
+++ b/Tests/RunCMake/CPack/tests/DEB_DESCRIPTION/test.cmake
@@ -5,7 +5,7 @@
 set(_description [[This is the Debian package multiline description.
 
 It must be formatted properly! Otherwise, the result `*.deb`
-package become broken and cant be installed!
+package become broken and cannot be installed!
 
 It may contains `;` characters (even like this `;;;;`). Example:
 
diff --git a/Tests/RunCMake/CPack/tests/DMG_SLA/English.license.rtf b/Tests/RunCMake/CPack/tests/DMG_SLA/English.license.rtf
new file mode 100644
index 0000000..c1da711
--- /dev/null
+++ b/Tests/RunCMake/CPack/tests/DMG_SLA/English.license.rtf
@@ -0,0 +1,7 @@
+{\rtf1\ansi\ansicpg1252\deff0\nouicompat\deflang1033{\fonttbl{\f0\fnil\fcharset0 Calibri;}}
+{\colortbl ;\red0\green0\blue255;}
+{\*\generator Riched20 10.0.18362}\viewkind4\uc1
+\pard\sa200\sl276\slmult1\b\f0\fs22\lang9 LICENSE\b0\par
+This is an installer created using CPack ({{\field{\*\fldinst{HYPERLINK https://cmake.org }}{\fldrslt{https://cmake.org\ul0\cf0}}}}\f0\fs22 ). No license provided.\par
+\par
+}
diff --git a/Tests/RunCMake/CPack/tests/DMG_SLA/English.menu.txt b/Tests/RunCMake/CPack/tests/DMG_SLA/English.menu.txt
new file mode 100644
index 0000000..b2cbc25
--- /dev/null
+++ b/Tests/RunCMake/CPack/tests/DMG_SLA/English.menu.txt
@@ -0,0 +1,9 @@
+English
+Agree
+Disagree
+Print
+Save...
+You agree to the License Agreement terms when you click the "Agree" button.
+Software License Agreement
+This text cannot be saved. This disk may be full or locked or the file may be locked.
+Unable to print.  Make sure you have selected a printer.
diff --git a/Tests/RunCMake/CPack/tests/DMG_SLA/ExpectedFiles.cmake b/Tests/RunCMake/CPack/tests/DMG_SLA/ExpectedFiles.cmake
new file mode 100644
index 0000000..d1a3a5f
--- /dev/null
+++ b/Tests/RunCMake/CPack/tests/DMG_SLA/ExpectedFiles.cmake
@@ -0,0 +1,2 @@
+set(EXPECTED_FILES_COUNT "1")
+set(EXPECTED_FILE_CONTENT_1_LIST "/foo;/foo/CMakeLists.txt")
diff --git a/Tests/RunCMake/CPack/tests/DMG_SLA/German.license.txt b/Tests/RunCMake/CPack/tests/DMG_SLA/German.license.txt
new file mode 100644
index 0000000..0edd1f2
--- /dev/null
+++ b/Tests/RunCMake/CPack/tests/DMG_SLA/German.license.txt
@@ -0,0 +1,3 @@
+LIZENZ
+------
+Dies ist ein Installationsprogramm, das mit erstellt wurde CPack (https://cmake.org). Keine Lizenz angegeben.
diff --git a/Tests/RunCMake/CPack/tests/DMG_SLA/German.menu.txt b/Tests/RunCMake/CPack/tests/DMG_SLA/German.menu.txt
new file mode 100644
index 0000000..7724818
--- /dev/null
+++ b/Tests/RunCMake/CPack/tests/DMG_SLA/German.menu.txt
@@ -0,0 +1,9 @@
+German
+Akzeptieren
+Ablehnen
+Drucken
+Speichern...
+Klicken Sie auf "Akzeptieren", wenn Sie mit den Bestimmungen des Software-Lizenzvertrages einverstanden sind.
+Software-Lizenzvertrag
+Dieser Text kann nicht gesichert werden. Diese Festplatte ist mšglicherweise voll oder geschŸtzt oder der Ordner ist geschŸtzt.
+Es kann nicht gedruckt werden. Bitte stellen Sie sicher, dass ein Drucker ausgewŠhlt ist.
diff --git a/Tests/RunCMake/CPack/tests/DMG_SLA/VerifyResult.cmake b/Tests/RunCMake/CPack/tests/DMG_SLA/VerifyResult.cmake
new file mode 100644
index 0000000..010e14c
--- /dev/null
+++ b/Tests/RunCMake/CPack/tests/DMG_SLA/VerifyResult.cmake
@@ -0,0 +1,33 @@
+set(dmg "${bin_dir}/${FOUND_FILE_1}")
+execute_process(COMMAND hdiutil udifderez -xml "${dmg}" OUTPUT_VARIABLE out ERROR_VARIABLE err RESULT_VARIABLE res)
+if(NOT res EQUAL 0)
+  string(REPLACE "\n" "\n  " err "  ${err}")
+  message(FATAL_ERROR "Running 'hdiutil udifderez -xml' on\n  ${dmg}\nfailed with:\n${err}")
+endif()
+foreach(key "LPic" "STR#" "TEXT" "RTF ")
+  if(NOT out MATCHES "<key>${key}</key>")
+    string(REPLACE "\n" "\n  " out "  ${out}")
+    message(FATAL_ERROR "error: running 'hdiutil udifderez -xml' on\n  ${dmg}\ndid not show '${key}' key:\n${out}")
+  endif()
+endforeach()
+foreach(line
+    # LPic
+    "\tAAAAAgAAAAAAAAADAAEAAA==\n"
+    # STR# English first and last base64 lines
+    "\tAAkHRW5nbGlzaAVBZ3JlZQhEaXNhZ3JlZQVQcmludAdTYXZlLi4u\n"
+    "\tZCBhIHByaW50ZXIu\n"
+    # STR# German first and last base64 lines
+    "\tAAkGR2VybWFuC0FremVwdGllcmVuCEFibGVobmVuB0RydWNrZW4M\n"
+    "\tYXVzZ2V3wopobHQgaXN0Lg==\n"
+    # RTF English first and last base64 lines
+    "\te1xydGYxXGFuc2lcYW5zaWNwZzEyNTJcZGVmZjBcbm91aWNvbXBh\n"
+    "\tdmlkZWQuXHBhcg1ccGFyDX0NDQ==\n"
+    # TEXT German first and last base64 lines
+    "\tTElaRU5aDS0tLS0tLQ1EaWVzIGlzdCBlaW4gSW5zdGFsbGF0aW9u\n"
+    "\tZ2ViZW4uDQ0=\n"
+    )
+  if(NOT out MATCHES "${line}")
+    string(REPLACE "\n" "\n  " out "  ${out}")
+    message(FATAL_ERROR "error: running 'hdiutil udifderez -xml' on\n  ${dmg}\ndid not show '${line}':\n${out}")
+  endif()
+endforeach()
diff --git a/Tests/RunCMake/CPack/tests/DMG_SLA/test.cmake b/Tests/RunCMake/CPack/tests/DMG_SLA/test.cmake
new file mode 100644
index 0000000..2804b0b
--- /dev/null
+++ b/Tests/RunCMake/CPack/tests/DMG_SLA/test.cmake
@@ -0,0 +1,3 @@
+install(FILES CMakeLists.txt DESTINATION foo)
+set(CPACK_DMG_SLA_DIR "${CMAKE_CURRENT_LIST_DIR}")
+set(CPACK_DMG_SLA_LANGUAGES English German)
diff --git a/Tests/RunCMake/CPack/tests/EXTERNAL/create_package.cmake b/Tests/RunCMake/CPack/tests/EXTERNAL/create_package.cmake
index 6f7c4c2..3db8014 100644
--- a/Tests/RunCMake/CPack/tests/EXTERNAL/create_package.cmake
+++ b/Tests/RunCMake/CPack/tests/EXTERNAL/create_package.cmake
@@ -29,3 +29,11 @@
 expect_file(${CPACK_TEMPORARY_DIRECTORY}/f4/share/cpack-test/f4.txt)
 
 message(STATUS "This status message is expected to be visible")
+
+set(
+    CPACK_EXTERNAL_BUILT_PACKAGES
+    ${CPACK_TEMPORARY_DIRECTORY}/f1/share/cpack-test/f1.txt
+    ${CPACK_TEMPORARY_DIRECTORY}/f2/share/cpack-test/f2.txt
+    ${CPACK_TEMPORARY_DIRECTORY}/f3/share/cpack-test/f3.txt
+    ${CPACK_TEMPORARY_DIRECTORY}/f4/share/cpack-test/f4.txt
+  )
diff --git a/Tests/RunCMake/CPack/tests/EXTERNAL/stage_and_package-stdout.txt b/Tests/RunCMake/CPack/tests/EXTERNAL/stage_and_package-stdout.txt
index 37d635f..587b2e8 100644
--- a/Tests/RunCMake/CPack/tests/EXTERNAL/stage_and_package-stdout.txt
+++ b/Tests/RunCMake/CPack/tests/EXTERNAL/stage_and_package-stdout.txt
@@ -1 +1,11 @@
 -- This status message is expected to be visible
+CPack: - package: .*/Tests/RunCMake/External/CPack/EXTERNAL-build-stage_and_package-subtest/external-0\.1\.1-.*\.json generated\.
+CPack: - checksum file: .*/Tests/RunCMake/External/CPack/EXTERNAL-build-stage_and_package-subtest/external-0\.1\.1-.*\.json\.sha1 generated\.
+CPack: - package: .*/Tests/RunCMake/External/CPack/EXTERNAL-build-stage_and_package-subtest/f1\.txt generated\.
+CPack: - checksum file: .*/Tests/RunCMake/External/CPack/EXTERNAL-build-stage_and_package-subtest/f1\.txt\.sha1 generated\.
+CPack: - package: .*/Tests/RunCMake/External/CPack/EXTERNAL-build-stage_and_package-subtest/f2\.txt generated\.
+CPack: - checksum file: .*/Tests/RunCMake/External/CPack/EXTERNAL-build-stage_and_package-subtest/f2\.txt\.sha1 generated\.
+CPack: - package: .*/Tests/RunCMake/External/CPack/EXTERNAL-build-stage_and_package-subtest/f3\.txt generated\.
+CPack: - checksum file: .*/Tests/RunCMake/External/CPack/EXTERNAL-build-stage_and_package-subtest/f3\.txt\.sha1 generated\.
+CPack: - package: .*/Tests/RunCMake/External/CPack/EXTERNAL-build-stage_and_package-subtest/f4\.txt generated\.
+CPack: - checksum file: .*/Tests/RunCMake/External/CPack/EXTERNAL-build-stage_and_package-subtest/f4\.txt\.sha1 generated\.
diff --git a/Tests/RunCMake/CPack/tests/EXTERNAL/test.cmake b/Tests/RunCMake/CPack/tests/EXTERNAL/test.cmake
index bc9766b..d4781ba 100644
--- a/Tests/RunCMake/CPack/tests/EXTERNAL/test.cmake
+++ b/Tests/RunCMake/CPack/tests/EXTERNAL/test.cmake
@@ -17,6 +17,7 @@
 elseif(RunCMake_SUBTEST_SUFFIX STREQUAL "stage_and_package")
   set(CPACK_EXTERNAL_ENABLE_STAGING 1)
   set(CPACK_EXTERNAL_PACKAGE_SCRIPT "${CMAKE_CURRENT_LIST_DIR}/create_package.cmake")
+  set(CPACK_PACKAGE_CHECKSUM SHA1)
 endif()
 
 file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/f1.txt" test1)
diff --git a/Tests/RunCMake/CPack/tests/PRE_POST_SCRIPTS/ExpectedFiles.cmake b/Tests/RunCMake/CPack/tests/PRE_POST_SCRIPTS/ExpectedFiles.cmake
new file mode 100644
index 0000000..63a36a3
--- /dev/null
+++ b/Tests/RunCMake/CPack/tests/PRE_POST_SCRIPTS/ExpectedFiles.cmake
@@ -0,0 +1,19 @@
+set(SATU "/satu;/satu/CMakeLists.txt")
+set(DUA "/dua;/dua/CMakeLists.txt")
+
+if(GENERATOR_TYPE STREQUAL ZIP)
+    set(_ext "zip")
+elseif(GENERATOR_TYPE STREQUAL TGZ)
+    set(_ext "tar.gz")
+endif()
+
+if(PACKAGING_TYPE STREQUAL "COMPONENT")
+    set(EXPECTED_FILES_COUNT "2")
+    set(EXPECTED_FILE_1 "*-satu.${_ext}")
+    set(EXPECTED_FILE_CONTENT_1_LIST ${SATU})
+    set(EXPECTED_FILE_2 "*-dua.${_ext}")
+    set(EXPECTED_FILE_CONTENT_2_LIST ${DUA})
+else()
+    set(EXPECTED_FILES_COUNT "1")
+    set(EXPECTED_FILE_CONTENT_1_LIST ${SATU} ${DUA})
+endif()
diff --git a/Tests/RunCMake/CPack/tests/PRE_POST_SCRIPTS/ZIP_COMPONENT-stdout.txt b/Tests/RunCMake/CPack/tests/PRE_POST_SCRIPTS/ZIP_COMPONENT-stdout.txt
new file mode 100644
index 0000000..319d0da
--- /dev/null
+++ b/Tests/RunCMake/CPack/tests/PRE_POST_SCRIPTS/ZIP_COMPONENT-stdout.txt
@@ -0,0 +1,4 @@
+-- The message from .*/Tests/RunCMake/CPack/tests/PRE_POST_SCRIPTS/pre\.cmake and generator ZIP
+.*
+-- The message from .*/Tests/RunCMake/CPack/tests/PRE_POST_SCRIPTS/post\.cmake and generator ZIP
+-- Built packages: .*/_CPack_Packages/.*/pre_post_scripts-.*-dua.zip;.*/_CPack_Packages/.*/pre_post_scripts-.*-satu.zip
diff --git a/Tests/RunCMake/CPack/tests/PRE_POST_SCRIPTS/ZIP_MONOLITHIC-stdout.txt b/Tests/RunCMake/CPack/tests/PRE_POST_SCRIPTS/ZIP_MONOLITHIC-stdout.txt
new file mode 100644
index 0000000..632c4d1
--- /dev/null
+++ b/Tests/RunCMake/CPack/tests/PRE_POST_SCRIPTS/ZIP_MONOLITHIC-stdout.txt
@@ -0,0 +1,4 @@
+-- The message from .*/Tests/RunCMake/CPack/tests/PRE_POST_SCRIPTS/pre\.cmake and generator ZIP
+.*
+-- The message from .*/Tests/RunCMake/CPack/tests/PRE_POST_SCRIPTS/post\.cmake and generator ZIP
+-- Built packages: .*/_CPack_Packages/.*/pre_post_scripts-0\.1\.1-.*\.zip
diff --git a/Tests/RunCMake/CPack/tests/PRE_POST_SCRIPTS/post.cmake b/Tests/RunCMake/CPack/tests/PRE_POST_SCRIPTS/post.cmake
new file mode 100644
index 0000000..cf0b149
--- /dev/null
+++ b/Tests/RunCMake/CPack/tests/PRE_POST_SCRIPTS/post.cmake
@@ -0,0 +1,2 @@
+message(STATUS "The message from ${CMAKE_CURRENT_LIST_FILE} and generator ${CPACK_GENERATOR}")
+message(STATUS "Built packages: ${CPACK_PACKAGE_FILES}")
diff --git a/Tests/RunCMake/CPack/tests/PRE_POST_SCRIPTS/pre.cmake b/Tests/RunCMake/CPack/tests/PRE_POST_SCRIPTS/pre.cmake
new file mode 100644
index 0000000..b04aa6b
--- /dev/null
+++ b/Tests/RunCMake/CPack/tests/PRE_POST_SCRIPTS/pre.cmake
@@ -0,0 +1 @@
+message(STATUS "The message from ${CMAKE_CURRENT_LIST_FILE} and generator ${CPACK_GENERATOR}")
diff --git a/Tests/RunCMake/CPack/tests/PRE_POST_SCRIPTS/test.cmake b/Tests/RunCMake/CPack/tests/PRE_POST_SCRIPTS/test.cmake
new file mode 100644
index 0000000..f1b6d5f
--- /dev/null
+++ b/Tests/RunCMake/CPack/tests/PRE_POST_SCRIPTS/test.cmake
@@ -0,0 +1,9 @@
+install(FILES CMakeLists.txt DESTINATION satu COMPONENT satu)
+install(FILES CMakeLists.txt DESTINATION dua COMPONENT dua)
+
+set(CPACK_PRE_BUILD_SCRIPTS "${CMAKE_CURRENT_LIST_DIR}/pre.cmake")
+set(CPACK_POST_BUILD_SCRIPTS "${CMAKE_CURRENT_LIST_DIR}/post.cmake")
+
+if(PACKAGING_TYPE STREQUAL "COMPONENT")
+  set(CPACK_COMPONENTS_ALL satu dua)
+endif()
diff --git a/Tests/RunCMake/CPack/tests/PROJECT_META/VerifyResult.cmake b/Tests/RunCMake/CPack/tests/PROJECT_META/VerifyResult.cmake
index b3accb5..35a93d6 100644
--- a/Tests/RunCMake/CPack/tests/PROJECT_META/VerifyResult.cmake
+++ b/Tests/RunCMake/CPack/tests/PROJECT_META/VerifyResult.cmake
@@ -13,7 +13,7 @@
     endif()
   endforeach()
   if(NOT _seen_url)
-    message(FATAL_ERROR "The packge `${FILE}` do not have URL as expected")
+    message(FATAL_ERROR "The package `${FILE}` do not have URL as expected")
   endif()
 endfunction()
 
diff --git a/Tests/RunCMake/CTest/CMakeLists.txt b/Tests/RunCMake/CTest/CMakeLists.txt
index 73e6a78..f1a83e8 100644
--- a/Tests/RunCMake/CTest/CMakeLists.txt
+++ b/Tests/RunCMake/CTest/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 if(NOT NoProject)
   project(${RunCMake_TEST} NONE)
 endif()
diff --git a/Tests/RunCMake/CheckModules/CMakeLists.txt b/Tests/RunCMake/CheckModules/CMakeLists.txt
index 9872df2..842c5cf 100644
--- a/Tests/RunCMake/CheckModules/CMakeLists.txt
+++ b/Tests/RunCMake/CheckModules/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 2.8.11)
+cmake_minimum_required(VERSION 2.8.12)
 cmake_policy(SET CMP0054 NEW)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CommandLine/BuildDir--build-multiple-targets-fail-result.txt b/Tests/RunCMake/CommandLine/BuildDir--build-multiple-targets-fail-result.txt
new file mode 100644
index 0000000..d197c91
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/BuildDir--build-multiple-targets-fail-result.txt
@@ -0,0 +1 @@
+[^0]
diff --git a/Tests/RunCMake/CommandLine/BuildDir--build-multiple-targets-fail-stderr.txt b/Tests/RunCMake/CommandLine/BuildDir--build-multiple-targets-fail-stderr.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/BuildDir--build-multiple-targets-fail-stderr.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/CommandLine/BuildDir/CMakeLists.txt b/Tests/RunCMake/CommandLine/BuildDir/CMakeLists.txt
index d2a2831..cf2c087 100644
--- a/Tests/RunCMake/CommandLine/BuildDir/CMakeLists.txt
+++ b/Tests/RunCMake/CommandLine/BuildDir/CMakeLists.txt
@@ -5,3 +5,4 @@
 add_custom_target(CustomTarget ALL DEPENDS output.txt)
 add_custom_target(CustomTarget2 ALL DEPENDS output.txt)
 add_custom_target(CustomTarget3 ALL DEPENDS output.txt)
+add_custom_target(CustomTargetFail COMMAND DoesNotExist)
diff --git a/Tests/RunCMake/CommandLine/E_capabilities-stdout.txt b/Tests/RunCMake/CommandLine/E_capabilities-stdout.txt
index 03286f1..e24e131 100644
--- a/Tests/RunCMake/CommandLine/E_capabilities-stdout.txt
+++ b/Tests/RunCMake/CommandLine/E_capabilities-stdout.txt
@@ -1 +1 @@
-^{"fileApi":{"requests":\[{"kind":"codemodel","version":\[{"major":2,"minor":1}]},{"kind":"cache","version":\[{"major":2,"minor":0}]},{"kind":"cmakeFiles","version":\[{"major":1,"minor":0}]}]},"generators":\[.*\],"serverMode":true,"version":{.*}}$
+^{"fileApi":{"requests":\[{"kind":"codemodel","version":\[{"major":2,"minor":2}]},{"kind":"cache","version":\[{"major":2,"minor":0}]},{"kind":"cmakeFiles","version":\[{"major":1,"minor":0}]}]},"generators":\[.*\],"serverMode":true,"version":{.*}}$
diff --git a/Tests/RunCMake/CommandLine/E_compare_files-different-eol-stderr.txt b/Tests/RunCMake/CommandLine/E_compare_files-different-eol-stderr.txt
deleted file mode 100644
index 4729ccb..0000000
--- a/Tests/RunCMake/CommandLine/E_compare_files-different-eol-stderr.txt
+++ /dev/null
@@ -1 +0,0 @@
-^Files ".*/compare_files/lf" to ".*/compare_files/crlf" are different.$
diff --git a/Tests/RunCMake/CommandLine/E_compare_files-ignore-eol-nonexistent-stderr.txt b/Tests/RunCMake/CommandLine/E_compare_files-ignore-eol-nonexistent-stderr.txt
deleted file mode 100644
index 8a9ca81..0000000
--- a/Tests/RunCMake/CommandLine/E_compare_files-ignore-eol-nonexistent-stderr.txt
+++ /dev/null
@@ -1 +0,0 @@
-^Files "nonexistent_a" to "nonexistent_b" are different.$
diff --git a/Tests/RunCMake/CommandLine/E_compare_files-invalid-arguments-result.txt b/Tests/RunCMake/CommandLine/E_compare_files-invalid-arguments-result.txt
new file mode 100644
index 0000000..0cfbf08
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_compare_files-invalid-arguments-result.txt
@@ -0,0 +1 @@
+2
diff --git a/Tests/RunCMake/CommandLine/E_compare_files-invalid-arguments-stderr.txt b/Tests/RunCMake/CommandLine/E_compare_files-invalid-arguments-stderr.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_compare_files-invalid-arguments-stderr.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/interface_library/add_custom_command-TARGET-result.txt b/Tests/RunCMake/CommandLine/E_create_hardlink-no-arg-result.txt
similarity index 100%
copy from Tests/RunCMake/interface_library/add_custom_command-TARGET-result.txt
copy to Tests/RunCMake/CommandLine/E_create_hardlink-no-arg-result.txt
diff --git a/Tests/RunCMake/CommandLine/E_create_hardlink-no-arg-stderr.txt b/Tests/RunCMake/CommandLine/E_create_hardlink-no-arg-stderr.txt
new file mode 100644
index 0000000..50d9b03
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_create_hardlink-no-arg-stderr.txt
@@ -0,0 +1,3 @@
+^CMake Error: cmake version .*
+Usage: .* -E <command> \[arguments\.\.\.\]
+Available commands:
diff --git a/Tests/RunCMake/interface_library/IMPORTED_LIBNAME-bad-value-result.txt b/Tests/RunCMake/CommandLine/E_create_hardlink-no-directory-result.txt
similarity index 100%
copy from Tests/RunCMake/interface_library/IMPORTED_LIBNAME-bad-value-result.txt
copy to Tests/RunCMake/CommandLine/E_create_hardlink-no-directory-result.txt
diff --git a/Tests/RunCMake/CommandLine/E_create_hardlink-no-directory-stderr.txt b/Tests/RunCMake/CommandLine/E_create_hardlink-no-directory-stderr.txt
new file mode 100644
index 0000000..21e60ee
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_create_hardlink-no-directory-stderr.txt
@@ -0,0 +1 @@
+^CMake Error: failed to create link .* no such file or directory
diff --git a/Tests/RunCMake/interface_library/IMPORTED_LIBNAME-non-iface-result.txt b/Tests/RunCMake/CommandLine/E_create_hardlink-non-existent-source-result.txt
similarity index 100%
copy from Tests/RunCMake/interface_library/IMPORTED_LIBNAME-non-iface-result.txt
copy to Tests/RunCMake/CommandLine/E_create_hardlink-non-existent-source-result.txt
diff --git a/Tests/RunCMake/CommandLine/E_create_hardlink-non-existent-source-stderr.txt b/Tests/RunCMake/CommandLine/E_create_hardlink-non-existent-source-stderr.txt
new file mode 100644
index 0000000..a334571
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_create_hardlink-non-existent-source-stderr.txt
@@ -0,0 +1 @@
+^failed to create hard link because source path .* does not exist
diff --git a/Tests/RunCMake/CommandLine/E_create_hardlink-unresolved-symlink-prereq-check.cmake b/Tests/RunCMake/CommandLine/E_create_hardlink-unresolved-symlink-prereq-check.cmake
new file mode 100644
index 0000000..5b97aec
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_create_hardlink-unresolved-symlink-prereq-check.cmake
@@ -0,0 +1,3 @@
+if(${actual_stderr_var} MATCHES "operation not permitted")
+  unset(msg)
+endif()
diff --git a/Tests/RunCMake/interface_library/IMPORTED_LIBNAME-bad-value-result.txt b/Tests/RunCMake/CommandLine/E_create_hardlink-unresolved-symlink-result.txt
similarity index 100%
copy from Tests/RunCMake/interface_library/IMPORTED_LIBNAME-bad-value-result.txt
copy to Tests/RunCMake/CommandLine/E_create_hardlink-unresolved-symlink-result.txt
diff --git a/Tests/RunCMake/CommandLine/E_create_hardlink-unresolved-symlink-stderr.txt b/Tests/RunCMake/CommandLine/E_create_hardlink-unresolved-symlink-stderr.txt
new file mode 100644
index 0000000..a334571
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_create_hardlink-unresolved-symlink-stderr.txt
@@ -0,0 +1 @@
+^failed to create hard link because source path .* does not exist
diff --git a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
index 973391d..2a5d5d3 100644
--- a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
@@ -22,6 +22,7 @@
 run_cmake_command(E_compare_files-ignore-eol-same ${CMAKE_COMMAND} -E compare_files --ignore-eol ${RunCMake_SOURCE_DIR}/compare_files/lf ${RunCMake_SOURCE_DIR}/compare_files/crlf)
 run_cmake_command(E_compare_files-ignore-eol-empty ${CMAKE_COMMAND} -E compare_files --ignore-eol ${RunCMake_SOURCE_DIR}/compare_files/empty1 ${RunCMake_SOURCE_DIR}/compare_files/empty2)
 run_cmake_command(E_compare_files-ignore-eol-nonexistent ${CMAKE_COMMAND} -E compare_files --ignore-eol nonexistent_a nonexistent_b)
+run_cmake_command(E_compare_files-invalid-arguments ${CMAKE_COMMAND} -E compare_files file1.txt file2.txt file3.txt)
 run_cmake_command(E_echo_append ${CMAKE_COMMAND} -E echo_append)
 run_cmake_command(E_rename-no-arg ${CMAKE_COMMAND} -E rename)
 run_cmake_command(E_server-arg ${CMAKE_COMMAND} -E server --extra-arg)
@@ -66,6 +67,32 @@
 run_cmake_command(install-options-to-vars
   ${CMAKE_COMMAND} --install ${RunCMake_SOURCE_DIR}/dir-install-options-to-vars
   --strip --prefix /var/test --config sample --component pack)
+run_cmake_command(install-default-dir-permissions-all
+  ${CMAKE_COMMAND} --install ${RunCMake_SOURCE_DIR}/dir-permissions-install-options-to-vars
+  --default-directory-permissions u=rwx,g=rx,o=rx)
+run_cmake_command(install-default-dir-permissions-afew
+  ${CMAKE_COMMAND} --install ${RunCMake_SOURCE_DIR}/dir-permissions-install-options-to-vars
+  --default-directory-permissions u=rwx,g=rx)
+run_cmake_command(install-default-dir-permissions-none
+  ${CMAKE_COMMAND} --install ${RunCMake_SOURCE_DIR}/dir-permissions-install-options-to-vars)
+run_cmake_command(install-default-dir-permissions-invalid-comma1
+  ${CMAKE_COMMAND} --install ${RunCMake_SOURCE_DIR}/dir-permissions-install-options-to-vars
+  --default-directory-permissions u=rwxg=,x)
+run_cmake_command(install-default-dir-permissions-invalid-comma2
+  ${CMAKE_COMMAND} --install ${RunCMake_SOURCE_DIR}/dir-permissions-install-options-to-vars
+  --default-directory-permissions u=rwxg,=x)
+run_cmake_command(install-default-dir-permissions-comma-at-the-end
+  ${CMAKE_COMMAND} --install ${RunCMake_SOURCE_DIR}/dir-permissions-install-options-to-vars
+  --default-directory-permissions u=rwx,)
+run_cmake_command(install-default-dir-permissions-invalid-assignment
+  ${CMAKE_COMMAND} --install ${RunCMake_SOURCE_DIR}/dir-permissions-install-options-to-vars
+  --default-directory-permissions u=rwx,=x)
+run_cmake_command(install-default-dir-permissions-assignment-at-the-end
+  ${CMAKE_COMMAND} --install ${RunCMake_SOURCE_DIR}/dir-permissions-install-options-to-vars
+  --default-directory-permissions u=rwx,g=)
+run_cmake_command(install-default-dir-permissions-assignment-at-the-beginning
+  ${CMAKE_COMMAND} --install ${RunCMake_SOURCE_DIR}/dir-permissions-install-options-to-vars
+  --default-directory-permissions =u=rwx,g=rx)
 
 run_cmake_command(cache-bad-entry
   ${CMAKE_COMMAND} --build ${RunCMake_SOURCE_DIR}/cache-bad-entry/)
@@ -134,6 +161,8 @@
     ${CMAKE_COMMAND} --build BuildDir-build --target CustomTarget)
   run_cmake_command(BuildDir--build-multiple-targets ${CMAKE_COMMAND} -E chdir ..
     ${CMAKE_COMMAND} --build BuildDir-build -t CustomTarget2 --target CustomTarget3)
+  run_cmake_command(BuildDir--build-multiple-targets-fail ${CMAKE_COMMAND} -E chdir ..
+    ${CMAKE_COMMAND} --build BuildDir-build -t CustomTargetFail --target CustomTarget3)
   run_cmake_command(BuildDir--build-multiple-targets-jobs ${CMAKE_COMMAND} -E chdir ..
     ${CMAKE_COMMAND} --build BuildDir-build --target CustomTarget CustomTarget2 -j2 --target CustomTarget3)
   run_cmake_command(BuildDir--build-multiple-targets-with-clean-first ${CMAKE_COMMAND} -E chdir ..
@@ -319,6 +348,42 @@
   ${CMAKE_COMMAND} -E create_symlink T .
   )
 
+#create hard link tests
+run_cmake_command(E_create_hardlink-no-arg
+  ${CMAKE_COMMAND} -E create_hardlink
+  )
+
+set(dir ${RunCMake_BINARY_DIR}/hardlink_tests)
+file(REMOVE_RECURSE "${dir}")
+file(MAKE_DIRECTORY ${dir})
+
+run_cmake_command(E_create_hardlink-non-existent-source
+  ${CMAKE_COMMAND} -E create_hardlink ${dir}/I_dont_exist ${dir}/link
+  )
+
+file(TOUCH ${dir}/1)
+
+run_cmake_command(E_create_hardlink-ok
+  ${CMAKE_COMMAND} -E create_hardlink ${dir}/1 ${dir}/1-link
+  )
+
+run_cmake_command(E_create_hardlink-no-directory
+  ${CMAKE_COMMAND} -E create_hardlink ${dir}/1 ${dir}/a/1-link
+  )
+
+#On Windows, if the user does not have sufficient privileges
+#don't fail this test
+set(RunCMake_DEFAULT_stderr "(operation not permitted)?")
+run_cmake_command(E_create_hardlink-unresolved-symlink-prereq
+  ${CMAKE_COMMAND} -E create_symlink ${dir}/1 ${dir}/1-symlink
+  )
+file(REMOVE ${dir}/1)
+
+run_cmake_command(E_create_hardlink-unresolved-symlink
+  ${CMAKE_COMMAND} -E create_hardlink ${dir}/1-symlink ${dir}/1s-link
+  )
+unset(RunCMake_DEFAULT_stderr)
+
 set(in ${RunCMake_SOURCE_DIR}/copy_input)
 set(out ${RunCMake_BINARY_DIR}/copy_output)
 file(REMOVE_RECURSE "${out}")
@@ -714,15 +779,15 @@
   file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
   run_cmake_command(llvm_rc_no_args ${CMAKE_COMMAND} -E cmake_llvm_rc)
   run_cmake_command(llvm_rc_no_-- ${CMAKE_COMMAND} -E cmake_llvm_rc ${RunCMake_TEST_BINARY_DIR}/source_file test.tmp ${CMAKE_COMMAND} -E echo "This is a test")
-  run_cmake_command(llvm_rc_empty_preprocessor ${CMAKE_COMMAND} -E cmake_llvm_rc ${RunCMake_TEST_BINARY_DIR}/source_file test.tmp -- ${CMAKE_COMMAND} -E echo "This is a test")
-  run_cmake_command(llvm_rc_failing_first_command ${CMAKE_COMMAND} -E cmake_llvm_rc ${RunCMake_TEST_BINARY_DIR}/source_file test.tmp ${CMAKE_COMMAND} -P FailedProgram.cmake -- ${CMAKE_COMMAND} -E echo "This is a test")
-  run_cmake_command(llvm_rc_failing_second_command ${CMAKE_COMMAND} -E cmake_llvm_rc ${RunCMake_TEST_BINARY_DIR}/source_file test.tmp ${CMAKE_COMMAND} -E echo "This is a test" -- ${CMAKE_COMMAND} -P FailedProgram.cmake )
+  run_cmake_command(llvm_rc_empty_preprocessor ${CMAKE_COMMAND} -E cmake_llvm_rc ${RunCMake_TEST_BINARY_DIR}/source_file test.tmp ++ ${CMAKE_COMMAND} -E echo "This is a test")
+  run_cmake_command(llvm_rc_failing_first_command ${CMAKE_COMMAND} -E cmake_llvm_rc ${RunCMake_TEST_BINARY_DIR}/source_file test.tmp ${CMAKE_COMMAND} -P FailedProgram.cmake ++ ${CMAKE_COMMAND} -E echo "This is a test")
+  run_cmake_command(llvm_rc_failing_second_command ${CMAKE_COMMAND} -E cmake_llvm_rc ${RunCMake_TEST_BINARY_DIR}/source_file test.tmp ${CMAKE_COMMAND} -E echo "This is a test" ++ ${CMAKE_COMMAND} -P FailedProgram.cmake )
   if(EXISTS ${RunCMake_TEST_BINARY_DIR}/test.tmp)
       message(SEND_ERROR "${test} - FAILED:\n"
         "test.tmp was not deleted")
   endif()
   file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}/ExpandSourceDir")
-  run_cmake_command(llvm_rc_full_run ${CMAKE_COMMAND} -E cmake_llvm_rc ${RunCMake_TEST_BINARY_DIR}/ExpandSourceDir/source_file test.tmp ${CMAKE_COMMAND} -E echo "This is a test" -- ${CMAKE_COMMAND} -E copy test.tmp SOURCE_DIR/llvmrc.result )
+  run_cmake_command(llvm_rc_full_run ${CMAKE_COMMAND} -E cmake_llvm_rc ${RunCMake_TEST_BINARY_DIR}/ExpandSourceDir/source_file test.tmp ${CMAKE_COMMAND} -E echo "This is a test" ++ ${CMAKE_COMMAND} -E copy test.tmp SOURCE_DIR/llvmrc.result )
   if(EXISTS ${RunCMake_TEST_BINARY_DIR}/ExpandSourceDir/test.tmp)
       message(SEND_ERROR "${test} - FAILED:\n"
         "test.tmp was not deleted")
diff --git a/Tests/RunCMake/CommandLine/dir-permissions-install-options-to-vars/cmake_install.cmake b/Tests/RunCMake/CommandLine/dir-permissions-install-options-to-vars/cmake_install.cmake
new file mode 100644
index 0000000..42ef745
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/dir-permissions-install-options-to-vars/cmake_install.cmake
@@ -0,0 +1,3 @@
+if(CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS)
+  message("CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS is ${CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS}")
+endif()
diff --git a/Tests/RunCMake/interface_library/genex_link-result.txt b/Tests/RunCMake/CommandLine/install-default-dir-permissions-afew-result.txt
similarity index 100%
copy from Tests/RunCMake/interface_library/genex_link-result.txt
copy to Tests/RunCMake/CommandLine/install-default-dir-permissions-afew-result.txt
diff --git a/Tests/RunCMake/CommandLine/install-default-dir-permissions-afew-stderr.txt b/Tests/RunCMake/CommandLine/install-default-dir-permissions-afew-stderr.txt
new file mode 100644
index 0000000..42f4b3f
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/install-default-dir-permissions-afew-stderr.txt
@@ -0,0 +1 @@
+CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS is OWNER_READ;OWNER_WRITE;OWNER_EXECUTE;GROUP_READ;GROUP_EXECUTE
diff --git a/Tests/RunCMake/interface_library/genex_link-result.txt b/Tests/RunCMake/CommandLine/install-default-dir-permissions-all-result.txt
similarity index 100%
copy from Tests/RunCMake/interface_library/genex_link-result.txt
copy to Tests/RunCMake/CommandLine/install-default-dir-permissions-all-result.txt
diff --git a/Tests/RunCMake/CommandLine/install-default-dir-permissions-all-stderr.txt b/Tests/RunCMake/CommandLine/install-default-dir-permissions-all-stderr.txt
new file mode 100644
index 0000000..813d9c3
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/install-default-dir-permissions-all-stderr.txt
@@ -0,0 +1 @@
+CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS is OWNER_READ;OWNER_WRITE;OWNER_EXECUTE;GROUP_READ;GROUP_EXECUTE;WORLD_READ;WORLD_EXECUTE
diff --git a/Tests/RunCMake/interface_library/IMPORTED_LIBNAME-bad-value-result.txt b/Tests/RunCMake/CommandLine/install-default-dir-permissions-assignment-at-the-beginning-result.txt
similarity index 100%
copy from Tests/RunCMake/interface_library/IMPORTED_LIBNAME-bad-value-result.txt
copy to Tests/RunCMake/CommandLine/install-default-dir-permissions-assignment-at-the-beginning-result.txt
diff --git a/Tests/RunCMake/CommandLine/install-default-dir-permissions-assignment-at-the-beginning-stderr.txt b/Tests/RunCMake/CommandLine/install-default-dir-permissions-assignment-at-the-beginning-stderr.txt
new file mode 100644
index 0000000..1b80952
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/install-default-dir-permissions-assignment-at-the-beginning-stderr.txt
@@ -0,0 +1 @@
+--default-directory-permissions is in incorrect format
diff --git a/Tests/RunCMake/interface_library/genex_link-result.txt b/Tests/RunCMake/CommandLine/install-default-dir-permissions-assignment-at-the-end-result.txt
similarity index 100%
copy from Tests/RunCMake/interface_library/genex_link-result.txt
copy to Tests/RunCMake/CommandLine/install-default-dir-permissions-assignment-at-the-end-result.txt
diff --git a/Tests/RunCMake/CommandLine/install-default-dir-permissions-assignment-at-the-end-stderr.txt b/Tests/RunCMake/CommandLine/install-default-dir-permissions-assignment-at-the-end-stderr.txt
new file mode 100644
index 0000000..6680932
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/install-default-dir-permissions-assignment-at-the-end-stderr.txt
@@ -0,0 +1 @@
+CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS is OWNER_READ;OWNER_WRITE;OWNER_EXECUTE
diff --git a/Tests/RunCMake/interface_library/IMPORTED_LIBNAME-non-imported-result.txt b/Tests/RunCMake/CommandLine/install-default-dir-permissions-comma-at-the-end-result.txt
similarity index 100%
copy from Tests/RunCMake/interface_library/IMPORTED_LIBNAME-non-imported-result.txt
copy to Tests/RunCMake/CommandLine/install-default-dir-permissions-comma-at-the-end-result.txt
diff --git a/Tests/RunCMake/CommandLine/install-default-dir-permissions-comma-at-the-end-stderr.txt b/Tests/RunCMake/CommandLine/install-default-dir-permissions-comma-at-the-end-stderr.txt
new file mode 100644
index 0000000..1b80952
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/install-default-dir-permissions-comma-at-the-end-stderr.txt
@@ -0,0 +1 @@
+--default-directory-permissions is in incorrect format
diff --git a/Tests/RunCMake/interface_library/IMPORTED_LIBNAME-bad-value-result.txt b/Tests/RunCMake/CommandLine/install-default-dir-permissions-invalid-assignment-result.txt
similarity index 100%
copy from Tests/RunCMake/interface_library/IMPORTED_LIBNAME-bad-value-result.txt
copy to Tests/RunCMake/CommandLine/install-default-dir-permissions-invalid-assignment-result.txt
diff --git a/Tests/RunCMake/CommandLine/install-default-dir-permissions-invalid-assignment-stderr.txt b/Tests/RunCMake/CommandLine/install-default-dir-permissions-invalid-assignment-stderr.txt
new file mode 100644
index 0000000..1b80952
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/install-default-dir-permissions-invalid-assignment-stderr.txt
@@ -0,0 +1 @@
+--default-directory-permissions is in incorrect format
diff --git a/Tests/RunCMake/interface_library/IMPORTED_LIBNAME-bad-value-result.txt b/Tests/RunCMake/CommandLine/install-default-dir-permissions-invalid-comma1-result.txt
similarity index 100%
copy from Tests/RunCMake/interface_library/IMPORTED_LIBNAME-bad-value-result.txt
copy to Tests/RunCMake/CommandLine/install-default-dir-permissions-invalid-comma1-result.txt
diff --git a/Tests/RunCMake/CommandLine/install-default-dir-permissions-invalid-comma1-stderr.txt b/Tests/RunCMake/CommandLine/install-default-dir-permissions-invalid-comma1-stderr.txt
new file mode 100644
index 0000000..1b80952
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/install-default-dir-permissions-invalid-comma1-stderr.txt
@@ -0,0 +1 @@
+--default-directory-permissions is in incorrect format
diff --git a/Tests/RunCMake/interface_library/IMPORTED_LIBNAME-bad-value-result.txt b/Tests/RunCMake/CommandLine/install-default-dir-permissions-invalid-comma2-result.txt
similarity index 100%
copy from Tests/RunCMake/interface_library/IMPORTED_LIBNAME-bad-value-result.txt
copy to Tests/RunCMake/CommandLine/install-default-dir-permissions-invalid-comma2-result.txt
diff --git a/Tests/RunCMake/CommandLine/install-default-dir-permissions-invalid-comma2-stderr.txt b/Tests/RunCMake/CommandLine/install-default-dir-permissions-invalid-comma2-stderr.txt
new file mode 100644
index 0000000..1b80952
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/install-default-dir-permissions-invalid-comma2-stderr.txt
@@ -0,0 +1 @@
+--default-directory-permissions is in incorrect format
diff --git a/Tests/RunCMake/interface_library/genex_link-result.txt b/Tests/RunCMake/CommandLine/install-default-dir-permissions-none-result.txt
similarity index 100%
copy from Tests/RunCMake/interface_library/genex_link-result.txt
copy to Tests/RunCMake/CommandLine/install-default-dir-permissions-none-result.txt
diff --git a/Tests/RunCMake/CommandLine/install-default-dir-permissions-none-stderr.txt b/Tests/RunCMake/CommandLine/install-default-dir-permissions-none-stderr.txt
new file mode 100644
index 0000000..10f3293
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/install-default-dir-permissions-none-stderr.txt
@@ -0,0 +1 @@
+^$
diff --git a/Tests/RunCMake/CompatibleInterface/CMakeLists.txt b/Tests/RunCMake/CompatibleInterface/CMakeLists.txt
index f452db1..ebab7a3 100644
--- a/Tests/RunCMake/CompatibleInterface/CMakeLists.txt
+++ b/Tests/RunCMake/CompatibleInterface/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} CXX)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CompatibleInterface/DebugProperties.cmake b/Tests/RunCMake/CompatibleInterface/DebugProperties.cmake
index 0196611..64b52d9 100644
--- a/Tests/RunCMake/CompatibleInterface/DebugProperties.cmake
+++ b/Tests/RunCMake/CompatibleInterface/DebugProperties.cmake
@@ -1,5 +1,5 @@
 
-cmake_minimum_required(VERSION 2.8)
+cmake_minimum_required(VERSION 3.3)
 
 project(CompatibleInterface)
 
diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceString-builtin-prop.cmake b/Tests/RunCMake/CompatibleInterface/InterfaceString-builtin-prop.cmake
index 5772856..f072eb0 100644
--- a/Tests/RunCMake/CompatibleInterface/InterfaceString-builtin-prop.cmake
+++ b/Tests/RunCMake/CompatibleInterface/InterfaceString-builtin-prop.cmake
@@ -5,5 +5,5 @@
 set_property(TARGET foo APPEND PROPERTY COMPATIBLE_INTERFACE_STRING INCLUDE_DIRECTORIES)
 
 add_executable(user main.cpp)
-set_property(TARGET user PROPERTY INCLUDE_DIRECTORIES bar_inc)
+set_property(TARGET user PROPERTY INCLUDE_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR}/bar_inc)
 target_link_libraries(user foo bar)
diff --git a/Tests/RunCMake/CompilerArgs/C.cmake b/Tests/RunCMake/CompilerArgs/C.cmake
new file mode 100644
index 0000000..96b004b
--- /dev/null
+++ b/Tests/RunCMake/CompilerArgs/C.cmake
@@ -0,0 +1,3 @@
+enable_language(C)
+set(CMAKE_VERBOSE_MAKEFILE TRUE)
+add_executable(main main.c)
diff --git a/Tests/RunCMake/interface_library/CMakeLists.txt b/Tests/RunCMake/CompilerArgs/CMakeLists.txt
similarity index 62%
rename from Tests/RunCMake/interface_library/CMakeLists.txt
rename to Tests/RunCMake/CompilerArgs/CMakeLists.txt
index 12cd3c7..18dfd26 100644
--- a/Tests/RunCMake/interface_library/CMakeLists.txt
+++ b/Tests/RunCMake/CompilerArgs/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.2)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CompilerArgs/CXX.cmake b/Tests/RunCMake/CompilerArgs/CXX.cmake
new file mode 100644
index 0000000..3d2ee00
--- /dev/null
+++ b/Tests/RunCMake/CompilerArgs/CXX.cmake
@@ -0,0 +1,3 @@
+enable_language(CXX)
+set(CMAKE_VERBOSE_MAKEFILE TRUE)
+add_executable(main main.cxx)
diff --git a/Tests/RunCMake/CompilerArgs/FindCCompiler.cmake b/Tests/RunCMake/CompilerArgs/FindCCompiler.cmake
new file mode 100644
index 0000000..aeaaf7f
--- /dev/null
+++ b/Tests/RunCMake/CompilerArgs/FindCCompiler.cmake
@@ -0,0 +1,2 @@
+enable_language(C)
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/C_comp.cmake" "set(temp_CMAKE_C_COMPILER \"${CMAKE_C_COMPILER}\")\n")
diff --git a/Tests/RunCMake/CompilerArgs/FindCXXCompiler.cmake b/Tests/RunCMake/CompilerArgs/FindCXXCompiler.cmake
new file mode 100644
index 0000000..663ac83
--- /dev/null
+++ b/Tests/RunCMake/CompilerArgs/FindCXXCompiler.cmake
@@ -0,0 +1,2 @@
+enable_language(CXX)
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/CXX_comp.cmake" "set(temp_CMAKE_CXX_COMPILER \"${CMAKE_CXX_COMPILER}\")\n")
diff --git a/Tests/RunCMake/CompilerArgs/RunCMakeTest.cmake b/Tests/RunCMake/CompilerArgs/RunCMakeTest.cmake
new file mode 100644
index 0000000..9e5a18a
--- /dev/null
+++ b/Tests/RunCMake/CompilerArgs/RunCMakeTest.cmake
@@ -0,0 +1,58 @@
+include(RunCMake)
+
+function(find_compiler lang)
+  # Detect the compiler in use in the current environment.
+  run_cmake(Find${lang}Compiler)
+  # Use the detected compiler
+  include(${RunCMake_BINARY_DIR}/Find${lang}Compiler-build/${lang}_comp.cmake)
+  if(NOT temp_CMAKE_${lang}_COMPILER)
+    message(FATAL_ERROR "FindCompiler provided no compiler!")
+  endif()
+  # Create a toolchain file
+  set(__test_compiler_var CMAKE_${lang}_COMPILER)
+  set(__test_compiler "${temp_CMAKE_${lang}_COMPILER}")
+  configure_file(${RunCMake_SOURCE_DIR}/toolchain.cmake.in
+      ${RunCMake_BINARY_DIR}/Find${lang}Compiler-build/toolchain_${lang}_comp.cmake @ONLY)
+endfunction()
+
+function(run_compiler_env lang)
+  # Use the correct compiler
+  include(${RunCMake_BINARY_DIR}/Find${lang}Compiler-build/${lang}_comp.cmake)
+
+  # Use a single build tree for tests without cleaning.
+  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${lang}-env-build)
+  set(RunCMake_TEST_NO_CLEAN 1)
+  file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+  file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+
+  # Set the compiler
+  if(lang STREQUAL "C")
+    set(ENV{CC} "'${temp_CMAKE_${lang}_COMPILER}' -DFOO1 -DFOO2")
+  else()
+    set(ENV{${lang}} "'${temp_CMAKE_${lang}_COMPILER}' -DFOO1 -DFOO2")
+  endif()
+
+  run_cmake(${lang})
+  run_cmake_command(${lang}-Build ${CMAKE_COMMAND} --build . ${verbose_args})
+endfunction()
+
+function(run_compiler_tc lang)
+  # Use a single build tree for tests without cleaning.
+  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${lang}-tc-build)
+  set(RunCMake_TEST_NO_CLEAN 1)
+  file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+  file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+
+  set(RunCMake_TEST_OPTIONS
+      -DCMAKE_TOOLCHAIN_FILE=${RunCMake_BINARY_DIR}/Find${lang}Compiler-build/toolchain_${lang}_comp.cmake)
+  run_cmake(${lang})
+  run_cmake_command(${lang}-Build ${CMAKE_COMMAND} --build . ${verbose_args})
+endfunction()
+
+set(langs C CXX)
+
+foreach(lang ${langs})
+  find_compiler(${lang})
+  run_compiler_env(${lang})
+  run_compiler_tc(${lang})
+endforeach()
diff --git a/Tests/RunCMake/CompilerArgs/main.c b/Tests/RunCMake/CompilerArgs/main.c
new file mode 100644
index 0000000..b526135
--- /dev/null
+++ b/Tests/RunCMake/CompilerArgs/main.c
@@ -0,0 +1,10 @@
+#ifndef FOO1
+#  error Missing FOO1
+#endif
+#ifndef FOO2
+#  error Missing FOO2
+#endif
+int main(void)
+{
+  return 0;
+}
diff --git a/Tests/RunCMake/CompilerArgs/main.cxx b/Tests/RunCMake/CompilerArgs/main.cxx
new file mode 100644
index 0000000..db90e93
--- /dev/null
+++ b/Tests/RunCMake/CompilerArgs/main.cxx
@@ -0,0 +1,10 @@
+#ifndef FOO1
+#  error Missing FOO1
+#endif
+#ifndef FOO2
+#  error Missing FOO2
+#endif
+int main()
+{
+  return 0;
+}
diff --git a/Tests/RunCMake/CompilerArgs/toolchain.cmake.in b/Tests/RunCMake/CompilerArgs/toolchain.cmake.in
new file mode 100644
index 0000000..ff77639
--- /dev/null
+++ b/Tests/RunCMake/CompilerArgs/toolchain.cmake.in
@@ -0,0 +1 @@
+set(@__test_compiler_var@ "@__test_compiler@" -DFOO1 -DFOO2)
diff --git a/Tests/RunCMake/CompilerChange/CMakeLists.txt b/Tests/RunCMake/CompilerChange/CMakeLists.txt
index b4b3016..14c47ad 100644
--- a/Tests/RunCMake/CompilerChange/CMakeLists.txt
+++ b/Tests/RunCMake/CompilerChange/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 if(NOT RunCMake_TEST)
   set(RunCMake_TEST "$ENV{RunCMake_TEST}") # needed when cache is deleted
 endif()
diff --git a/Tests/RunCMake/CompilerNotFound/CMakeLists.txt b/Tests/RunCMake/CompilerNotFound/CMakeLists.txt
index 12cd3c7..74b3ff8 100644
--- a/Tests/RunCMake/CompilerNotFound/CMakeLists.txt
+++ b/Tests/RunCMake/CompilerNotFound/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/Configure/CMakeLists.txt b/Tests/RunCMake/Configure/CMakeLists.txt
index 12cd3c7..74b3ff8 100644
--- a/Tests/RunCMake/Configure/CMakeLists.txt
+++ b/Tests/RunCMake/Configure/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/DisallowedCommands/CMakeLists.txt b/Tests/RunCMake/DisallowedCommands/CMakeLists.txt
index 12cd3c7..4b3de84 100644
--- a/Tests/RunCMake/DisallowedCommands/CMakeLists.txt
+++ b/Tests/RunCMake/DisallowedCommands/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 2.8.12)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/interface_library/CMakeLists.txt b/Tests/RunCMake/ExcludeFromAll/CMakeLists.txt
similarity index 62%
copy from Tests/RunCMake/interface_library/CMakeLists.txt
copy to Tests/RunCMake/ExcludeFromAll/CMakeLists.txt
index 12cd3c7..74b3ff8 100644
--- a/Tests/RunCMake/interface_library/CMakeLists.txt
+++ b/Tests/RunCMake/ExcludeFromAll/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/ExcludeFromAll/RunCMakeTest.cmake b/Tests/RunCMake/ExcludeFromAll/RunCMakeTest.cmake
new file mode 100644
index 0000000..2b4fc89
--- /dev/null
+++ b/Tests/RunCMake/ExcludeFromAll/RunCMakeTest.cmake
@@ -0,0 +1,26 @@
+include(RunCMake)
+
+function(run_single_config_test label config exclude_from_all_value expectation)
+    set(case single-config)
+    message("-- Starting ${case} test: ${label}")
+    set(full_case_name "${case}-build-${config}")
+    set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/${full_case_name}/")
+    run_cmake_with_options(${case}
+        -DCMAKE_BUILD_TYPE=${config}
+        -DTOOL_EXCLUDE_FROM_ALL=${exclude_from_all_value})
+    set(RunCMake_TEST_NO_CLEAN 1)
+    include(${RunCMake_TEST_BINARY_DIR}/target_files_${config}.cmake)
+    run_cmake_command(${case}-build ${CMAKE_COMMAND} --build . --config ${config})
+endfunction()
+
+run_single_config_test("explictly not excluded" Debug 0 "should_exist")
+run_single_config_test("excluded" Debug 1 "should_not_exist")
+
+if(RunCMake_GENERATOR MATCHES "^(Xcode|Visual Studio)")
+    run_cmake(error-on-mixed-config)
+else()
+    run_single_config_test("explicitly not excluded with genex"
+        Release $<CONFIG:Debug> "should_exist")
+    run_single_config_test("excluded with genex"
+        Debug $<CONFIG:Debug> "should_not_exist")
+endif()
diff --git a/Tests/RunCMake/interface_library/global-interface-result.txt b/Tests/RunCMake/ExcludeFromAll/error-on-mixed-config-result.txt
similarity index 100%
copy from Tests/RunCMake/interface_library/global-interface-result.txt
copy to Tests/RunCMake/ExcludeFromAll/error-on-mixed-config-result.txt
diff --git a/Tests/RunCMake/ExcludeFromAll/error-on-mixed-config-stderr.txt b/Tests/RunCMake/ExcludeFromAll/error-on-mixed-config-stderr.txt
new file mode 100644
index 0000000..6dc785f
--- /dev/null
+++ b/Tests/RunCMake/ExcludeFromAll/error-on-mixed-config-stderr.txt
@@ -0,0 +1,3 @@
+CMake Error in CMakeLists.txt:
+  The EXCLUDE_FROM_ALL property of target "release_only_tool" varies by
+  configuration.  This is not supported by the "[^"]+"
diff --git a/Tests/RunCMake/ExcludeFromAll/error-on-mixed-config.cmake b/Tests/RunCMake/ExcludeFromAll/error-on-mixed-config.cmake
new file mode 100644
index 0000000..6c0ed1d
--- /dev/null
+++ b/Tests/RunCMake/ExcludeFromAll/error-on-mixed-config.cmake
@@ -0,0 +1,6 @@
+enable_language(C)
+
+set(CMAKE_CONFIGURATION_TYPES "Release;Debug" CACHE STRING "")
+
+add_executable(release_only_tool main.c)
+set_property(TARGET release_only_tool PROPERTY EXCLUDE_FROM_ALL "$<NOT:$<CONFIG:Release>>")
diff --git a/Tests/RunCMake/ExcludeFromAll/main.c b/Tests/RunCMake/ExcludeFromAll/main.c
new file mode 100644
index 0000000..f8b643a
--- /dev/null
+++ b/Tests/RunCMake/ExcludeFromAll/main.c
@@ -0,0 +1,4 @@
+int main()
+{
+  return 0;
+}
diff --git a/Tests/RunCMake/ExcludeFromAll/single-config-build-check.cmake b/Tests/RunCMake/ExcludeFromAll/single-config-build-check.cmake
new file mode 100644
index 0000000..1c455f2
--- /dev/null
+++ b/Tests/RunCMake/ExcludeFromAll/single-config-build-check.cmake
@@ -0,0 +1,17 @@
+if(expectation STREQUAL "should_not_exist")
+    set(should_exist FALSE)
+elseif(expectation STREQUAL "should_exist")
+    set(should_exist TRUE)
+else()
+    message(FATAL_ERROR "Encountered unknown expectation: ${expectation}")
+endif()
+
+if(EXISTS "${TARGET_FILE_tool_${config}}")
+    if(NOT should_exist)
+        message(FATAL_ERROR "${TARGET_FILE_tool_${config}} should not exist.")
+    endif()
+else()
+    if(should_exist)
+        message(FATAL_ERROR "${TARGET_FILE_tool_${config}} should exist.")
+    endif()
+endif()
diff --git a/Tests/RunCMake/ExcludeFromAll/single-config.cmake b/Tests/RunCMake/ExcludeFromAll/single-config.cmake
new file mode 100644
index 0000000..aa49c21
--- /dev/null
+++ b/Tests/RunCMake/ExcludeFromAll/single-config.cmake
@@ -0,0 +1,7 @@
+enable_language(C)
+add_executable(tool main.c)
+set_property(TARGET tool PROPERTY EXCLUDE_FROM_ALL "${TOOL_EXCLUDE_FROM_ALL}")
+
+file(GENERATE OUTPUT "${CMAKE_BINARY_DIR}/target_files_$<CONFIG>.cmake" CONTENT [[
+set(TARGET_FILE_tool_$<CONFIG> [==[$<TARGET_FILE:tool>]==])
+]])
diff --git a/Tests/RunCMake/ExportWithoutLanguage/CMakeLists.txt b/Tests/RunCMake/ExportWithoutLanguage/CMakeLists.txt
index 12cd3c7..74b3ff8 100644
--- a/Tests/RunCMake/ExportWithoutLanguage/CMakeLists.txt
+++ b/Tests/RunCMake/ExportWithoutLanguage/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/ExternalData/CMakeLists.txt b/Tests/RunCMake/ExternalData/CMakeLists.txt
index 12cd3c7..74b3ff8 100644
--- a/Tests/RunCMake/ExternalData/CMakeLists.txt
+++ b/Tests/RunCMake/ExternalData/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/FPHSA/CMakeLists.txt b/Tests/RunCMake/FPHSA/CMakeLists.txt
index 12cd3c7..74b3ff8 100644
--- a/Tests/RunCMake/FPHSA/CMakeLists.txt
+++ b/Tests/RunCMake/FPHSA/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/FeatureSummary/CMakeLists.txt b/Tests/RunCMake/FeatureSummary/CMakeLists.txt
index 72abfc8..74b3ff8 100644
--- a/Tests/RunCMake/FeatureSummary/CMakeLists.txt
+++ b/Tests/RunCMake/FeatureSummary/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.11)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-check.py b/Tests/RunCMake/FileAPI/codemodel-v2-check.py
index a3dd9ff..c66757f 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-check.py
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-check.py
@@ -12,7 +12,7 @@
 def check_objects(o, g):
     assert is_list(o)
     assert len(o) == 1
-    check_index_object(o[0], "codemodel", 2, 1, check_object_codemodel(g))
+    check_index_object(o[0], "codemodel", 2, 2, check_object_codemodel(g))
 
 def check_backtrace(t, b, backtrace):
     btg = t["backtraceGraph"]
@@ -42,6 +42,16 @@
 
     assert b is None
 
+def check_backtraces(t, actual, expected):
+    assert is_list(actual)
+    assert is_list(expected)
+    assert len(actual) == len(expected)
+
+    i = 0
+    while i < len(actual):
+        check_backtrace(t, actual[i], expected[i])
+        i += 1
+
 def check_directory(c):
     def _check(actual, expected):
         assert is_dict(actual)
@@ -421,6 +431,19 @@
                                      missing_exception=lambda e: "Precompile header: %s" % e["header"],
                                      extra_exception=lambda a: "Precompile header: %s" % a["header"])
 
+                if "languageStandard" in expected:
+                    expected_keys.append("languageStandard")
+
+                    def check_language_standard(actual, expected):
+                        assert is_dict(actual)
+                        expected_keys = ["backtraces", "standard"]
+                        assert actual["standard"] == expected["standard"]
+                        check_backtraces(obj, actual["backtraces"], expected["backtraces"])
+
+                        assert sorted(actual.keys()) == sorted(expected_keys)
+
+                    check_language_standard(actual["languageStandard"], expected["languageStandard"])
+
                 if expected["defines"] is not None:
                     expected_keys.append("defines")
 
@@ -499,6 +522,7 @@
         read_codemodel_json_data("directories/custom.json"),
         read_codemodel_json_data("directories/cxx.json"),
         read_codemodel_json_data("directories/imported.json"),
+        read_codemodel_json_data("directories/interface.json"),
         read_codemodel_json_data("directories/object.json"),
         read_codemodel_json_data("directories/dir.json"),
         read_codemodel_json_data("directories/dir_dir.json"),
@@ -544,6 +568,8 @@
         read_codemodel_json_data("targets/zero_check_cxx.json"),
         read_codemodel_json_data("targets/cxx_lib.json"),
         read_codemodel_json_data("targets/cxx_exe.json"),
+        read_codemodel_json_data("targets/cxx_standard_compile_feature_exe.json"),
+        read_codemodel_json_data("targets/cxx_standard_exe.json"),
         read_codemodel_json_data("targets/cxx_shared_lib.json"),
         read_codemodel_json_data("targets/cxx_shared_exe.json"),
         read_codemodel_json_data("targets/cxx_static_lib.json"),
@@ -569,6 +595,10 @@
         read_codemodel_json_data("targets/link_imported_object_exe.json"),
         read_codemodel_json_data("targets/link_imported_interface_exe.json"),
 
+        read_codemodel_json_data("targets/all_build_interface.json"),
+        read_codemodel_json_data("targets/zero_check_interface.json"),
+        read_codemodel_json_data("targets/iface_srcs.json"),
+
         read_codemodel_json_data("targets/all_build_custom.json"),
         read_codemodel_json_data("targets/zero_check_custom.json"),
         read_codemodel_json_data("targets/custom_tgt.json"),
@@ -592,6 +622,12 @@
                 e["sources"] = precompile_header_data["sources"]
                 e["sourceGroups"] = precompile_header_data["sourceGroups"]
 
+    if os.path.exists(os.path.join(reply_dir, "..", "..", "..", "..", "cxx", "cxx_std_11.txt")):
+        for e in expected:
+            if e["name"] == "cxx_standard_compile_feature_exe":
+                language_standard_data = read_codemodel_json_data("targets/cxx_standard_compile_feature_exe_languagestandard.json")
+                e["compileGroups"][0]["languageStandard"] = language_standard_data["languageStandard"]
+
     if not os.path.exists(os.path.join(reply_dir, "..", "..", "..", "..", "ipo_enabled.txt")):
         for e in expected:
             try:
@@ -691,6 +727,7 @@
         read_codemodel_json_data("projects/alias.json"),
         read_codemodel_json_data("projects/object.json"),
         read_codemodel_json_data("projects/imported.json"),
+        read_codemodel_json_data("projects/interface.json"),
         read_codemodel_json_data("projects/custom.json"),
         read_codemodel_json_data("projects/external.json"),
     ]
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/cxx.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/cxx.json
index ebe717a..a51b6eb 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/cxx.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/cxx.json
@@ -7,6 +7,8 @@
         "^ALL_BUILD::@a56b12a3f5c0529fb296$",
         "^ZERO_CHECK::@a56b12a3f5c0529fb296$",
         "^cxx_exe::@a56b12a3f5c0529fb296$",
+        "^cxx_standard_compile_feature_exe::@a56b12a3f5c0529fb296$",
+        "^cxx_standard_exe::@a56b12a3f5c0529fb296$",
         "^cxx_lib::@a56b12a3f5c0529fb296$",
         "^cxx_shared_exe::@a56b12a3f5c0529fb296$",
         "^cxx_shared_lib::@a56b12a3f5c0529fb296$",
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/interface.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/interface.json
new file mode 100644
index 0000000..b10d496
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/interface.json
@@ -0,0 +1,14 @@
+{
+    "source": "^interface$",
+    "build": "^interface$",
+    "parentSource": "^\\.$",
+    "childSources": null,
+    "targetIds": [
+        "^ALL_BUILD::@25b7fa8ea00134654b85$",
+        "^ZERO_CHECK::@25b7fa8ea00134654b85$",
+        "^iface_srcs::@25b7fa8ea00134654b85$"
+    ],
+    "projectName": "Interface",
+    "minimumCMakeVersion": "3.12",
+    "hasInstallRule": null
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/top.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/top.json
index c144953..736d1f5 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/top.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/top.json
@@ -7,6 +7,7 @@
         "^custom$",
         "^cxx$",
         "^imported$",
+        "^interface$",
         "^object$",
         "^.*/Tests/RunCMake/FileAPIExternalSource$",
         "^dir$"
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/codemodel-v2.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/codemodel-v2.json
index f3aac63..4d0cdc0 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/codemodel-v2.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/codemodel-v2.json
@@ -6,6 +6,7 @@
         "Custom",
         "Cxx",
         "Imported",
+        "Interface",
         "Object",
         "External"
     ],
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/cxx.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/cxx.json
index 296ae6c..363e853 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/cxx.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/cxx.json
@@ -10,6 +10,8 @@
         "^ZERO_CHECK::@a56b12a3f5c0529fb296$",
         "^cxx_lib::@a56b12a3f5c0529fb296$",
         "^cxx_exe::@a56b12a3f5c0529fb296$",
+        "^cxx_standard_compile_feature_exe::@a56b12a3f5c0529fb296$",
+        "^cxx_standard_exe::@a56b12a3f5c0529fb296$",
         "^cxx_shared_lib::@a56b12a3f5c0529fb296$",
         "^cxx_shared_exe::@a56b12a3f5c0529fb296$",
         "^cxx_static_lib::@a56b12a3f5c0529fb296$",
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/interface.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/interface.json
new file mode 100644
index 0000000..2a22767
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/interface.json
@@ -0,0 +1,13 @@
+{
+    "name": "Interface",
+    "parentName": "codemodel-v2",
+    "childNames": null,
+    "directorySources": [
+        "^interface$"
+    ],
+    "targetIds": [
+        "^ALL_BUILD::@25b7fa8ea00134654b85$",
+        "^ZERO_CHECK::@25b7fa8ea00134654b85$",
+        "^iface_srcs::@25b7fa8ea00134654b85$"
+    ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_cxx.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_cxx.json
index 92a7944..1f443b1 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_cxx.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_cxx.json
@@ -80,6 +80,14 @@
             "backtrace": null
         },
         {
+            "id": "^cxx_standard_compile_feature_exe::@a56b12a3f5c0529fb296$",
+            "backtrace": null
+        },
+        {
+            "id": "^cxx_standard_exe::@a56b12a3f5c0529fb296$",
+            "backtrace": null
+        },
+        {
             "id": "^cxx_shared_lib::@a56b12a3f5c0529fb296$",
             "backtrace": null
         },
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_interface.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_interface.json
new file mode 100644
index 0000000..fa2a6e5
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_interface.json
@@ -0,0 +1,79 @@
+{
+    "name": "ALL_BUILD",
+    "id": "^ALL_BUILD::@25b7fa8ea00134654b85$",
+    "directorySource": "^interface$",
+    "projectName": "Interface",
+    "type": "UTILITY",
+    "isGeneratorProvided": true,
+    "sources": [
+        {
+            "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/interface/CMakeFiles/ALL_BUILD$",
+            "isGenerated": true,
+            "sourceGroupName": "",
+            "compileGroupLanguage": null,
+            "backtrace": [
+                {
+                    "file": "^interface/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        },
+        {
+            "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/interface/CMakeFiles/ALL_BUILD\\.rule$",
+            "isGenerated": true,
+            "sourceGroupName": "CMake Rules",
+            "compileGroupLanguage": null,
+            "backtrace": [
+                {
+                    "file": "^interface/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        }
+    ],
+    "sourceGroups": [
+        {
+            "name": "",
+            "sourcePaths": [
+                "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/interface/CMakeFiles/ALL_BUILD$"
+            ]
+        },
+        {
+            "name": "CMake Rules",
+            "sourcePaths": [
+                "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/interface/CMakeFiles/ALL_BUILD\\.rule$"
+            ]
+        }
+    ],
+    "compileGroups": null,
+    "backtrace": [
+        {
+            "file": "^interface/CMakeLists\\.txt$",
+            "line": null,
+            "command": null,
+            "hasParent": false
+        }
+    ],
+    "folder": null,
+    "nameOnDisk": null,
+    "artifacts": null,
+    "build": "^interface$",
+    "source": "^interface$",
+    "install": null,
+    "link": null,
+    "archive": null,
+    "dependencies": [
+        {
+            "id": "^ZERO_CHECK::@25b7fa8ea00134654b85$",
+            "backtrace": null
+        },
+        {
+            "id": "^iface_srcs::@25b7fa8ea00134654b85$",
+            "backtrace": null
+        }
+    ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_top.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_top.json
index b4def78..d023f99 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_top.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_top.json
@@ -116,6 +116,14 @@
             "backtrace": null
         },
         {
+            "id": "^cxx_standard_compile_feature_exe::@a56b12a3f5c0529fb296$",
+            "backtrace": null
+        },
+        {
+            "id": "^cxx_standard_exe::@a56b12a3f5c0529fb296$",
+            "backtrace": null
+        },
+        {
             "id": "^cxx_shared_lib::@a56b12a3f5c0529fb296$",
             "backtrace": null
         },
@@ -168,6 +176,10 @@
             "backtrace": null
         },
         {
+            "id": "^iface_srcs::@25b7fa8ea00134654b85$",
+            "backtrace": null
+        },
+        {
             "id": "^custom_exe::@c11385ffed57b860da63$",
             "backtrace": null
         },
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe.json
index e7ab55b..c9e652b 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe.json
@@ -119,7 +119,7 @@
                 "backtrace": [
                     {
                         "file": "^codemodel-v2\\.cmake$",
-                        "line": 37,
+                        "line": 38,
                         "command": "install",
                         "hasParent": true
                     },
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_standard_compile_feature_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_standard_compile_feature_exe.json
new file mode 100644
index 0000000..d6d573f
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_standard_compile_feature_exe.json
@@ -0,0 +1,110 @@
+{
+    "name": "cxx_standard_compile_feature_exe",
+    "id": "^cxx_standard_compile_feature_exe::@a56b12a3f5c0529fb296$",
+    "directorySource": "^cxx$",
+    "projectName": "Cxx",
+    "type": "EXECUTABLE",
+    "isGeneratorProvided": null,
+    "sources": [
+        {
+            "path": "^empty\\.cxx$",
+            "isGenerated": null,
+            "sourceGroupName": "Source Files",
+            "compileGroupLanguage": "CXX",
+            "backtrace": [
+                {
+                    "file": "^cxx/CMakeLists\\.txt$",
+                    "line": 26,
+                    "command": "add_executable",
+                    "hasParent": true
+                },
+                {
+                    "file": "^cxx/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        }
+    ],
+    "sourceGroups": [
+        {
+            "name": "Source Files",
+            "sourcePaths": [
+                "^empty\\.cxx$"
+            ]
+        }
+    ],
+    "compileGroups": [
+        {
+            "language": "CXX",
+            "languageStandard" :
+            {
+                "backtraces": [
+                    [
+                        {
+                            "file": "^cxx/CMakeLists\\.txt$",
+                            "line": 27,
+                            "command": "set_property",
+                            "hasParent": true
+                        },
+                        {
+                            "file": "^cxx/CMakeLists\\.txt$",
+                            "line": null,
+                            "command": null,
+                            "hasParent": false
+                        }
+                    ]
+                ],
+                "standard" : "98"
+            },
+            "sourcePaths": [
+                "^empty\\.cxx$"
+            ],
+            "includes": null,
+            "defines": null,
+            "compileCommandFragments": null
+        }
+    ],
+    "backtrace": [
+        {
+            "file": "^cxx/CMakeLists\\.txt$",
+            "line": 26,
+            "command": "add_executable",
+            "hasParent": true
+        },
+        {
+            "file": "^cxx/CMakeLists\\.txt$",
+            "line": null,
+            "command": null,
+            "hasParent": false
+        }
+    ],
+    "folder": null,
+    "nameOnDisk": "^cxx_standard_compile_feature_exe(\\.exe)?$",
+    "artifacts": [
+        {
+            "path": "^cxx/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?cxx_standard_compile_feature_exe(\\.exe)?$",
+            "_dllExtra": false
+        },
+        {
+            "path": "^cxx/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?cxx_standard_compile_feature_exe\\.pdb$",
+            "_dllExtra": true
+        }
+    ],
+    "build": "^cxx$",
+    "source": "^cxx$",
+    "install": null,
+    "link": {
+        "language": "CXX",
+        "lto": null,
+        "commandFragments": null
+    },
+    "archive": null,
+    "dependencies": [
+        {
+            "id": "^ZERO_CHECK::@a56b12a3f5c0529fb296$",
+            "backtrace": null
+        }
+    ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_standard_compile_feature_exe_languagestandard.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_standard_compile_feature_exe_languagestandard.json
new file mode 100644
index 0000000..0c4eabb
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_standard_compile_feature_exe_languagestandard.json
@@ -0,0 +1,36 @@
+{
+    "languageStandard" :
+    {
+      "backtraces": [
+          [
+              {
+                  "file": "^cxx/CMakeLists\\.txt$",
+                  "line": 29,
+                  "command": "target_compile_features",
+                  "hasParent": true
+              },
+              {
+                  "file": "^cxx/CMakeLists\\.txt$",
+                  "line": null,
+                  "command": null,
+                  "hasParent": false
+              }
+          ],
+          [
+              {
+                  "file": "^cxx/CMakeLists\\.txt$",
+                  "line": 30,
+                  "command": "target_compile_features",
+                  "hasParent": true
+              },
+              {
+                  "file": "^cxx/CMakeLists\\.txt$",
+                  "line": null,
+                  "command": null,
+                  "hasParent": false
+              }
+          ]
+      ],
+      "standard" : "11"
+    }
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_standard_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_standard_exe.json
new file mode 100644
index 0000000..9cb2832
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_standard_exe.json
@@ -0,0 +1,110 @@
+{
+    "name": "cxx_standard_exe",
+    "id": "^cxx_standard_exe::@a56b12a3f5c0529fb296$",
+    "directorySource": "^cxx$",
+    "projectName": "Cxx",
+    "type": "EXECUTABLE",
+    "isGeneratorProvided": null,
+    "sources": [
+        {
+            "path": "^empty\\.cxx$",
+            "isGenerated": null,
+            "sourceGroupName": "Source Files",
+            "compileGroupLanguage": "CXX",
+            "backtrace": [
+                {
+                    "file": "^cxx/CMakeLists\\.txt$",
+                    "line": 23,
+                    "command": "add_executable",
+                    "hasParent": true
+                },
+                {
+                    "file": "^cxx/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        }
+    ],
+    "sourceGroups": [
+        {
+            "name": "Source Files",
+            "sourcePaths": [
+                "^empty\\.cxx$"
+            ]
+        }
+    ],
+    "compileGroups": [
+        {
+            "language": "CXX",
+            "languageStandard" :
+            {
+                "backtraces": [
+                    [
+                        {
+                            "file": "^cxx/CMakeLists\\.txt$",
+                            "line": 24,
+                            "command": "set_property",
+                            "hasParent": true
+                        },
+                        {
+                            "file": "^cxx/CMakeLists\\.txt$",
+                            "line": null,
+                            "command": null,
+                            "hasParent": false
+                        }
+                    ]
+                ],
+                "standard" : "17"
+            },
+            "sourcePaths": [
+                "^empty\\.cxx$"
+            ],
+            "includes": null,
+            "defines": null,
+            "compileCommandFragments": null
+        }
+    ],
+    "backtrace": [
+        {
+            "file": "^cxx/CMakeLists\\.txt$",
+            "line": 23,
+            "command": "add_executable",
+            "hasParent": true
+        },
+        {
+            "file": "^cxx/CMakeLists\\.txt$",
+            "line": null,
+            "command": null,
+            "hasParent": false
+        }
+    ],
+    "folder": null,
+    "nameOnDisk": "^cxx_standard_exe(\\.exe)?$",
+    "artifacts": [
+        {
+            "path": "^cxx/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?cxx_standard_exe(\\.exe)?$",
+            "_dllExtra": false
+        },
+        {
+            "path": "^cxx/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?cxx_standard_exe\\.pdb$",
+            "_dllExtra": true
+        }
+    ],
+    "build": "^cxx$",
+    "source": "^cxx$",
+    "install": null,
+    "link": {
+        "language": "CXX",
+        "lto": null,
+        "commandFragments": null
+    },
+    "archive": null,
+    "dependencies": [
+        {
+            "id": "^ZERO_CHECK::@a56b12a3f5c0529fb296$",
+            "backtrace": null
+        }
+    ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/iface_srcs.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/iface_srcs.json
new file mode 100644
index 0000000..97d7ccd
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/iface_srcs.json
@@ -0,0 +1,67 @@
+{
+    "name": "iface_srcs",
+    "id": "^iface_srcs::@25b7fa8ea00134654b85$",
+    "directorySource": "^interface$",
+    "projectName": "Interface",
+    "type": "INTERFACE_LIBRARY",
+    "isGeneratorProvided": null,
+    "sources": [
+        {
+            "path": "^empty\\.c$",
+            "isGenerated": null,
+            "sourceGroupName": "Source Files",
+            "compileGroupLanguage": null,
+            "backtrace": [
+                {
+                    "file": "^interface/CMakeLists\\.txt$",
+                    "line": 3,
+                    "command": "add_library",
+                    "hasParent": true
+                },
+                {
+                    "file": "^interface/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        }
+    ],
+    "sourceGroups": [
+        {
+            "name": "Source Files",
+            "sourcePaths": [
+                "^empty\\.c$"
+            ]
+        }
+    ],
+    "compileGroups": null,
+    "backtrace": [
+        {
+            "file": "^interface/CMakeLists\\.txt$",
+            "line": 3,
+            "command": "add_library",
+            "hasParent": true
+        },
+        {
+            "file": "^interface/CMakeLists\\.txt$",
+            "line": null,
+            "command": null,
+            "hasParent": false
+        }
+    ],
+    "folder": null,
+    "nameOnDisk": null,
+    "artifacts": null,
+    "build": "^interface$",
+    "source": "^interface$",
+    "install": null,
+    "link": null,
+    "archive": null,
+    "dependencies": [
+        {
+            "id": "^ZERO_CHECK::@25b7fa8ea00134654b85$",
+            "backtrace": null
+        }
+    ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_interface.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_interface.json
new file mode 100644
index 0000000..fdd4b2a
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_interface.json
@@ -0,0 +1,70 @@
+{
+    "name": "ZERO_CHECK",
+    "id": "^ZERO_CHECK::@25b7fa8ea00134654b85$",
+    "directorySource": "^interface$",
+    "projectName": "Interface",
+    "type": "UTILITY",
+    "isGeneratorProvided": true,
+    "sources": [
+        {
+            "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/interface/CMakeFiles/ZERO_CHECK$",
+            "isGenerated": true,
+            "sourceGroupName": "",
+            "compileGroupLanguage": null,
+            "backtrace": [
+                {
+                    "file": "^interface/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        },
+        {
+            "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/interface/CMakeFiles/ZERO_CHECK\\.rule$",
+            "isGenerated": true,
+            "sourceGroupName": "CMake Rules",
+            "compileGroupLanguage": null,
+            "backtrace": [
+                {
+                    "file": "^interface/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        }
+    ],
+    "sourceGroups": [
+        {
+            "name": "",
+            "sourcePaths": [
+                "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/interface/CMakeFiles/ZERO_CHECK$"
+            ]
+        },
+        {
+            "name": "CMake Rules",
+            "sourcePaths": [
+                "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/interface/CMakeFiles/ZERO_CHECK\\.rule$"
+            ]
+        }
+    ],
+    "compileGroups": null,
+    "backtrace": [
+        {
+            "file": "^interface/CMakeLists\\.txt$",
+            "line": null,
+            "command": null,
+            "hasParent": false
+        }
+    ],
+    "folder": null,
+    "nameOnDisk": null,
+    "artifacts": null,
+    "build": "^interface$",
+    "source": "^interface$",
+    "install": null,
+    "link": null,
+    "archive": null,
+    "dependencies": null
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2.cmake b/Tests/RunCMake/FileAPI/codemodel-v2.cmake
index c98a84c..2405954 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2.cmake
+++ b/Tests/RunCMake/FileAPI/codemodel-v2.cmake
@@ -18,6 +18,7 @@
 add_subdirectory(alias)
 add_subdirectory(object)
 add_subdirectory(imported)
+add_subdirectory(interface)
 add_subdirectory(custom)
 add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/../FileAPIExternalSource" "${CMAKE_CURRENT_BINARY_DIR}/../FileAPIExternalBuild")
 add_subdirectory(dir)
diff --git a/Tests/RunCMake/FileAPI/cxx/CMakeLists.txt b/Tests/RunCMake/FileAPI/cxx/CMakeLists.txt
index fa51195..76235f5 100644
--- a/Tests/RunCMake/FileAPI/cxx/CMakeLists.txt
+++ b/Tests/RunCMake/FileAPI/cxx/CMakeLists.txt
@@ -19,3 +19,14 @@
 target_link_directories(cxx_exe PUBLIC "${CMAKE_BINARY_DIR}/TargetLinkDir")
 
 target_precompile_headers(cxx_exe PUBLIC ../empty.h)
+
+add_executable(cxx_standard_exe ../empty.cxx)
+set_property(TARGET cxx_standard_exe PROPERTY CXX_STANDARD 17)
+
+add_executable(cxx_standard_compile_feature_exe ../empty.cxx)
+set_property(TARGET cxx_standard_compile_feature_exe PROPERTY CXX_STANDARD 98)
+if(CMAKE_CXX_STANDARD_DEFAULT AND DEFINED CMAKE_CXX11_STANDARD_COMPILE_OPTION)
+  target_compile_features(cxx_standard_compile_feature_exe PRIVATE cxx_std_11)
+  target_compile_features(cxx_standard_compile_feature_exe PRIVATE cxx_decltype)
+  file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/cxx_std_11.txt" "")
+endif()
diff --git a/Tests/RunCMake/FileAPI/interface/CMakeLists.txt b/Tests/RunCMake/FileAPI/interface/CMakeLists.txt
new file mode 100644
index 0000000..97948c5
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/interface/CMakeLists.txt
@@ -0,0 +1,3 @@
+project(Interface)
+add_library(iface_none INTERFACE)
+add_library(iface_srcs INTERFACE ../empty.c)
diff --git a/Tests/RunCMake/File_Generate/AdjacentInOut.cmake b/Tests/RunCMake/File_Generate/AdjacentInOut.cmake
new file mode 100644
index 0000000..828c2ee
--- /dev/null
+++ b/Tests/RunCMake/File_Generate/AdjacentInOut.cmake
@@ -0,0 +1,6 @@
+cmake_policy(SET CMP0070 NEW)
+if(EXISTS "${CMAKE_CURRENT_BINARY_DIR}/AdjacentInOut.txt")
+  message(FATAL_ERROR "CMake should not re-run during the build!")
+endif()
+configure_file(AdjacentInOut.in ${CMAKE_CURRENT_BINARY_DIR}/AdjacentInOut.txt.tmp)
+file(GENERATE OUTPUT AdjacentInOut.txt INPUT ${CMAKE_CURRENT_BINARY_DIR}/AdjacentInOut.txt.tmp)
diff --git a/Tests/RunCMake/File_Generate/AdjacentInOut.in b/Tests/RunCMake/File_Generate/AdjacentInOut.in
new file mode 100644
index 0000000..bfbbda7
--- /dev/null
+++ b/Tests/RunCMake/File_Generate/AdjacentInOut.in
@@ -0,0 +1 @@
+Sample Text File
diff --git a/Tests/RunCMake/File_Generate/CMakeLists.txt b/Tests/RunCMake/File_Generate/CMakeLists.txt
index bc0cf5d..3178de5 100644
--- a/Tests/RunCMake/File_Generate/CMakeLists.txt
+++ b/Tests/RunCMake/File_Generate/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} NONE)
 if(NOT TEST_FILE)
   set(TEST_FILE ${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/File_Generate/RunCMakeTest.cmake b/Tests/RunCMake/File_Generate/RunCMakeTest.cmake
index 94aaca8..5987417 100644
--- a/Tests/RunCMake/File_Generate/RunCMakeTest.cmake
+++ b/Tests/RunCMake/File_Generate/RunCMakeTest.cmake
@@ -72,6 +72,7 @@
   if (NOT script_output STREQUAL SUCCESS)
     message(SEND_ERROR "Generated script did not execute correctly:\n${script_output}\n====\n${script_error}")
   endif()
+  unset(RunCMake_TEST_NO_CLEAN)
 endif()
 
 if (RunCMake_GENERATOR MATCHES Makefiles)
@@ -104,3 +105,10 @@
     message(SEND_ERROR "File did not re-generate: \"${RunCMake_BINARY_DIR}/ReRunCMake-build/output_file.txt\"")
   endif()
 endif()
+
+set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/AdjacentInOut-build)
+run_cmake(AdjacentInOut)
+set(RunCMake_TEST_NO_CLEAN 1)
+run_cmake_command(AdjacentInOut-nowork ${CMAKE_COMMAND} --build .)
+unset(RunCMake_TEST_BINARY_DIR)
+unset(RunCMake_TEST_NO_CLEAN)
diff --git a/Tests/RunCMake/FindOpenGL/CMP0072-OLD-stderr.txt b/Tests/RunCMake/FindOpenGL/CMP0072-OLD-stderr.txt
new file mode 100644
index 0000000..68d23d4
--- /dev/null
+++ b/Tests/RunCMake/FindOpenGL/CMP0072-OLD-stderr.txt
@@ -0,0 +1,10 @@
+^CMake Deprecation Warning at CMP0072-OLD.cmake:1 \(cmake_policy\):
+  The OLD behavior for policy CMP0072 will be removed from a future version
+  of CMake.
+
+  The cmake-policies\(7\) manual explains that the OLD behaviors of all
+  policies are deprecated and that a policy should be set to OLD only under
+  specific short-term circumstances.  Projects should be ported to the NEW
+  behavior and not rely on setting a policy to OLD.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/FindPkgConfig/CMakeLists.txt b/Tests/RunCMake/FindPkgConfig/CMakeLists.txt
index 72abfc8..74b3ff8 100644
--- a/Tests/RunCMake/FindPkgConfig/CMakeLists.txt
+++ b/Tests/RunCMake/FindPkgConfig/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.11)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/FindPkgConfig/FindPkgConfig_GET_MATCHING_MODULE_NAME.cmake b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_GET_MATCHING_MODULE_NAME.cmake
index fc3a766..aa293d5 100644
--- a/Tests/RunCMake/FindPkgConfig/FindPkgConfig_GET_MATCHING_MODULE_NAME.cmake
+++ b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_GET_MATCHING_MODULE_NAME.cmake
@@ -20,7 +20,7 @@
 
 unset(FOO_MODULE_NAME)
 
-# verify variable get's also set on subsequent run
+# verify variable gets also set on subsequent run
 pkg_search_module(FOO REQUIRED foo bletch bar)
 
 if(NOT FOO_MODULE_NAME STREQUAL "bletch")
diff --git a/Tests/RunCMake/GenEx-COMPILE_LANGUAGE/COMPILE_LANGUAGE-TARGET_PROPERTY.cmake b/Tests/RunCMake/GenEx-COMPILE_LANGUAGE/COMPILE_LANGUAGE-TARGET_PROPERTY.cmake
new file mode 100644
index 0000000..293ddda
--- /dev/null
+++ b/Tests/RunCMake/GenEx-COMPILE_LANGUAGE/COMPILE_LANGUAGE-TARGET_PROPERTY.cmake
@@ -0,0 +1,17 @@
+enable_language(C)
+
+add_library (lib SHARED empty.c)
+set_target_properties(lib PROPERTIES
+  INCLUDE_DIRECTORIES "$<$<COMPILE_LANGUAGE:C>:/usr/include>"
+  COMPILE_DEFINITIONS "$<$<COMPILE_LANGUAGE:C>:DEF>"
+  COMPILE_OPTIONS "$<$<COMPILE_LANGUAGE:C>:-O>")
+
+add_custom_target(drive
+  COMMAND ${CMAKE_COMMAND} -E echo $<TARGET_PROPERTY:lib,INCLUDE_DIRECTORIES>
+                                   $<TARGET_PROPERTY:lib,COMPILE_DEFINITIONS>
+                                   $<TARGET_PROPERTY:lib,COMPILE_OPTIONS>)
+
+add_custom_command(TARGET drive PRE_BUILD
+  COMMAND ${CMAKE_COMMAND} -E echo $<TARGET_PROPERTY:lib,INCLUDE_DIRECTORIES>
+                                   $<TARGET_PROPERTY:lib,COMPILE_DEFINITIONS>
+                                   $<TARGET_PROPERTY:lib,COMPILE_OPTIONS>)
diff --git a/Tests/RunCMake/GenEx-COMPILE_LANGUAGE/RunCMakeTest.cmake b/Tests/RunCMake/GenEx-COMPILE_LANGUAGE/RunCMakeTest.cmake
index 6691fdf..15a5e79 100644
--- a/Tests/RunCMake/GenEx-COMPILE_LANGUAGE/RunCMakeTest.cmake
+++ b/Tests/RunCMake/GenEx-COMPILE_LANGUAGE/RunCMakeTest.cmake
@@ -8,3 +8,4 @@
 run_cmake(COMPILE_LANGUAGE-add_library)
 run_cmake(COMPILE_LANGUAGE-add_test)
 run_cmake(COMPILE_LANGUAGE-unknown-lang)
+run_cmake(COMPILE_LANGUAGE-TARGET_PROPERTY)
diff --git a/Tests/RunCMake/GenEx-COMPILE_LANG_AND_ID/COMPILE_LANG_AND_ID-TARGET_PROPERTY.cmake b/Tests/RunCMake/GenEx-COMPILE_LANG_AND_ID/COMPILE_LANG_AND_ID-TARGET_PROPERTY.cmake
new file mode 100644
index 0000000..6a718d6
--- /dev/null
+++ b/Tests/RunCMake/GenEx-COMPILE_LANG_AND_ID/COMPILE_LANG_AND_ID-TARGET_PROPERTY.cmake
@@ -0,0 +1,17 @@
+enable_language(C)
+
+add_library (lib SHARED empty.c)
+set_target_properties(lib PROPERTIES
+  INCLUDE_DIRECTORIES "$<$<COMPILE_LANG_AND_ID:C,GNU>:/usr/include>"
+  COMPILE_DEFINITIONS "$<$<COMPILE_LANG_AND_ID:C,GNU>:DEF>"
+  COMPILE_OPTIONS "$<$<COMPILE_LANG_AND_ID:C,GNU>:-O>")
+
+add_custom_target(drive
+  COMMAND ${CMAKE_COMMAND} -E echo $<TARGET_PROPERTY:lib,INCLUDE_DIRECTORIES>
+                                   $<TARGET_PROPERTY:lib,COMPILE_DEFINITIONS>
+                                   $<TARGET_PROPERTY:lib,COMPILE_OPTIONS>)
+
+add_custom_command(TARGET drive PRE_BUILD
+  COMMAND ${CMAKE_COMMAND} -E echo $<TARGET_PROPERTY:lib,INCLUDE_DIRECTORIES>
+                                   $<TARGET_PROPERTY:lib,COMPILE_DEFINITIONS>
+                                   $<TARGET_PROPERTY:lib,COMPILE_OPTIONS>)
diff --git a/Tests/RunCMake/GenEx-COMPILE_LANG_AND_ID/RunCMakeTest.cmake b/Tests/RunCMake/GenEx-COMPILE_LANG_AND_ID/RunCMakeTest.cmake
index a0a7bb9..68bd05d 100644
--- a/Tests/RunCMake/GenEx-COMPILE_LANG_AND_ID/RunCMakeTest.cmake
+++ b/Tests/RunCMake/GenEx-COMPILE_LANG_AND_ID/RunCMakeTest.cmake
@@ -8,3 +8,4 @@
 run_cmake(COMPILE_LANG_AND_ID-add_library)
 run_cmake(COMPILE_LANG_AND_ID-add_test)
 run_cmake(COMPILE_LANG_AND_ID-unknown-lang)
+run_cmake(COMPILE_LANG_AND_ID-TARGET_PROPERTY)
diff --git a/Tests/RunCMake/GenerateExportHeader/RunCMakeTest.cmake b/Tests/RunCMake/GenerateExportHeader/RunCMakeTest.cmake
index b3977f1..5a5a7bf 100644
--- a/Tests/RunCMake/GenerateExportHeader/RunCMakeTest.cmake
+++ b/Tests/RunCMake/GenerateExportHeader/RunCMakeTest.cmake
@@ -26,7 +26,7 @@
   endforeach()
 endfunction()
 
-# remove these flags from the enviornment if they have been set
+# remove these flags from the environment if they have been set
 # so the tests run the correct env
 set(env_cxx_flags $ENV{CXXFLAGS})
 if(env_cxx_flags)
diff --git a/Tests/RunCMake/GeneratorExpression/BadCONFIG-stderr.txt b/Tests/RunCMake/GeneratorExpression/BadCONFIG-stderr.txt
index 42dd0ce..130de2b 100644
--- a/Tests/RunCMake/GeneratorExpression/BadCONFIG-stderr.txt
+++ b/Tests/RunCMake/GeneratorExpression/BadCONFIG-stderr.txt
@@ -10,15 +10,6 @@
 CMake Error at BadCONFIG.cmake:1 \(add_custom_target\):
   Error evaluating generator expression:
 
-    \$<CONFIG:Foo,Bar>
-
-  \$<CONFIG> expression requires one or zero parameters.
-Call Stack \(most recent call first\):
-  CMakeLists.txt:3 \(include\)
-+
-CMake Error at BadCONFIG.cmake:1 \(add_custom_target\):
-  Error evaluating generator expression:
-
     \$<CONFIG:Foo-Bar>
 
   Expression syntax not recognized.
diff --git a/Tests/RunCMake/GeneratorExpression/BadCONFIG.cmake b/Tests/RunCMake/GeneratorExpression/BadCONFIG.cmake
index 5c22aaa..1735ab7 100644
--- a/Tests/RunCMake/GeneratorExpression/BadCONFIG.cmake
+++ b/Tests/RunCMake/GeneratorExpression/BadCONFIG.cmake
@@ -1,6 +1,5 @@
 add_custom_target(check ALL COMMAND check
   $<CONFIG:.>
-  $<CONFIG:Foo,Bar>
   $<CONFIG:Foo-Bar>
   $<$<CONFIG:Foo-Nested>:foo>
   VERBATIM)
diff --git a/Tests/RunCMake/GeneratorExpression/CMakeLists.txt b/Tests/RunCMake/GeneratorExpression/CMakeLists.txt
index 12cd3c7..4b3de84 100644
--- a/Tests/RunCMake/GeneratorExpression/CMakeLists.txt
+++ b/Tests/RunCMake/GeneratorExpression/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 2.8.12)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/GeneratorExpression/CONFIG-empty-entries-check.cmake b/Tests/RunCMake/GeneratorExpression/CONFIG-empty-entries-check.cmake
new file mode 100644
index 0000000..b43256b
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/CONFIG-empty-entries-check.cmake
@@ -0,0 +1,6 @@
+file(READ "${RunCMake_TEST_BINARY_DIR}/CONFIG-empty-entries-generated.txt" content)
+
+set(expected "1234")
+if(NOT content STREQUAL expected)
+  set(RunCMake_TEST_FAILED "actual content:\n [[${content}]]\nbut expected:\n [[${expected}]]")
+endif()
diff --git a/Tests/RunCMake/GeneratorExpression/CONFIG-empty-entries.cmake b/Tests/RunCMake/GeneratorExpression/CONFIG-empty-entries.cmake
new file mode 100644
index 0000000..a4d53f9
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/CONFIG-empty-entries.cmake
@@ -0,0 +1,9 @@
+cmake_policy(SET CMP0070 NEW)
+
+set(text)
+string(APPEND text "$<$<CONFIG:>:1>")
+string(APPEND text "$<$<CONFIG:Release,>:2>")
+string(APPEND text "$<$<CONFIG:,Release>:3>")
+string(APPEND text "$<$<CONFIG:Release,,Debug>:4>")
+string(APPEND text "$<$<CONFIG:Release,Debug>:5>")
+file(GENERATE OUTPUT CONFIG-empty-entries-generated.txt CONTENT  ${text})
diff --git a/Tests/RunCMake/GeneratorExpression/CONFIG-multiple-entries-check.cmake b/Tests/RunCMake/GeneratorExpression/CONFIG-multiple-entries-check.cmake
new file mode 100644
index 0000000..66f42c7
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/CONFIG-multiple-entries-check.cmake
@@ -0,0 +1,6 @@
+file(READ "${RunCMake_TEST_BINARY_DIR}/CONFIG-multiple-entries-generated.txt" content)
+
+set(expected "14")
+if(NOT content STREQUAL expected)
+  set(RunCMake_TEST_FAILED "actual content:\n [[${content}]]\nbut expected:\n [[${expected}]]")
+endif()
diff --git a/Tests/RunCMake/GeneratorExpression/CONFIG-multiple-entries.cmake b/Tests/RunCMake/GeneratorExpression/CONFIG-multiple-entries.cmake
new file mode 100644
index 0000000..6829282
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/CONFIG-multiple-entries.cmake
@@ -0,0 +1,8 @@
+cmake_policy(SET CMP0070 NEW)
+
+set(text)
+string(APPEND text "$<$<CONFIG:CustomConfig>:1>")
+string(APPEND text "$<$<CONFIG:Release>:2>")
+string(APPEND text "$<$<CONFIG:Debug,Release>:3>")
+string(APPEND text "$<$<CONFIG:Release,CustomConfig,Debug>:4>")
+file(GENERATE OUTPUT CONFIG-multiple-entries-generated.txt CONTENT "${text}")
diff --git a/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake b/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake
index 0278cf6..6349112 100644
--- a/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake
+++ b/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake
@@ -12,6 +12,7 @@
 run_cmake(BadTargetTypeObject)
 run_cmake(BadInstallPrefix)
 run_cmake(BadSHELL_PATH)
+run_cmake(BadCONFIG)
 run_cmake(CMP0044-WARN)
 run_cmake(NonValidTarget-C_COMPILER_ID)
 run_cmake(NonValidTarget-CXX_COMPILER_ID)
@@ -44,6 +45,19 @@
 run_cmake(FILTER-Exclude)
 run_cmake(FILTER-Include)
 
+if(RunCMake_GENERATOR_IS_MULTI_CONFIG)
+  set(RunCMake_TEST_OPTIONS [==[-DCMAKE_CONFIGURATION_TYPES=CustomConfig]==])
+else()
+  set(RunCMake_TEST_OPTIONS [==[-DCMAKE_BUILD_TYPE=CustomConfig]==])
+endif()
+run_cmake(CONFIG-multiple-entries)
+if(RunCMake_GENERATOR_IS_MULTI_CONFIG)
+  set(RunCMake_TEST_OPTIONS [==[-DCMAKE_CONFIGURATION_TYPES=]==])
+else()
+  set(RunCMake_TEST_OPTIONS [==[-DCMAKE_BUILD_TYPE=]==])
+endif()
+run_cmake(CONFIG-empty-entries)
+
 set(RunCMake_TEST_OPTIONS -DCMAKE_POLICY_DEFAULT_CMP0085:STRING=OLD)
 run_cmake(CMP0085-OLD)
 unset(RunCMake_TEST_OPTIONS)
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_PROPERTY-INCLUDE_DIRECTORIES-check.cmake b/Tests/RunCMake/GeneratorExpression/TARGET_PROPERTY-INCLUDE_DIRECTORIES-check.cmake
new file mode 100644
index 0000000..ecf7bfe
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/TARGET_PROPERTY-INCLUDE_DIRECTORIES-check.cmake
@@ -0,0 +1,17 @@
+file(READ "${RunCMake_TEST_BINARY_DIR}/out.txt" content)
+
+unset(RunCMake_TEST_FAILED)
+
+if (NOT content MATCHES "(INCLUDES1:${RunCMake_TEST_SOURCE_DIR}/include)")
+  string(APPEND RunCMake_TEST_FAILED "wrong content for INCLUDES1: \"${CMAKE_MATCH_1}\"\n")
+endif()
+
+if (NOT content MATCHES "(INCLUDES2:><)")
+  string(APPEND RunCMake_TEST_FAILED "wrong content for INCLUDES2: \"${CMAKE_MATCH_1}\"\n")
+endif()
+if (NOT content MATCHES "(INCLUDES3:><)")
+  string(APPEND RunCMake_TEST_FAILED "wrong content for INCLUDES3: \"${CMAKE_MATCH_1}\"\n")
+endif()
+if (NOT content MATCHES "(CUSTOM:>;;<)")
+  string(APPEND RunCMake_TEST_FAILED "wrong content for CUSTOM: \"${CMAKE_MATCH_1}\"\n")
+endif()
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_PROPERTY-INCLUDE_DIRECTORIES.cmake b/Tests/RunCMake/GeneratorExpression/TARGET_PROPERTY-INCLUDE_DIRECTORIES.cmake
index cb6f4d8..e9855be 100644
--- a/Tests/RunCMake/GeneratorExpression/TARGET_PROPERTY-INCLUDE_DIRECTORIES.cmake
+++ b/Tests/RunCMake/GeneratorExpression/TARGET_PROPERTY-INCLUDE_DIRECTORIES.cmake
@@ -14,5 +14,10 @@
 add_library(foo4 STATIC empty.c)
 target_include_directories(foo4 PUBLIC $<TARGET_PROPERTY:foo3,INCLUDE_DIRECTORIES>)
 
+add_library (foo5 SHARED empty.c)
+set_property(TARGET foo5 PROPERTY INCLUDE_DIRECTORIES "$<$<COMPILE_LANGUAGE:CUDA>:/include/CUDA>" "$<$<COMPILE_LANGUAGE:Fortran>:/include/Fortran>")
+set_property(TARGET foo5 PROPERTY INTERFACE_INCLUDE_DIRECTORIES "$<$<COMPILE_LANGUAGE:CUDA>:/include/CUDA>" "$<$<COMPILE_LANGUAGE:Fortran>:/include/Fortran>")
+set_property(TARGET foo5 PROPERTY CUSTOM ";;")
+
 # Evaluate a genex that looks up INCLUDE_DIRECTORIES on multiple targets.
-file(GENERATE OUTPUT out.txt CONTENT "$<TARGET_PROPERTY:foo4,INCLUDE_DIRECTORIES>")
+file(GENERATE OUTPUT out.txt CONTENT "INCLUDES1:$<TARGET_PROPERTY:foo4,INCLUDE_DIRECTORIES>\nINCLUDES2:>$<TARGET_PROPERTY:foo5,INTERFACE_INCLUDE_DIRECTORIES><\nINCLUDES3:>$<TARGET_PROPERTY:foo5,INCLUDE_DIRECTORIES><\nCUSTOM:>$<TARGET_PROPERTY:foo5,CUSTOM><\n")
diff --git a/Tests/RunCMake/GeneratorPlatform/CMakeLists.txt b/Tests/RunCMake/GeneratorPlatform/CMakeLists.txt
index 12cd3c7..74b3ff8 100644
--- a/Tests/RunCMake/GeneratorPlatform/CMakeLists.txt
+++ b/Tests/RunCMake/GeneratorPlatform/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/GeneratorToolset/CMakeLists.txt b/Tests/RunCMake/GeneratorToolset/CMakeLists.txt
index 12cd3c7..74b3ff8 100644
--- a/Tests/RunCMake/GeneratorToolset/CMakeLists.txt
+++ b/Tests/RunCMake/GeneratorToolset/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/GoogleTest/GoogleTestXML-special-result-check.cmake b/Tests/RunCMake/GoogleTest/GoogleTestXML-special-result-check.cmake
new file mode 100644
index 0000000..fea0a6b
--- /dev/null
+++ b/Tests/RunCMake/GoogleTest/GoogleTestXML-special-result-check.cmake
@@ -0,0 +1,28 @@
+set(RESULT_FILES
+  "${RunCMake_TEST_BINARY_DIR}/GoogleTestXMLSpecial/cases.case/0.xml"
+  "${RunCMake_TEST_BINARY_DIR}/GoogleTestXMLSpecial/cases.case/1.xml"
+  "${RunCMake_TEST_BINARY_DIR}/GoogleTestXMLSpecial/cases.case/2.xml"
+)
+
+# Check result files exist
+foreach(file ${RESULT_FILES})
+  if(NOT EXISTS ${file})
+    if(NOT ${RunCMake_TEST_FAILED} STREQUAL "")
+      set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}\n")
+    endif()
+    set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}Result XML file ${file} was not created")
+  endif()
+endforeach()
+
+# and no other xml files are created
+file(GLOB_RECURSE file_list "${RunCMake_TEST_BINARY_DIR}/GoogleTestXMLSpecial/*/*.xml" LIST_DIRECTORIES false)
+
+foreach(file ${file_list})
+  list(FIND RESULT_FILES "${file}" idx)
+  if(-1 EQUAL ${idx})
+    if(NOT ${RunCMake_TEST_FAILED} STREQUAL "")
+      set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}\n")
+    endif()
+    set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}Invalid file ${file} was created")
+  endif()
+endforeach()
diff --git a/Tests/RunCMake/GoogleTest/GoogleTestXML.cmake b/Tests/RunCMake/GoogleTest/GoogleTestXML.cmake
index 29bd05e..fb91c0e 100644
--- a/Tests/RunCMake/GoogleTest/GoogleTestXML.cmake
+++ b/Tests/RunCMake/GoogleTest/GoogleTestXML.cmake
@@ -3,6 +3,17 @@
 
 enable_testing()
 
+# This creates the folder structure for the paramterized tests
+# to avoid handling missing folders in C++
+#
+# This must match the match the name defined in xml_output.cpp
+# for every instance of tests with GetParam.
+#
+# The folder name is created fom the test name (output of the line
+# without leading spaces: "GoogleTestXMLSpecial/cases.") and
+# the parts until the last slash ("case/"). These parts are concatenated.
+file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/GoogleTestXMLSpecial/cases.case")
+
 add_executable(xml_output xml_output.cpp)
 gtest_discover_tests(
   xml_output
diff --git a/Tests/RunCMake/GoogleTest/RunCMakeTest.cmake b/Tests/RunCMake/GoogleTest/RunCMakeTest.cmake
index efd22be..530c8ab 100644
--- a/Tests/RunCMake/GoogleTest/RunCMakeTest.cmake
+++ b/Tests/RunCMake/GoogleTest/RunCMakeTest.cmake
@@ -101,6 +101,13 @@
   -R GoogleTestXML
   --no-label-summary
   )
+
+  run_cmake_command(GoogleTestXML-special-result
+  ${CMAKE_CTEST_COMMAND}
+  -C Debug
+  -R GoogleTestXMLSpecial
+  --no-label-summary
+  )
 endfunction()
 
 function(run_GoogleTest_discovery_timeout DISCOVERY_MODE)
diff --git a/Tests/RunCMake/GoogleTest/xml_output.cpp b/Tests/RunCMake/GoogleTest/xml_output.cpp
index e130231..82f0d02 100644
--- a/Tests/RunCMake/GoogleTest/xml_output.cpp
+++ b/Tests/RunCMake/GoogleTest/xml_output.cpp
@@ -13,11 +13,22 @@
       // This actually defines the name of the file passed in the 2nd run
       std::cout << "GoogleTestXML." << std::endl;
       std::cout << "  Foo" << std::endl;
+      // When changing these names, make sure to adapt the folder creation
+      // in GoogleTestXML.cmake
+      std::cout << "GoogleTestXMLSpecial/cases." << std::endl;
+      std::cout << "  case/0  # GetParam() = 42" << std::endl;
+      std::cout << "  case/1  # GetParam() = \"string\"" << std::endl;
+      std::cout << "  case/2  # GetParam() = \"path/like\"" << std::endl;
     } else if (param.find("--gtest_output=xml:") != std::string::npos) {
       std::string::size_type split = param.find(":");
       std::string filepath = param.substr(split + 1);
       // The full file path is passed
       std::ofstream ostrm(filepath.c_str(), std::ios::binary);
+      if (!ostrm) {
+        std::cerr << "Failed to create file: " << filepath.c_str()
+                  << std::endl;
+        return 1;
+      }
       ostrm << "--gtest_output=xml: mockup file\n";
     }
   }
diff --git a/Tests/RunCMake/Graphviz/GraphvizTestProject.cmake b/Tests/RunCMake/Graphviz/GraphvizTestProject.cmake
index 10cd2bc..4ce6b5c 100644
--- a/Tests/RunCMake/Graphviz/GraphvizTestProject.cmake
+++ b/Tests/RunCMake/Graphviz/GraphvizTestProject.cmake
@@ -9,6 +9,7 @@
 #   - All library depend on a common INTERFACE library holding compiler flags
 #   - We have a custom target to generate a man page
 #   - Someone has added an UNKNOWN, IMPORTED crypto mining library!
+#   - We have a circular dependency between two libraries
 
 add_subdirectory(test_project/third_party_project)
 
@@ -23,6 +24,13 @@
 
 target_link_libraries(CoreLibrary PRIVATE SeriousLoggingLibrary)
 
+add_library(SystemLibrary STATIC test_project/system_library.c)
+
+# Create a circular dependency.
+# See https://gitlab.kitware.com/cmake/cmake/issues/20720
+target_link_libraries(CoreLibrary PRIVATE SystemLibrary)
+target_link_libraries(SystemLibrary PRIVATE CoreLibrary)
+
 add_library(GraphicLibraryObjects OBJECT test_project/graphic_library.c)
 
 add_library(GraphicLibrary SHARED)
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_custom_targets.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_custom_targets.dot
index 8b0365a..31d88df 100644
--- a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_custom_targets.dot
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_custom_targets.dot
@@ -28,25 +28,28 @@
     "node2" -> "node0"  // CoreLibrary -> CompilerFlags
     "node3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
     "node2" -> "node3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+    "node4" [ label = "SystemLibrary", shape = octagon ];
+    "node4" -> "node2" [ style = dotted ] // SystemLibrary -> CoreLibrary
+    "node2" -> "node4" [ style = dotted ] // CoreLibrary -> SystemLibrary
     "node1" -> "node2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
-    "node4" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
-    "node1" -> "node4" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
-    "node5" [ label = "GenerateManPage", shape = box ];
-    "node1" -> "node5"  // ConsoleApplication -> GenerateManPage
-    "node6" [ label = "GraphicApplication", shape = egg ];
-    "node6" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
-    "node7" [ label = "GraphicLibrary", shape = doubleoctagon ];
-    "node8" [ label = "\"-lm\"", shape = septagon ];
-    "node7" -> "node8" [ style = dotted ] // GraphicLibrary -> "-lm"
-    "node7" -> "node0"  // GraphicLibrary -> CompilerFlags
-    "node7" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
-    "node9" [ label = "GraphicLibraryObjects", shape = hexagon ];
-    "node7" -> "node9" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
-    "node6" -> "node7" [ style = dotted ] // GraphicApplication -> GraphicLibrary
-    "node10" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
-    "node10" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
-    "node10" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
-    "node11" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
-    "node11" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
-    "node11" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+    "node5" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+    "node1" -> "node5" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
+    "node6" [ label = "GenerateManPage", shape = box ];
+    "node1" -> "node6"  // ConsoleApplication -> GenerateManPage
+    "node7" [ label = "GraphicApplication", shape = egg ];
+    "node7" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
+    "node8" [ label = "GraphicLibrary", shape = doubleoctagon ];
+    "node9" [ label = "\"-lm\"", shape = septagon ];
+    "node8" -> "node9" [ style = dotted ] // GraphicLibrary -> "-lm"
+    "node8" -> "node0"  // GraphicLibrary -> CompilerFlags
+    "node8" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+    "node10" [ label = "GraphicLibraryObjects", shape = hexagon ];
+    "node8" -> "node10" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
+    "node7" -> "node8" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+    "node11" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+    "node11" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
+    "node11" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+    "node12" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+    "node12" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
+    "node12" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
 }
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_default_options.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_default_options.dot
index 1bbf25a..26f2f64 100644
--- a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_default_options.dot
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_default_options.dot
@@ -28,23 +28,26 @@
     "node2" -> "node0"  // CoreLibrary -> CompilerFlags
     "node3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
     "node2" -> "node3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+    "node4" [ label = "SystemLibrary", shape = octagon ];
+    "node4" -> "node2" [ style = dotted ] // SystemLibrary -> CoreLibrary
+    "node2" -> "node4" [ style = dotted ] // CoreLibrary -> SystemLibrary
     "node1" -> "node2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
-    "node4" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
-    "node1" -> "node4" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
-    "node5" [ label = "GraphicApplication", shape = egg ];
-    "node5" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
-    "node6" [ label = "GraphicLibrary", shape = doubleoctagon ];
-    "node7" [ label = "\"-lm\"", shape = septagon ];
-    "node6" -> "node7" [ style = dotted ] // GraphicLibrary -> "-lm"
-    "node6" -> "node0"  // GraphicLibrary -> CompilerFlags
-    "node6" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
-    "node8" [ label = "GraphicLibraryObjects", shape = hexagon ];
-    "node6" -> "node8" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
-    "node5" -> "node6" [ style = dotted ] // GraphicApplication -> GraphicLibrary
-    "node9" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
-    "node9" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
-    "node9" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
-    "node10" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
-    "node10" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
-    "node10" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+    "node5" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+    "node1" -> "node5" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
+    "node6" [ label = "GraphicApplication", shape = egg ];
+    "node6" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
+    "node7" [ label = "GraphicLibrary", shape = doubleoctagon ];
+    "node8" [ label = "\"-lm\"", shape = septagon ];
+    "node7" -> "node8" [ style = dotted ] // GraphicLibrary -> "-lm"
+    "node7" -> "node0"  // GraphicLibrary -> CompilerFlags
+    "node7" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+    "node9" [ label = "GraphicLibraryObjects", shape = hexagon ];
+    "node7" -> "node9" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
+    "node6" -> "node7" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+    "node10" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+    "node10" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
+    "node10" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+    "node11" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+    "node11" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
+    "node11" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
 }
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_dependers_files.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_dependers_files.dot
index 1bbf25a..26f2f64 100644
--- a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_dependers_files.dot
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_dependers_files.dot
@@ -28,23 +28,26 @@
     "node2" -> "node0"  // CoreLibrary -> CompilerFlags
     "node3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
     "node2" -> "node3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+    "node4" [ label = "SystemLibrary", shape = octagon ];
+    "node4" -> "node2" [ style = dotted ] // SystemLibrary -> CoreLibrary
+    "node2" -> "node4" [ style = dotted ] // CoreLibrary -> SystemLibrary
     "node1" -> "node2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
-    "node4" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
-    "node1" -> "node4" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
-    "node5" [ label = "GraphicApplication", shape = egg ];
-    "node5" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
-    "node6" [ label = "GraphicLibrary", shape = doubleoctagon ];
-    "node7" [ label = "\"-lm\"", shape = septagon ];
-    "node6" -> "node7" [ style = dotted ] // GraphicLibrary -> "-lm"
-    "node6" -> "node0"  // GraphicLibrary -> CompilerFlags
-    "node6" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
-    "node8" [ label = "GraphicLibraryObjects", shape = hexagon ];
-    "node6" -> "node8" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
-    "node5" -> "node6" [ style = dotted ] // GraphicApplication -> GraphicLibrary
-    "node9" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
-    "node9" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
-    "node9" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
-    "node10" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
-    "node10" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
-    "node10" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+    "node5" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+    "node1" -> "node5" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
+    "node6" [ label = "GraphicApplication", shape = egg ];
+    "node6" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
+    "node7" [ label = "GraphicLibrary", shape = doubleoctagon ];
+    "node8" [ label = "\"-lm\"", shape = septagon ];
+    "node7" -> "node8" [ style = dotted ] // GraphicLibrary -> "-lm"
+    "node7" -> "node0"  // GraphicLibrary -> CompilerFlags
+    "node7" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+    "node9" [ label = "GraphicLibraryObjects", shape = hexagon ];
+    "node7" -> "node9" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
+    "node6" -> "node7" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+    "node10" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+    "node10" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
+    "node10" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+    "node11" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+    "node11" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
+    "node11" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
 }
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_executables.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_executables.dot
index 558a470..7f2e01c 100644
--- a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_executables.dot
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_executables.dot
@@ -27,18 +27,21 @@
     "node1" -> "node0"  // CoreLibrary -> CompilerFlags
     "node2" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
     "node1" -> "node2" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
-    "node3" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
-    "node4" [ label = "GraphicLibrary", shape = doubleoctagon ];
-    "node5" [ label = "\"-lm\"", shape = septagon ];
-    "node4" -> "node5" [ style = dotted ] // GraphicLibrary -> "-lm"
-    "node4" -> "node0"  // GraphicLibrary -> CompilerFlags
-    "node4" -> "node1" [ style = dotted ] // GraphicLibrary -> CoreLibrary
-    "node6" [ label = "GraphicLibraryObjects", shape = hexagon ];
-    "node4" -> "node6" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
-    "node7" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
-    "node7" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
-    "node7" -> "node1" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
-    "node8" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
-    "node8" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
-    "node8" -> "node1" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+    "node3" [ label = "SystemLibrary", shape = octagon ];
+    "node3" -> "node1" [ style = dotted ] // SystemLibrary -> CoreLibrary
+    "node1" -> "node3" [ style = dotted ] // CoreLibrary -> SystemLibrary
+    "node4" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+    "node5" [ label = "GraphicLibrary", shape = doubleoctagon ];
+    "node6" [ label = "\"-lm\"", shape = septagon ];
+    "node5" -> "node6" [ style = dotted ] // GraphicLibrary -> "-lm"
+    "node5" -> "node0"  // GraphicLibrary -> CompilerFlags
+    "node5" -> "node1" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+    "node7" [ label = "GraphicLibraryObjects", shape = hexagon ];
+    "node5" -> "node7" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
+    "node8" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+    "node8" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
+    "node8" -> "node1" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+    "node9" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+    "node9" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
+    "node9" -> "node1" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
 }
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_external_libs.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_external_libs.dot
index 660af37..db675a8 100644
--- a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_external_libs.dot
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_external_libs.dot
@@ -28,19 +28,22 @@
     "node2" -> "node0"  // CoreLibrary -> CompilerFlags
     "node3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
     "node2" -> "node3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+    "node4" [ label = "SystemLibrary", shape = octagon ];
+    "node4" -> "node2" [ style = dotted ] // SystemLibrary -> CoreLibrary
+    "node2" -> "node4" [ style = dotted ] // CoreLibrary -> SystemLibrary
     "node1" -> "node2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
-    "node4" [ label = "GraphicApplication", shape = egg ];
-    "node4" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
-    "node5" [ label = "GraphicLibrary", shape = doubleoctagon ];
-    "node5" -> "node0"  // GraphicLibrary -> CompilerFlags
-    "node5" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
-    "node6" [ label = "GraphicLibraryObjects", shape = hexagon ];
-    "node5" -> "node6" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
-    "node4" -> "node5" [ style = dotted ] // GraphicApplication -> GraphicLibrary
-    "node7" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
-    "node7" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
-    "node7" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
-    "node8" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
-    "node8" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
-    "node8" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+    "node5" [ label = "GraphicApplication", shape = egg ];
+    "node5" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
+    "node6" [ label = "GraphicLibrary", shape = doubleoctagon ];
+    "node6" -> "node0"  // GraphicLibrary -> CompilerFlags
+    "node6" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+    "node7" [ label = "GraphicLibraryObjects", shape = hexagon ];
+    "node6" -> "node7" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
+    "node5" -> "node6" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+    "node8" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+    "node8" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
+    "node8" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+    "node9" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+    "node9" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
+    "node9" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
 }
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_graphic_libs.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_graphic_libs.dot
index 5af7fec..234ee39 100644
--- a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_graphic_libs.dot
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_graphic_libs.dot
@@ -28,8 +28,11 @@
     "node2" -> "node0"  // CoreLibrary -> CompilerFlags
     "node3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
     "node2" -> "node3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+    "node4" [ label = "SystemLibrary", shape = octagon ];
+    "node4" -> "node2" [ style = dotted ] // SystemLibrary -> CoreLibrary
+    "node2" -> "node4" [ style = dotted ] // CoreLibrary -> SystemLibrary
     "node1" -> "node2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
-    "node4" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
-    "node1" -> "node4" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
-    "node5" [ label = "\"-lm\"", shape = septagon ];
+    "node5" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+    "node1" -> "node5" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
+    "node6" [ label = "\"-lm\"", shape = septagon ];
 }
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_interface_libs.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_interface_libs.dot
index 94ec41c..6dea88c 100644
--- a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_interface_libs.dot
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_interface_libs.dot
@@ -24,20 +24,23 @@
 }
     "node0" [ label = "ConsoleApplication", shape = egg ];
     "node1" [ label = "CoreLibrary", shape = octagon ];
+    "node2" [ label = "SystemLibrary", shape = octagon ];
+    "node2" -> "node1" [ style = dotted ] // SystemLibrary -> CoreLibrary
+    "node1" -> "node2" [ style = dotted ] // CoreLibrary -> SystemLibrary
     "node0" -> "node1" [ style = dotted ] // ConsoleApplication -> CoreLibrary
-    "node2" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
-    "node0" -> "node2" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
-    "node3" [ label = "GraphicApplication", shape = egg ];
-    "node3" -> "node1" [ style = dotted ] // GraphicApplication -> CoreLibrary
-    "node4" [ label = "GraphicLibrary", shape = doubleoctagon ];
-    "node5" [ label = "\"-lm\"", shape = septagon ];
-    "node4" -> "node5" [ style = dotted ] // GraphicLibrary -> "-lm"
-    "node4" -> "node1" [ style = dotted ] // GraphicLibrary -> CoreLibrary
-    "node6" [ label = "GraphicLibraryObjects", shape = hexagon ];
-    "node4" -> "node6" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
-    "node3" -> "node4" [ style = dotted ] // GraphicApplication -> GraphicLibrary
-    "node7" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
-    "node7" -> "node1" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
-    "node8" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
-    "node8" -> "node1" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+    "node3" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+    "node0" -> "node3" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
+    "node4" [ label = "GraphicApplication", shape = egg ];
+    "node4" -> "node1" [ style = dotted ] // GraphicApplication -> CoreLibrary
+    "node5" [ label = "GraphicLibrary", shape = doubleoctagon ];
+    "node6" [ label = "\"-lm\"", shape = septagon ];
+    "node5" -> "node6" [ style = dotted ] // GraphicLibrary -> "-lm"
+    "node5" -> "node1" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+    "node7" [ label = "GraphicLibraryObjects", shape = hexagon ];
+    "node5" -> "node7" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
+    "node4" -> "node5" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+    "node8" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+    "node8" -> "node1" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+    "node9" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+    "node9" -> "node1" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
 }
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_module_libs.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_module_libs.dot
index 65b7a71..df3d10a 100644
--- a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_module_libs.dot
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_module_libs.dot
@@ -28,17 +28,20 @@
     "node2" -> "node0"  // CoreLibrary -> CompilerFlags
     "node3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
     "node2" -> "node3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+    "node4" [ label = "SystemLibrary", shape = octagon ];
+    "node4" -> "node2" [ style = dotted ] // SystemLibrary -> CoreLibrary
+    "node2" -> "node4" [ style = dotted ] // CoreLibrary -> SystemLibrary
     "node1" -> "node2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
-    "node4" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
-    "node1" -> "node4" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
-    "node5" [ label = "GraphicApplication", shape = egg ];
-    "node5" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
-    "node6" [ label = "GraphicLibrary", shape = doubleoctagon ];
-    "node7" [ label = "\"-lm\"", shape = septagon ];
-    "node6" -> "node7" [ style = dotted ] // GraphicLibrary -> "-lm"
-    "node6" -> "node0"  // GraphicLibrary -> CompilerFlags
-    "node6" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
-    "node8" [ label = "GraphicLibraryObjects", shape = hexagon ];
-    "node6" -> "node8" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
-    "node5" -> "node6" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+    "node5" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+    "node1" -> "node5" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
+    "node6" [ label = "GraphicApplication", shape = egg ];
+    "node6" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
+    "node7" [ label = "GraphicLibrary", shape = doubleoctagon ];
+    "node8" [ label = "\"-lm\"", shape = septagon ];
+    "node7" -> "node8" [ style = dotted ] // GraphicLibrary -> "-lm"
+    "node7" -> "node0"  // GraphicLibrary -> CompilerFlags
+    "node7" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+    "node9" [ label = "GraphicLibraryObjects", shape = hexagon ];
+    "node7" -> "node9" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
+    "node6" -> "node7" [ style = dotted ] // GraphicApplication -> GraphicLibrary
 }
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_object_libs.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_object_libs.dot
index 8116bc9..8f832a8 100644
--- a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_object_libs.dot
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_object_libs.dot
@@ -28,21 +28,24 @@
     "node2" -> "node0"  // CoreLibrary -> CompilerFlags
     "node3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
     "node2" -> "node3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+    "node4" [ label = "SystemLibrary", shape = octagon ];
+    "node4" -> "node2" [ style = dotted ] // SystemLibrary -> CoreLibrary
+    "node2" -> "node4" [ style = dotted ] // CoreLibrary -> SystemLibrary
     "node1" -> "node2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
-    "node4" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
-    "node1" -> "node4" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
-    "node5" [ label = "GraphicApplication", shape = egg ];
-    "node5" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
-    "node6" [ label = "GraphicLibrary", shape = doubleoctagon ];
-    "node7" [ label = "\"-lm\"", shape = septagon ];
-    "node6" -> "node7" [ style = dotted ] // GraphicLibrary -> "-lm"
-    "node6" -> "node0"  // GraphicLibrary -> CompilerFlags
-    "node6" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
-    "node5" -> "node6" [ style = dotted ] // GraphicApplication -> GraphicLibrary
-    "node8" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
-    "node8" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
-    "node8" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
-    "node9" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
-    "node9" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
-    "node9" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+    "node5" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+    "node1" -> "node5" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
+    "node6" [ label = "GraphicApplication", shape = egg ];
+    "node6" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
+    "node7" [ label = "GraphicLibrary", shape = doubleoctagon ];
+    "node8" [ label = "\"-lm\"", shape = septagon ];
+    "node7" -> "node8" [ style = dotted ] // GraphicLibrary -> "-lm"
+    "node7" -> "node0"  // GraphicLibrary -> CompilerFlags
+    "node7" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+    "node6" -> "node7" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+    "node9" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+    "node9" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
+    "node9" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+    "node10" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+    "node10" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
+    "node10" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
 }
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_per_target_files.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_per_target_files.dot
index 1bbf25a..26f2f64 100644
--- a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_per_target_files.dot
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_per_target_files.dot
@@ -28,23 +28,26 @@
     "node2" -> "node0"  // CoreLibrary -> CompilerFlags
     "node3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
     "node2" -> "node3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+    "node4" [ label = "SystemLibrary", shape = octagon ];
+    "node4" -> "node2" [ style = dotted ] // SystemLibrary -> CoreLibrary
+    "node2" -> "node4" [ style = dotted ] // CoreLibrary -> SystemLibrary
     "node1" -> "node2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
-    "node4" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
-    "node1" -> "node4" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
-    "node5" [ label = "GraphicApplication", shape = egg ];
-    "node5" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
-    "node6" [ label = "GraphicLibrary", shape = doubleoctagon ];
-    "node7" [ label = "\"-lm\"", shape = septagon ];
-    "node6" -> "node7" [ style = dotted ] // GraphicLibrary -> "-lm"
-    "node6" -> "node0"  // GraphicLibrary -> CompilerFlags
-    "node6" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
-    "node8" [ label = "GraphicLibraryObjects", shape = hexagon ];
-    "node6" -> "node8" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
-    "node5" -> "node6" [ style = dotted ] // GraphicApplication -> GraphicLibrary
-    "node9" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
-    "node9" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
-    "node9" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
-    "node10" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
-    "node10" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
-    "node10" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+    "node5" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+    "node1" -> "node5" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
+    "node6" [ label = "GraphicApplication", shape = egg ];
+    "node6" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
+    "node7" [ label = "GraphicLibrary", shape = doubleoctagon ];
+    "node8" [ label = "\"-lm\"", shape = septagon ];
+    "node7" -> "node8" [ style = dotted ] // GraphicLibrary -> "-lm"
+    "node7" -> "node0"  // GraphicLibrary -> CompilerFlags
+    "node7" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+    "node9" [ label = "GraphicLibraryObjects", shape = hexagon ];
+    "node7" -> "node9" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
+    "node6" -> "node7" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+    "node10" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+    "node10" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
+    "node10" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+    "node11" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+    "node11" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
+    "node11" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
 }
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_shared_libs.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_shared_libs.dot
index 439d1f7..e127daa 100644
--- a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_shared_libs.dot
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_shared_libs.dot
@@ -28,17 +28,20 @@
     "node2" -> "node0"  // CoreLibrary -> CompilerFlags
     "node3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
     "node2" -> "node3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+    "node4" [ label = "SystemLibrary", shape = octagon ];
+    "node4" -> "node2" [ style = dotted ] // SystemLibrary -> CoreLibrary
+    "node2" -> "node4" [ style = dotted ] // CoreLibrary -> SystemLibrary
     "node1" -> "node2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
-    "node4" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
-    "node1" -> "node4" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
-    "node5" [ label = "GraphicApplication", shape = egg ];
-    "node5" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
-    "node6" [ label = "\"-lm\"", shape = septagon ];
-    "node7" [ label = "GraphicLibraryObjects", shape = hexagon ];
-    "node8" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
-    "node8" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
-    "node8" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
-    "node9" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
-    "node9" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
-    "node9" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+    "node5" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+    "node1" -> "node5" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
+    "node6" [ label = "GraphicApplication", shape = egg ];
+    "node6" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
+    "node7" [ label = "\"-lm\"", shape = septagon ];
+    "node8" [ label = "GraphicLibraryObjects", shape = hexagon ];
+    "node9" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+    "node9" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
+    "node9" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+    "node10" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+    "node10" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
+    "node10" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
 }
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_unknown_libs.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_unknown_libs.dot
index 1be6550..4f242bb 100644
--- a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_unknown_libs.dot
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_unknown_libs.dot
@@ -28,21 +28,24 @@
     "node2" -> "node0"  // CoreLibrary -> CompilerFlags
     "node3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
     "node2" -> "node3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+    "node4" [ label = "SystemLibrary", shape = octagon ];
+    "node4" -> "node2" [ style = dotted ] // SystemLibrary -> CoreLibrary
+    "node2" -> "node4" [ style = dotted ] // CoreLibrary -> SystemLibrary
     "node1" -> "node2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
-    "node4" [ label = "GraphicApplication", shape = egg ];
-    "node4" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
-    "node5" [ label = "GraphicLibrary", shape = doubleoctagon ];
-    "node6" [ label = "\"-lm\"", shape = septagon ];
-    "node5" -> "node6" [ style = dotted ] // GraphicLibrary -> "-lm"
-    "node5" -> "node0"  // GraphicLibrary -> CompilerFlags
-    "node5" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
-    "node7" [ label = "GraphicLibraryObjects", shape = hexagon ];
-    "node5" -> "node7" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
-    "node4" -> "node5" [ style = dotted ] // GraphicApplication -> GraphicLibrary
-    "node8" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
-    "node8" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
-    "node8" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
-    "node9" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
-    "node9" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
-    "node9" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+    "node5" [ label = "GraphicApplication", shape = egg ];
+    "node5" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
+    "node6" [ label = "GraphicLibrary", shape = doubleoctagon ];
+    "node7" [ label = "\"-lm\"", shape = septagon ];
+    "node6" -> "node7" [ style = dotted ] // GraphicLibrary -> "-lm"
+    "node6" -> "node0"  // GraphicLibrary -> CompilerFlags
+    "node6" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+    "node8" [ label = "GraphicLibraryObjects", shape = hexagon ];
+    "node6" -> "node8" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
+    "node5" -> "node6" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+    "node9" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+    "node9" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
+    "node9" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+    "node10" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+    "node10" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
+    "node10" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
 }
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_set_graph_header.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_set_graph_header.dot
index 1cfbe0f..c664af8 100644
--- a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_set_graph_header.dot
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_set_graph_header.dot
@@ -28,23 +28,26 @@
     "node2" -> "node0"  // CoreLibrary -> CompilerFlags
     "node3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
     "node2" -> "node3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+    "node4" [ label = "SystemLibrary", shape = octagon ];
+    "node4" -> "node2" [ style = dotted ] // SystemLibrary -> CoreLibrary
+    "node2" -> "node4" [ style = dotted ] // CoreLibrary -> SystemLibrary
     "node1" -> "node2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
-    "node4" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
-    "node1" -> "node4" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
-    "node5" [ label = "GraphicApplication", shape = egg ];
-    "node5" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
-    "node6" [ label = "GraphicLibrary", shape = doubleoctagon ];
-    "node7" [ label = "\"-lm\"", shape = septagon ];
-    "node6" -> "node7" [ style = dotted ] // GraphicLibrary -> "-lm"
-    "node6" -> "node0"  // GraphicLibrary -> CompilerFlags
-    "node6" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
-    "node8" [ label = "GraphicLibraryObjects", shape = hexagon ];
-    "node6" -> "node8" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
-    "node5" -> "node6" [ style = dotted ] // GraphicApplication -> GraphicLibrary
-    "node9" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
-    "node9" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
-    "node9" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
-    "node10" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
-    "node10" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
-    "node10" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+    "node5" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+    "node1" -> "node5" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
+    "node6" [ label = "GraphicApplication", shape = egg ];
+    "node6" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
+    "node7" [ label = "GraphicLibrary", shape = doubleoctagon ];
+    "node8" [ label = "\"-lm\"", shape = septagon ];
+    "node7" -> "node8" [ style = dotted ] // GraphicLibrary -> "-lm"
+    "node7" -> "node0"  // GraphicLibrary -> CompilerFlags
+    "node7" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+    "node9" [ label = "GraphicLibraryObjects", shape = hexagon ];
+    "node7" -> "node9" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
+    "node6" -> "node7" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+    "node10" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+    "node10" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
+    "node10" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+    "node11" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+    "node11" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
+    "node11" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
 }
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_set_graph_name.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_set_graph_name.dot
index 9653c33..5579306 100644
--- a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_set_graph_name.dot
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_set_graph_name.dot
@@ -28,23 +28,26 @@
     "node2" -> "node0"  // CoreLibrary -> CompilerFlags
     "node3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
     "node2" -> "node3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+    "node4" [ label = "SystemLibrary", shape = octagon ];
+    "node4" -> "node2" [ style = dotted ] // SystemLibrary -> CoreLibrary
+    "node2" -> "node4" [ style = dotted ] // CoreLibrary -> SystemLibrary
     "node1" -> "node2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
-    "node4" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
-    "node1" -> "node4" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
-    "node5" [ label = "GraphicApplication", shape = egg ];
-    "node5" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
-    "node6" [ label = "GraphicLibrary", shape = doubleoctagon ];
-    "node7" [ label = "\"-lm\"", shape = septagon ];
-    "node6" -> "node7" [ style = dotted ] // GraphicLibrary -> "-lm"
-    "node6" -> "node0"  // GraphicLibrary -> CompilerFlags
-    "node6" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
-    "node8" [ label = "GraphicLibraryObjects", shape = hexagon ];
-    "node6" -> "node8" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
-    "node5" -> "node6" [ style = dotted ] // GraphicApplication -> GraphicLibrary
-    "node9" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
-    "node9" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
-    "node9" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
-    "node10" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
-    "node10" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
-    "node10" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+    "node5" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+    "node1" -> "node5" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
+    "node6" [ label = "GraphicApplication", shape = egg ];
+    "node6" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
+    "node7" [ label = "GraphicLibrary", shape = doubleoctagon ];
+    "node8" [ label = "\"-lm\"", shape = septagon ];
+    "node7" -> "node8" [ style = dotted ] // GraphicLibrary -> "-lm"
+    "node7" -> "node0"  // GraphicLibrary -> CompilerFlags
+    "node7" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+    "node9" [ label = "GraphicLibraryObjects", shape = hexagon ];
+    "node7" -> "node9" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
+    "node6" -> "node7" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+    "node10" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+    "node10" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
+    "node10" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+    "node11" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+    "node11" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
+    "node11" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
 }
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_set_node_prefix.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_set_node_prefix.dot
index 82d96d0..3bf20ec 100644
--- a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_set_node_prefix.dot
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_set_node_prefix.dot
@@ -28,23 +28,26 @@
     "point2" -> "point0"  // CoreLibrary -> CompilerFlags
     "point3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
     "point2" -> "point3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+    "point4" [ label = "SystemLibrary", shape = octagon ];
+    "point4" -> "point2" [ style = dotted ] // SystemLibrary -> CoreLibrary
+    "point2" -> "point4" [ style = dotted ] // CoreLibrary -> SystemLibrary
     "point1" -> "point2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
-    "point4" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
-    "point1" -> "point4" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
-    "point5" [ label = "GraphicApplication", shape = egg ];
-    "point5" -> "point2" [ style = dotted ] // GraphicApplication -> CoreLibrary
-    "point6" [ label = "GraphicLibrary", shape = doubleoctagon ];
-    "point7" [ label = "\"-lm\"", shape = septagon ];
-    "point6" -> "point7" [ style = dotted ] // GraphicLibrary -> "-lm"
-    "point6" -> "point0"  // GraphicLibrary -> CompilerFlags
-    "point6" -> "point2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
-    "point8" [ label = "GraphicLibraryObjects", shape = hexagon ];
-    "point6" -> "point8" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
-    "point5" -> "point6" [ style = dotted ] // GraphicApplication -> GraphicLibrary
-    "point9" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
-    "point9" -> "point0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
-    "point9" -> "point2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
-    "point10" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
-    "point10" -> "point0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
-    "point10" -> "point2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+    "point5" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+    "point1" -> "point5" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
+    "point6" [ label = "GraphicApplication", shape = egg ];
+    "point6" -> "point2" [ style = dotted ] // GraphicApplication -> CoreLibrary
+    "point7" [ label = "GraphicLibrary", shape = doubleoctagon ];
+    "point8" [ label = "\"-lm\"", shape = septagon ];
+    "point7" -> "point8" [ style = dotted ] // GraphicLibrary -> "-lm"
+    "point7" -> "point0"  // GraphicLibrary -> CompilerFlags
+    "point7" -> "point2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+    "point9" [ label = "GraphicLibraryObjects", shape = hexagon ];
+    "point7" -> "point9" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
+    "point6" -> "point7" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+    "point10" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+    "point10" -> "point0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
+    "point10" -> "point2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+    "point11" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+    "point11" -> "point0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
+    "point11" -> "point2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
 }
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_target_dependencies.dot.GraphicApplication b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_target_dependencies.dot.GraphicApplication
index 6893fd1..92fe609 100644
--- a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_target_dependencies.dot.GraphicApplication
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_target_dependencies.dot.GraphicApplication
@@ -2,21 +2,25 @@
 node [
   fontsize = "12"
 ];
-    "node5" [ label = "GraphicApplication", shape = egg ];
+    "node6" [ label = "GraphicApplication", shape = egg ];
     "node2" [ label = "CoreLibrary", shape = octagon ];
-    "node5" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
+    "node6" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
     "node0" [ label = "CompilerFlags", shape = pentagon ];
     "node2" -> "node0"  // CoreLibrary -> CompilerFlags
     "node3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
     "node2" -> "node3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
-    "node6" [ label = "GraphicLibrary", shape = doubleoctagon ];
-    "node5" -> "node6" [ style = dotted ] // GraphicApplication -> GraphicLibrary
-    "node7" [ label = "\"-lm\"", shape = septagon ];
-    "node6" -> "node7" [ style = dotted ] // GraphicLibrary -> "-lm"
-    "node0" [ label = "CompilerFlags", shape = pentagon ];
-    "node6" -> "node0"  // GraphicLibrary -> CompilerFlags
+    "node4" [ label = "SystemLibrary", shape = octagon ];
+    "node2" -> "node4" [ style = dotted ] // CoreLibrary -> SystemLibrary
     "node2" [ label = "CoreLibrary", shape = octagon ];
-    "node6" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
-    "node8" [ label = "GraphicLibraryObjects", shape = hexagon ];
-    "node6" -> "node8" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
+    "node4" -> "node2" [ style = dotted ] // SystemLibrary -> CoreLibrary
+    "node7" [ label = "GraphicLibrary", shape = doubleoctagon ];
+    "node6" -> "node7" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+    "node8" [ label = "\"-lm\"", shape = septagon ];
+    "node7" -> "node8" [ style = dotted ] // GraphicLibrary -> "-lm"
+    "node0" [ label = "CompilerFlags", shape = pentagon ];
+    "node7" -> "node0"  // GraphicLibrary -> CompilerFlags
+    "node2" [ label = "CoreLibrary", shape = octagon ];
+    "node7" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+    "node9" [ label = "GraphicLibraryObjects", shape = hexagon ];
+    "node7" -> "node9" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
 }
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_target_dependers.dot.CompilerFlags.dependers b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_target_dependers.dot.CompilerFlags.dependers
index 3352b1a..82a2efe 100644
--- a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_target_dependers.dot.CompilerFlags.dependers
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_target_dependers.dot.CompilerFlags.dependers
@@ -5,22 +5,26 @@
     "node0" [ label = "CompilerFlags", shape = pentagon ];
     "node2" [ label = "CoreLibrary", shape = octagon ];
     "node2" -> "node0"  // CoreLibrary -> CompilerFlags
+    "node4" [ label = "SystemLibrary", shape = octagon ];
+    "node4" -> "node2" [ style = dotted ] // SystemLibrary -> CoreLibrary
+    "node2" [ label = "CoreLibrary", shape = octagon ];
+    "node2" -> "node4" [ style = dotted ] // CoreLibrary -> SystemLibrary
     "node1" [ label = "ConsoleApplication", shape = egg ];
     "node1" -> "node2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
-    "node5" [ label = "GraphicApplication", shape = egg ];
-    "node5" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
-    "node6" [ label = "GraphicLibrary", shape = doubleoctagon ];
-    "node6" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
-    "node5" [ label = "GraphicApplication", shape = egg ];
-    "node5" -> "node6" [ style = dotted ] // GraphicApplication -> GraphicLibrary
-    "node9" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
-    "node9" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
-    "node10" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
-    "node10" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
-    "node6" [ label = "GraphicLibrary", shape = doubleoctagon ];
-    "node6" -> "node0"  // GraphicLibrary -> CompilerFlags
-    "node9" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
-    "node9" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
-    "node10" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
-    "node10" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
+    "node6" [ label = "GraphicApplication", shape = egg ];
+    "node6" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
+    "node7" [ label = "GraphicLibrary", shape = doubleoctagon ];
+    "node7" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+    "node6" [ label = "GraphicApplication", shape = egg ];
+    "node6" -> "node7" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+    "node10" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+    "node10" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+    "node11" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+    "node11" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+    "node7" [ label = "GraphicLibrary", shape = doubleoctagon ];
+    "node7" -> "node0"  // GraphicLibrary -> CompilerFlags
+    "node10" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+    "node10" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
+    "node11" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+    "node11" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
 }
diff --git a/Tests/RunCMake/Graphviz/test_project/system_library.c b/Tests/RunCMake/Graphviz/test_project/system_library.c
new file mode 100644
index 0000000..5d67079
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/test_project/system_library.c
@@ -0,0 +1,3 @@
+void initialize_system()
+{
+}
diff --git a/Tests/RunCMake/IncompatibleQt/CMakeLists.txt b/Tests/RunCMake/IncompatibleQt/CMakeLists.txt
index f452db1..ebab7a3 100644
--- a/Tests/RunCMake/IncompatibleQt/CMakeLists.txt
+++ b/Tests/RunCMake/IncompatibleQt/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} CXX)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/interface_library/CMakeLists.txt b/Tests/RunCMake/InterfaceLibrary/CMakeLists.txt
similarity index 62%
copy from Tests/RunCMake/interface_library/CMakeLists.txt
copy to Tests/RunCMake/InterfaceLibrary/CMakeLists.txt
index 12cd3c7..74b3ff8 100644
--- a/Tests/RunCMake/interface_library/CMakeLists.txt
+++ b/Tests/RunCMake/InterfaceLibrary/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/InterfaceLibrary/ConfigSources.cmake b/Tests/RunCMake/InterfaceLibrary/ConfigSources.cmake
new file mode 100644
index 0000000..631a845
--- /dev/null
+++ b/Tests/RunCMake/InterfaceLibrary/ConfigSources.cmake
@@ -0,0 +1,2 @@
+# Test an interface library added to the build system by a per-config source.
+add_library(iface INTERFACE $<$<CONFIG:NotAConfig>:${CMAKE_CURRENT_SOURCE_DIR}/iface.c>)
diff --git a/Tests/RunCMake/InterfaceLibrary/EmptySources-build2-result.txt b/Tests/RunCMake/InterfaceLibrary/EmptySources-build2-result.txt
new file mode 100644
index 0000000..d197c91
--- /dev/null
+++ b/Tests/RunCMake/InterfaceLibrary/EmptySources-build2-result.txt
@@ -0,0 +1 @@
+[^0]
diff --git a/Tests/RunCMake/InterfaceLibrary/EmptySources-build2-stdout.txt b/Tests/RunCMake/InterfaceLibrary/EmptySources-build2-stdout.txt
new file mode 100644
index 0000000..aac9172
--- /dev/null
+++ b/Tests/RunCMake/InterfaceLibrary/EmptySources-build2-stdout.txt
@@ -0,0 +1 @@
+iface2|Invalid project
diff --git a/Tests/RunCMake/InterfaceLibrary/EmptySources.cmake b/Tests/RunCMake/InterfaceLibrary/EmptySources.cmake
new file mode 100644
index 0000000..f452394
--- /dev/null
+++ b/Tests/RunCMake/InterfaceLibrary/EmptySources.cmake
@@ -0,0 +1,8 @@
+# Test an interface library added to the build system by empty SOURCES.
+add_library(iface INTERFACE)
+set_property(TARGET iface PROPERTY SOURCES "")
+
+# ...but not added by unset SOURCES.
+add_library(iface2 INTERFACE)
+set_property(TARGET iface2 PROPERTY SOURCES "")
+set_property(TARGET iface2 PROPERTY SOURCES)
diff --git a/Tests/RunCMake/InterfaceLibrary/ExcludeFromAll-build1-check.cmake b/Tests/RunCMake/InterfaceLibrary/ExcludeFromAll-build1-check.cmake
new file mode 100644
index 0000000..6500e48
--- /dev/null
+++ b/Tests/RunCMake/InterfaceLibrary/ExcludeFromAll-build1-check.cmake
@@ -0,0 +1,4 @@
+if(EXISTS "${RunCMake_TEST_BINARY_DIR}/iface.txt")
+  set(RunCMake_TEST_FAILED "iface target built as part of 'all'")
+  return()
+endif()
diff --git a/Tests/RunCMake/InterfaceLibrary/ExcludeFromAll-build2-check.cmake b/Tests/RunCMake/InterfaceLibrary/ExcludeFromAll-build2-check.cmake
new file mode 100644
index 0000000..0977c24
--- /dev/null
+++ b/Tests/RunCMake/InterfaceLibrary/ExcludeFromAll-build2-check.cmake
@@ -0,0 +1,4 @@
+if(NOT EXISTS "${RunCMake_TEST_BINARY_DIR}/iface.txt")
+  set(RunCMake_TEST_FAILED "iface target not built")
+  return()
+endif()
diff --git a/Tests/RunCMake/InterfaceLibrary/ExcludeFromAll-build3-result.txt b/Tests/RunCMake/InterfaceLibrary/ExcludeFromAll-build3-result.txt
new file mode 100644
index 0000000..d197c91
--- /dev/null
+++ b/Tests/RunCMake/InterfaceLibrary/ExcludeFromAll-build3-result.txt
@@ -0,0 +1 @@
+[^0]
diff --git a/Tests/RunCMake/InterfaceLibrary/ExcludeFromAll-build3-stdout.txt b/Tests/RunCMake/InterfaceLibrary/ExcludeFromAll-build3-stdout.txt
new file mode 100644
index 0000000..aac9172
--- /dev/null
+++ b/Tests/RunCMake/InterfaceLibrary/ExcludeFromAll-build3-stdout.txt
@@ -0,0 +1 @@
+iface2|Invalid project
diff --git a/Tests/RunCMake/InterfaceLibrary/ExcludeFromAll.cmake b/Tests/RunCMake/InterfaceLibrary/ExcludeFromAll.cmake
new file mode 100644
index 0000000..714161d
--- /dev/null
+++ b/Tests/RunCMake/InterfaceLibrary/ExcludeFromAll.cmake
@@ -0,0 +1,7 @@
+# Test an interface library with a custom command, but excluded from all.
+add_custom_command(OUTPUT iface.txt COMMAND ${CMAKE_COMMAND} -E touch iface.txt)
+add_library(iface INTERFACE EXCLUDE_FROM_ALL iface.txt)
+
+# Test that EXCLUDE_FROM_ALL is allowed even if the interface library has
+# no sources, and does not cause it to appear in the build system.
+add_library(iface2 INTERFACE EXCLUDE_FROM_ALL)
diff --git a/Tests/RunCMake/interface_library/IMPORTED_LIBNAME-bad-value-result.txt b/Tests/RunCMake/InterfaceLibrary/IMPORTED_LIBNAME-bad-value-result.txt
similarity index 100%
rename from Tests/RunCMake/interface_library/IMPORTED_LIBNAME-bad-value-result.txt
rename to Tests/RunCMake/InterfaceLibrary/IMPORTED_LIBNAME-bad-value-result.txt
diff --git a/Tests/RunCMake/interface_library/IMPORTED_LIBNAME-bad-value-stderr.txt b/Tests/RunCMake/InterfaceLibrary/IMPORTED_LIBNAME-bad-value-stderr.txt
similarity index 100%
rename from Tests/RunCMake/interface_library/IMPORTED_LIBNAME-bad-value-stderr.txt
rename to Tests/RunCMake/InterfaceLibrary/IMPORTED_LIBNAME-bad-value-stderr.txt
diff --git a/Tests/RunCMake/interface_library/IMPORTED_LIBNAME-bad-value.cmake b/Tests/RunCMake/InterfaceLibrary/IMPORTED_LIBNAME-bad-value.cmake
similarity index 100%
rename from Tests/RunCMake/interface_library/IMPORTED_LIBNAME-bad-value.cmake
rename to Tests/RunCMake/InterfaceLibrary/IMPORTED_LIBNAME-bad-value.cmake
diff --git a/Tests/RunCMake/interface_library/IMPORTED_LIBNAME-non-iface-result.txt b/Tests/RunCMake/InterfaceLibrary/IMPORTED_LIBNAME-non-iface-result.txt
similarity index 100%
rename from Tests/RunCMake/interface_library/IMPORTED_LIBNAME-non-iface-result.txt
rename to Tests/RunCMake/InterfaceLibrary/IMPORTED_LIBNAME-non-iface-result.txt
diff --git a/Tests/RunCMake/interface_library/IMPORTED_LIBNAME-non-iface-stderr.txt b/Tests/RunCMake/InterfaceLibrary/IMPORTED_LIBNAME-non-iface-stderr.txt
similarity index 100%
rename from Tests/RunCMake/interface_library/IMPORTED_LIBNAME-non-iface-stderr.txt
rename to Tests/RunCMake/InterfaceLibrary/IMPORTED_LIBNAME-non-iface-stderr.txt
diff --git a/Tests/RunCMake/interface_library/IMPORTED_LIBNAME-non-iface.cmake b/Tests/RunCMake/InterfaceLibrary/IMPORTED_LIBNAME-non-iface.cmake
similarity index 100%
rename from Tests/RunCMake/interface_library/IMPORTED_LIBNAME-non-iface.cmake
rename to Tests/RunCMake/InterfaceLibrary/IMPORTED_LIBNAME-non-iface.cmake
diff --git a/Tests/RunCMake/interface_library/IMPORTED_LIBNAME-non-imported-result.txt b/Tests/RunCMake/InterfaceLibrary/IMPORTED_LIBNAME-non-imported-result.txt
similarity index 100%
rename from Tests/RunCMake/interface_library/IMPORTED_LIBNAME-non-imported-result.txt
rename to Tests/RunCMake/InterfaceLibrary/IMPORTED_LIBNAME-non-imported-result.txt
diff --git a/Tests/RunCMake/interface_library/IMPORTED_LIBNAME-non-imported-stderr.txt b/Tests/RunCMake/InterfaceLibrary/IMPORTED_LIBNAME-non-imported-stderr.txt
similarity index 100%
rename from Tests/RunCMake/interface_library/IMPORTED_LIBNAME-non-imported-stderr.txt
rename to Tests/RunCMake/InterfaceLibrary/IMPORTED_LIBNAME-non-imported-stderr.txt
diff --git a/Tests/RunCMake/interface_library/IMPORTED_LIBNAME-non-imported.cmake b/Tests/RunCMake/InterfaceLibrary/IMPORTED_LIBNAME-non-imported.cmake
similarity index 100%
rename from Tests/RunCMake/interface_library/IMPORTED_LIBNAME-non-imported.cmake
rename to Tests/RunCMake/InterfaceLibrary/IMPORTED_LIBNAME-non-imported.cmake
diff --git a/Tests/RunCMake/InterfaceLibrary/PublicSources-build3-result.txt b/Tests/RunCMake/InterfaceLibrary/PublicSources-build3-result.txt
new file mode 100644
index 0000000..d197c91
--- /dev/null
+++ b/Tests/RunCMake/InterfaceLibrary/PublicSources-build3-result.txt
@@ -0,0 +1 @@
+[^0]
diff --git a/Tests/RunCMake/InterfaceLibrary/PublicSources-build3-stdout.txt b/Tests/RunCMake/InterfaceLibrary/PublicSources-build3-stdout.txt
new file mode 100644
index 0000000..aac9172
--- /dev/null
+++ b/Tests/RunCMake/InterfaceLibrary/PublicSources-build3-stdout.txt
@@ -0,0 +1 @@
+iface2|Invalid project
diff --git a/Tests/RunCMake/InterfaceLibrary/PublicSources.cmake b/Tests/RunCMake/InterfaceLibrary/PublicSources.cmake
new file mode 100644
index 0000000..24785bb
--- /dev/null
+++ b/Tests/RunCMake/InterfaceLibrary/PublicSources.cmake
@@ -0,0 +1,20 @@
+cmake_policy(SET CMP0076 NEW)
+enable_language(C)
+
+# Test that an interface library can have PUBLIC sources.
+# This causes the target to appear in the build system
+# *and* causes consumers to use the source.
+add_library(iface INTERFACE)
+target_sources(iface
+  PUBLIC iface.c
+  # Private sources do not compile here or propagate.
+  PRIVATE iface_broken.c
+  )
+
+# Test that an intermediate interface library does not get the
+# sources and does not appear in the build system.
+add_library(iface2 INTERFACE)
+target_link_libraries(iface2 INTERFACE iface)
+
+add_executable(use_iface use_iface.c)
+target_link_libraries(use_iface PRIVATE iface2)
diff --git a/Tests/RunCMake/InterfaceLibrary/RunCMakeTest.cmake b/Tests/RunCMake/InterfaceLibrary/RunCMakeTest.cmake
new file mode 100644
index 0000000..834b3c8
--- /dev/null
+++ b/Tests/RunCMake/InterfaceLibrary/RunCMakeTest.cmake
@@ -0,0 +1,36 @@
+include(RunCMake)
+
+run_cmake(invalid_name)
+run_cmake(target_commands)
+run_cmake(no_shared_libs)
+run_cmake(invalid_signature)
+run_cmake(global-interface)
+run_cmake(genex_link)
+run_cmake(add_custom_command-TARGET)
+run_cmake(IMPORTED_LIBNAME-bad-value)
+run_cmake(IMPORTED_LIBNAME-non-iface)
+run_cmake(IMPORTED_LIBNAME-non-imported)
+
+function(run_WithSources CASE)
+  if(NOT RunCMake_GENERATOR_IS_MULTI_CONFIG)
+    set(RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Debug)
+  endif()
+  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${CASE}-build)
+  run_cmake(${CASE})
+  set(RunCMake_TEST_NO_CLEAN 1)
+  foreach(build IN LISTS ARGN)
+    if(build MATCHES "^([^:]+)$")
+      run_cmake_command(${CASE}-${CMAKE_MATCH_1} ${CMAKE_COMMAND} --build . --config Debug)
+    elseif(build MATCHES "^([^:]+):([^:,]+)(,merge)?$")
+      if(CMAKE_MATCH_3 STREQUAL ",merge")
+        set(RunCMake_TEST_OUTPUT_MERGE 1)
+      endif()
+      run_cmake_command(${CASE}-${CMAKE_MATCH_1} ${CMAKE_COMMAND} --build . --config Debug --target ${CMAKE_MATCH_2})
+    endif()
+  endforeach()
+endfunction()
+
+run_WithSources(ConfigSources "build1:iface")
+run_WithSources(EmptySources "build1:iface" "build2:iface2,merge")
+run_WithSources(ExcludeFromAll "build1" "build2:iface" "build3:iface2,merge")
+run_WithSources(PublicSources "build1" "build2:iface" "build3:iface2,merge")
diff --git a/Tests/RunCMake/interface_library/add_custom_command-TARGET-result.txt b/Tests/RunCMake/InterfaceLibrary/add_custom_command-TARGET-result.txt
similarity index 100%
rename from Tests/RunCMake/interface_library/add_custom_command-TARGET-result.txt
rename to Tests/RunCMake/InterfaceLibrary/add_custom_command-TARGET-result.txt
diff --git a/Tests/RunCMake/interface_library/add_custom_command-TARGET-stderr.txt b/Tests/RunCMake/InterfaceLibrary/add_custom_command-TARGET-stderr.txt
similarity index 100%
rename from Tests/RunCMake/interface_library/add_custom_command-TARGET-stderr.txt
rename to Tests/RunCMake/InterfaceLibrary/add_custom_command-TARGET-stderr.txt
diff --git a/Tests/RunCMake/interface_library/add_custom_command-TARGET.cmake b/Tests/RunCMake/InterfaceLibrary/add_custom_command-TARGET.cmake
similarity index 100%
rename from Tests/RunCMake/interface_library/add_custom_command-TARGET.cmake
rename to Tests/RunCMake/InterfaceLibrary/add_custom_command-TARGET.cmake
diff --git a/Tests/RunCMake/interface_library/genex_link-result.txt b/Tests/RunCMake/InterfaceLibrary/genex_link-result.txt
similarity index 100%
rename from Tests/RunCMake/interface_library/genex_link-result.txt
rename to Tests/RunCMake/InterfaceLibrary/genex_link-result.txt
diff --git a/Tests/RunCMake/interface_library/genex_link.cmake b/Tests/RunCMake/InterfaceLibrary/genex_link.cmake
similarity index 100%
rename from Tests/RunCMake/interface_library/genex_link.cmake
rename to Tests/RunCMake/InterfaceLibrary/genex_link.cmake
diff --git a/Tests/RunCMake/interface_library/global-interface-result.txt b/Tests/RunCMake/InterfaceLibrary/global-interface-result.txt
similarity index 100%
rename from Tests/RunCMake/interface_library/global-interface-result.txt
rename to Tests/RunCMake/InterfaceLibrary/global-interface-result.txt
diff --git a/Tests/RunCMake/interface_library/global-interface-stderr.txt b/Tests/RunCMake/InterfaceLibrary/global-interface-stderr.txt
similarity index 81%
rename from Tests/RunCMake/interface_library/global-interface-stderr.txt
rename to Tests/RunCMake/InterfaceLibrary/global-interface-stderr.txt
index 23b45d9..38585eb 100644
--- a/Tests/RunCMake/interface_library/global-interface-stderr.txt
+++ b/Tests/RunCMake/InterfaceLibrary/global-interface-stderr.txt
@@ -3,7 +3,7 @@
 
     GLOBAL
 
-  Tried extensions( \.[A-Za-z+]+|
- )*
+  Tried extensions \.c \.C .*
+.*
 Call Stack \(most recent call first\):
   CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/interface_library/global-interface.cmake b/Tests/RunCMake/InterfaceLibrary/global-interface.cmake
similarity index 100%
rename from Tests/RunCMake/interface_library/global-interface.cmake
rename to Tests/RunCMake/InterfaceLibrary/global-interface.cmake
diff --git a/Tests/RunCMake/InterfaceLibrary/iface.c b/Tests/RunCMake/InterfaceLibrary/iface.c
new file mode 100644
index 0000000..c7e7372
--- /dev/null
+++ b/Tests/RunCMake/InterfaceLibrary/iface.c
@@ -0,0 +1,4 @@
+int iface(void)
+{
+  return 0;
+}
diff --git a/Tests/RunCMake/InterfaceLibrary/iface_broken.c b/Tests/RunCMake/InterfaceLibrary/iface_broken.c
new file mode 100644
index 0000000..4ff7f31
--- /dev/null
+++ b/Tests/RunCMake/InterfaceLibrary/iface_broken.c
@@ -0,0 +1 @@
+#error This file should not compile
diff --git a/Tests/RunCMake/interface_library/invalid_name-result.txt b/Tests/RunCMake/InterfaceLibrary/invalid_name-result.txt
similarity index 100%
rename from Tests/RunCMake/interface_library/invalid_name-result.txt
rename to Tests/RunCMake/InterfaceLibrary/invalid_name-result.txt
diff --git a/Tests/RunCMake/interface_library/invalid_name-stderr.txt b/Tests/RunCMake/InterfaceLibrary/invalid_name-stderr.txt
similarity index 100%
rename from Tests/RunCMake/interface_library/invalid_name-stderr.txt
rename to Tests/RunCMake/InterfaceLibrary/invalid_name-stderr.txt
diff --git a/Tests/RunCMake/interface_library/invalid_name.cmake b/Tests/RunCMake/InterfaceLibrary/invalid_name.cmake
similarity index 75%
rename from Tests/RunCMake/interface_library/invalid_name.cmake
rename to Tests/RunCMake/InterfaceLibrary/invalid_name.cmake
index 9a965aa..575fcc6 100644
--- a/Tests/RunCMake/interface_library/invalid_name.cmake
+++ b/Tests/RunCMake/InterfaceLibrary/invalid_name.cmake
@@ -1,4 +1,4 @@
-
+cmake_minimum_required(VERSION 2.8.12)
 add_library(if$ace INTERFACE)
 
 add_library(iface::target INTERFACE)
diff --git a/Tests/RunCMake/interface_library/invalid_signature-result.txt b/Tests/RunCMake/InterfaceLibrary/invalid_signature-result.txt
similarity index 100%
rename from Tests/RunCMake/interface_library/invalid_signature-result.txt
rename to Tests/RunCMake/InterfaceLibrary/invalid_signature-result.txt
diff --git a/Tests/RunCMake/interface_library/invalid_signature-stderr.txt b/Tests/RunCMake/InterfaceLibrary/invalid_signature-stderr.txt
similarity index 83%
rename from Tests/RunCMake/interface_library/invalid_signature-stderr.txt
rename to Tests/RunCMake/InterfaceLibrary/invalid_signature-stderr.txt
index 6374b33..763f9f8 100644
--- a/Tests/RunCMake/interface_library/invalid_signature-stderr.txt
+++ b/Tests/RunCMake/InterfaceLibrary/invalid_signature-stderr.txt
@@ -1,8 +1,3 @@
-CMake Error at invalid_signature.cmake:2 \(add_library\):
-  add_library INTERFACE library requires no source arguments.
-Call Stack \(most recent call first\):
-  CMakeLists.txt:3 \(include\)
-+
 CMake Error at invalid_signature.cmake:3 \(add_library\):
   add_library INTERFACE library specified with conflicting/multiple types.
 Call Stack \(most recent call first\):
@@ -73,16 +68,6 @@
 Call Stack \(most recent call first\):
   CMakeLists.txt:3 \(include\)
 +
-CMake Error at invalid_signature.cmake:17 \(add_library\):
-  add_library INTERFACE library may not be used with EXCLUDE_FROM_ALL.
-Call Stack \(most recent call first\):
-  CMakeLists.txt:3 \(include\)
-+
-CMake Error at invalid_signature.cmake:18 \(add_library\):
-  add_library INTERFACE library may not be used with EXCLUDE_FROM_ALL.
-Call Stack \(most recent call first\):
-  CMakeLists.txt:3 \(include\)
-+
 CMake Error at invalid_signature.cmake:20 \(add_library\):
   add_library GLOBAL option may only be used with IMPORTED libraries.
 Call Stack \(most recent call first\):
diff --git a/Tests/RunCMake/interface_library/invalid_signature.cmake b/Tests/RunCMake/InterfaceLibrary/invalid_signature.cmake
similarity index 82%
rename from Tests/RunCMake/interface_library/invalid_signature.cmake
rename to Tests/RunCMake/InterfaceLibrary/invalid_signature.cmake
index 4e53534..2a575b5 100644
--- a/Tests/RunCMake/interface_library/invalid_signature.cmake
+++ b/Tests/RunCMake/InterfaceLibrary/invalid_signature.cmake
@@ -1,5 +1,5 @@
 
-add_library(iface1 INTERFACE empty.cpp)
+
 add_library(iface3 STATIC INTERFACE)
 add_library(iface4 STATIC INTERFACE empty.cpp)
 add_library(iface5 SHARED INTERFACE)
@@ -14,7 +14,7 @@
 add_library(iface14 INTERFACE ALIAS)
 add_library(iface15 ALIAS INTERFACE)
 add_library(iface16 INTERFACE INTERFACE)
-add_library(iface17 INTERFACE EXCLUDE_FROM_ALL)
-add_library(iface18 EXCLUDE_FROM_ALL INTERFACE)
+
+
 # add_library(iface19 GLOBAL INTERFACE) Tested separately
 add_library(iface20 INTERFACE GLOBAL)
diff --git a/Tests/RunCMake/interface_library/no_shared_libs.cmake b/Tests/RunCMake/InterfaceLibrary/no_shared_libs.cmake
similarity index 100%
rename from Tests/RunCMake/interface_library/no_shared_libs.cmake
rename to Tests/RunCMake/InterfaceLibrary/no_shared_libs.cmake
diff --git a/Tests/RunCMake/interface_library/target_commands-result.txt b/Tests/RunCMake/InterfaceLibrary/target_commands-result.txt
similarity index 100%
rename from Tests/RunCMake/interface_library/target_commands-result.txt
rename to Tests/RunCMake/InterfaceLibrary/target_commands-result.txt
diff --git a/Tests/RunCMake/interface_library/target_commands-stderr.txt b/Tests/RunCMake/InterfaceLibrary/target_commands-stderr.txt
similarity index 100%
rename from Tests/RunCMake/interface_library/target_commands-stderr.txt
rename to Tests/RunCMake/InterfaceLibrary/target_commands-stderr.txt
diff --git a/Tests/RunCMake/interface_library/target_commands.cmake b/Tests/RunCMake/InterfaceLibrary/target_commands.cmake
similarity index 100%
rename from Tests/RunCMake/interface_library/target_commands.cmake
rename to Tests/RunCMake/InterfaceLibrary/target_commands.cmake
diff --git a/Tests/RunCMake/InterfaceLibrary/use_iface.c b/Tests/RunCMake/InterfaceLibrary/use_iface.c
new file mode 100644
index 0000000..66293e4
--- /dev/null
+++ b/Tests/RunCMake/InterfaceLibrary/use_iface.c
@@ -0,0 +1,6 @@
+extern int iface(void);
+
+int main(void)
+{
+  return iface();
+}
diff --git a/Tests/RunCMake/Languages/CMakeLists.txt b/Tests/RunCMake/Languages/CMakeLists.txt
index 8996fef..74b3ff8 100644
--- a/Tests/RunCMake/Languages/CMakeLists.txt
+++ b/Tests/RunCMake/Languages/CMakeLists.txt
@@ -1,4 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
-cmake_policy(SET CMP0042 NEW)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/Make/RunCMakeTest.cmake b/Tests/RunCMake/Make/RunCMakeTest.cmake
index 6b2721c..32aafca 100644
--- a/Tests/RunCMake/Make/RunCMakeTest.cmake
+++ b/Tests/RunCMake/Make/RunCMakeTest.cmake
@@ -27,12 +27,15 @@
   run_cmake_command(VerboseBuild-build ${CMAKE_COMMAND} --build . -v --clean-first)
   unset(RunCMake-stdout-file)
   set(_backup_lang "$ENV{LANG}")
+  set(_backup_lc_Messages "$ENV{LC_MESSAGES}")
   if(MAKE_IS_GNU)
     set(RunCMake-stdout-file VerboseBuild-nowork-gnu-stdout.txt)
     set(ENV{LANG} "C")
+    set(ENV{LC_MESSAGES} "C")
   endif()
   run_cmake_command(VerboseBuild-nowork ${CMAKE_COMMAND} --build . --verbose)
   set(ENV{LANG} "${_backup_lang}")
+  set(ENV{LC_MESSAGES} "${_backup_lc_messages}")
 endfunction()
 run_VerboseBuild()
 
diff --git a/Tests/RunCMake/NinjaMultiConfig/ExcludeFromAll-all-build-check.cmake b/Tests/RunCMake/NinjaMultiConfig/ExcludeFromAll-all-build-check.cmake
new file mode 100644
index 0000000..a4d2758
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/ExcludeFromAll-all-build-check.cmake
@@ -0,0 +1,9 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+  INCLUDE
+    ${TARGET_FILE_release_only_tool_Release}
+    ${TARGET_EXE_FILE_release_only_tool_Release}
+
+  EXCLUDE
+    ${TARGET_FILE_release_only_tool_Debug}
+    ${TARGET_EXE_FILE_release_only_tool_Debug}
+  )
diff --git a/Tests/RunCMake/NinjaMultiConfig/ExcludeFromAll.cmake b/Tests/RunCMake/NinjaMultiConfig/ExcludeFromAll.cmake
new file mode 100644
index 0000000..52f84ea
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/ExcludeFromAll.cmake
@@ -0,0 +1,12 @@
+enable_language(C)
+
+set(CMAKE_CONFIGURATION_TYPES "Release;Debug" CACHE STRING "")
+set(CMAKE_DEFAULT_BUILD_TYPE "Release" CACHE STRING "")
+set(CMAKE_CROSS_CONFIGS "all" CACHE STRING "")
+set(CMAKE_DEFAULT_CONFIGS "all" CACHE STRING "")
+
+add_executable(release_only_tool main.c)
+set_property(TARGET release_only_tool PROPERTY EXCLUDE_FROM_ALL "$<NOT:$<CONFIG:Release>>")
+
+include(${CMAKE_CURRENT_LIST_DIR}/Common.cmake)
+generate_output_files(release_only_tool)
diff --git a/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake b/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake
index 76b488e..9249724 100644
--- a/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake
+++ b/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake
@@ -274,6 +274,11 @@
 file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}/install")
 run_ninja(Install all-install build.ninja install:all)
 
+set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/ExcludeFromAll-build)
+run_cmake_configure(ExcludeFromAll)
+include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake)
+run_cmake_build(ExcludeFromAll all "" all:all)
+
 # FIXME Get this working
 #set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/AutoMocExecutable-build)
 #run_cmake_configure(AutoMocExecutable)
diff --git a/Tests/RunCMake/ObjectLibrary/MissingSource-stderr.txt b/Tests/RunCMake/ObjectLibrary/MissingSource-stderr.txt
index 411cd7c..5c7882d 100644
--- a/Tests/RunCMake/ObjectLibrary/MissingSource-stderr.txt
+++ b/Tests/RunCMake/ObjectLibrary/MissingSource-stderr.txt
@@ -3,7 +3,7 @@
 
     missing.c
 
-  Tried extensions( \.[A-Za-z+]+|
- )*
+  Tried extensions \.c \.C .*
+.*
 Call Stack \(most recent call first\):
   CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/ObsoleteQtMacros/CMakeLists.txt b/Tests/RunCMake/ObsoleteQtMacros/CMakeLists.txt
index 65ac8e8..44b5d30 100644
--- a/Tests/RunCMake/ObsoleteQtMacros/CMakeLists.txt
+++ b/Tests/RunCMake/ObsoleteQtMacros/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.11)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST})
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/PositionIndependentCode/CMakeLists.txt b/Tests/RunCMake/PositionIndependentCode/CMakeLists.txt
index 90afc12..c3922d6 100644
--- a/Tests/RunCMake/PositionIndependentCode/CMakeLists.txt
+++ b/Tests/RunCMake/PositionIndependentCode/CMakeLists.txt
@@ -1,5 +1,5 @@
 
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} CXX)
 
 # MSVC creates extra targets which pollute the stderr unless we set this.
diff --git a/Tests/RunCMake/RunCMake.cmake b/Tests/RunCMake/RunCMake.cmake
index cb20fb1..c13c694 100644
--- a/Tests/RunCMake/RunCMake.cmake
+++ b/Tests/RunCMake/RunCMake.cmake
@@ -154,6 +154,7 @@
 
     "|[^\n]*xcodebuild[^\n]*warning: file type[^\n]*is based on missing file type"
     "|[^\n]*is a member of multiple groups"
+    "|[^\n]*offset in archive not a multiple of 8"
     "|[^\n]*from Time Machine by path"
     "|[^\n]*Bullseye Testing Technology"
     ")[^\n]*\n)+"
diff --git a/Tests/RunCMake/SourceProperties/CMakeLists.txt b/Tests/RunCMake/SourceProperties/CMakeLists.txt
index a17c8cd..e93f0b6 100644
--- a/Tests/RunCMake/SourceProperties/CMakeLists.txt
+++ b/Tests/RunCMake/SourceProperties/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} C)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/TargetObjects/CMakeLists.txt b/Tests/RunCMake/TargetObjects/CMakeLists.txt
index be9d403..44b5d30 100644
--- a/Tests/RunCMake/TargetObjects/CMakeLists.txt
+++ b/Tests/RunCMake/TargetObjects/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST})
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/TargetPolicies/CMakeLists.txt b/Tests/RunCMake/TargetPolicies/CMakeLists.txt
index 12cd3c7..74b3ff8 100644
--- a/Tests/RunCMake/TargetPolicies/CMakeLists.txt
+++ b/Tests/RunCMake/TargetPolicies/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/TargetProperties/CMakeLists.txt b/Tests/RunCMake/TargetProperties/CMakeLists.txt
index be9d403..44b5d30 100644
--- a/Tests/RunCMake/TargetProperties/CMakeLists.txt
+++ b/Tests/RunCMake/TargetProperties/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST})
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/CMakeLists.txt b/Tests/RunCMake/TargetPropertyGeneratorExpressions/CMakeLists.txt
index 90afc12..c3922d6 100644
--- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/CMakeLists.txt
+++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/CMakeLists.txt
@@ -1,5 +1,5 @@
 
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} CXX)
 
 # MSVC creates extra targets which pollute the stderr unless we set this.
diff --git a/Tests/RunCMake/TargetSources/CMakeLists.txt b/Tests/RunCMake/TargetSources/CMakeLists.txt
index f452db1..a06591c 100644
--- a/Tests/RunCMake/TargetSources/CMakeLists.txt
+++ b/Tests/RunCMake/TargetSources/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 2.8.12)
 project(${RunCMake_TEST} CXX)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_order-check.cmake b/Tests/RunCMake/UnityBuild/unitybuild_order-check.cmake
index f26ec2e..85e6587 100644
--- a/Tests/RunCMake/UnityBuild/unitybuild_order-check.cmake
+++ b/Tests/RunCMake/UnityBuild/unitybuild_order-check.cmake
@@ -2,6 +2,6 @@
 file(STRINGS ${unitybuild_c} unitybuild_c_strings)
 string(REGEX MATCH ".*#include.*s3.c.*#include.*s1.c.*#include.*s2.c.*" matched_code ${unitybuild_c_strings})
 if(NOT matched_code)
-  set(RunCMake_TEST_FAILED "Generated unity file doesn't include expected oder of source files")
+  set(RunCMake_TEST_FAILED "Generated unity file doesn't include expected order of source files")
   return()
 endif()
diff --git a/Tests/RunCMake/VS10Project/InterfaceLibSources-check.cmake b/Tests/RunCMake/VS10Project/InterfaceLibSources-check.cmake
new file mode 100644
index 0000000..bcdc101
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/InterfaceLibSources-check.cmake
@@ -0,0 +1,25 @@
+set(vcProjectFile "${RunCMake_TEST_BINARY_DIR}/iface.vcxproj")
+if(NOT EXISTS "${vcProjectFile}")
+  set(RunCMake_TEST_FAILED "Project file ${vcProjectFile} does not exist.")
+  return()
+endif()
+
+set(found_iface_h 0)
+file(STRINGS "${vcProjectFile}" lines)
+foreach(line IN LISTS lines)
+  if(line MATCHES "<([A-Za-z0-9_]+) +Include=.*iface\\.h")
+    set(rule "${CMAKE_MATCH_1}")
+    if(NOT rule STREQUAL "None")
+      set(RunCMake_TEST_FAILED "iface.h referenced as ${rule} instead of None in\n  ${vcProjectFile}")
+      return()
+    endif()
+    if(found_iface_h)
+      set(RunCMake_TEST_FAILED "iface.h referenced multiple times in\n  ${vcProjectFile}")
+      return()
+    endif()
+    set(found_iface_h 1)
+  endif()
+endforeach()
+if(NOT found_iface_h)
+  set(RunCMake_TEST_FAILED "iface.h not referenced in\n  ${vcProjectFile}")
+endif()
diff --git a/Tests/RunCMake/VS10Project/InterfaceLibSources.cmake b/Tests/RunCMake/VS10Project/InterfaceLibSources.cmake
new file mode 100644
index 0000000..3672be1
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/InterfaceLibSources.cmake
@@ -0,0 +1 @@
+add_library(iface INTERFACE iface.h)
diff --git a/Tests/RunCMake/VS10Project/RunCMakeTest.cmake b/Tests/RunCMake/VS10Project/RunCMakeTest.cmake
index 93ef603..e9f251a 100644
--- a/Tests/RunCMake/VS10Project/RunCMakeTest.cmake
+++ b/Tests/RunCMake/VS10Project/RunCMakeTest.cmake
@@ -6,6 +6,7 @@
 run_cmake(VsCsharpSourceGroup)
 run_cmake(VsCSharpCompilerOpts)
 run_cmake(ExplicitCMakeLists)
+run_cmake(InterfaceLibSources)
 run_cmake(RuntimeLibrary)
 run_cmake(SourceGroupCMakeLists)
 run_cmake(SourceGroupTreeCMakeLists)
diff --git a/Tests/RunCMake/VS10Project/VsPlatformToolset-check.cmake b/Tests/RunCMake/VS10Project/VsPlatformToolset-check.cmake
index 416220b..0d82d3f 100644
--- a/Tests/RunCMake/VS10Project/VsPlatformToolset-check.cmake
+++ b/Tests/RunCMake/VS10Project/VsPlatformToolset-check.cmake
@@ -31,6 +31,6 @@
 endif()
 
 if ("${NORMAL_TOOLSET}" STREQUAL "MyCustomToolset")
-  set(RunCMake_TEST_FAILED "Main toolset was overriden (it shouldn't)")
+  set(RunCMake_TEST_FAILED "Main toolset was overridden (it shouldn't)")
   return()
 endif()
diff --git a/Tests/RunCMake/VS10Project/iface.h b/Tests/RunCMake/VS10Project/iface.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/iface.h
diff --git a/Tests/RunCMake/VSSolution/CMakeLists.txt b/Tests/RunCMake/VSSolution/CMakeLists.txt
index 12cd3c7..74b3ff8 100644
--- a/Tests/RunCMake/VSSolution/CMakeLists.txt
+++ b/Tests/RunCMake/VSSolution/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/XcodeProject/CMakeLists.txt b/Tests/RunCMake/XcodeProject/CMakeLists.txt
index 12cd3c7..74b3ff8 100644
--- a/Tests/RunCMake/XcodeProject/CMakeLists.txt
+++ b/Tests/RunCMake/XcodeProject/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/XcodeProject/InterfaceLibSources-check.cmake b/Tests/RunCMake/XcodeProject/InterfaceLibSources-check.cmake
new file mode 100644
index 0000000..613951a
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/InterfaceLibSources-check.cmake
@@ -0,0 +1,16 @@
+set(xcProjectFile "${RunCMake_TEST_BINARY_DIR}/InterfaceLibSources.xcodeproj/project.pbxproj")
+if(NOT EXISTS "${xcProjectFile}")
+  set(RunCMake_TEST_FAILED "Project file ${xcProjectFile} does not exist.")
+  return()
+endif()
+
+set(found_iface_h 0)
+file(STRINGS "${xcProjectFile}" lines)
+foreach(line IN LISTS lines)
+  if(line MATCHES "PBXFileReference.*explicitFileType.*sourcecode\\.c\\.h.*iface\\.h")
+    set(found_iface_h 1)
+  endif()
+endforeach()
+if(NOT found_iface_h)
+  set(RunCMake_TEST_FAILED "iface.h not referenced in\n  ${xcProjectFile}")
+endif()
diff --git a/Tests/RunCMake/XcodeProject/InterfaceLibSources.cmake b/Tests/RunCMake/XcodeProject/InterfaceLibSources.cmake
new file mode 100644
index 0000000..3672be1
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/InterfaceLibSources.cmake
@@ -0,0 +1 @@
+add_library(iface INTERFACE iface.h)
diff --git a/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake b/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake
index 342dbbc..cd6fd06 100644
--- a/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake
+++ b/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake
@@ -2,6 +2,7 @@
 
 run_cmake(ExplicitCMakeLists)
 run_cmake(ImplicitCMakeLists)
+run_cmake(InterfaceLibSources)
 
 run_cmake(XcodeFileType)
 run_cmake(XcodeAttributeLocation)
diff --git a/Tests/RunCMake/XcodeProject/XcodeInstallIOS.cmake b/Tests/RunCMake/XcodeProject/XcodeInstallIOS.cmake
index ab31387..75da7b1 100644
--- a/Tests/RunCMake/XcodeProject/XcodeInstallIOS.cmake
+++ b/Tests/RunCMake/XcodeProject/XcodeInstallIOS.cmake
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 2.8.5)
+cmake_minimum_required(VERSION 3.3)
 
 project(XcodeInstallIOS)
 
diff --git a/Tests/RunCMake/XcodeProject/iface.h b/Tests/RunCMake/XcodeProject/iface.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/iface.h
diff --git a/Tests/RunCMake/add_dependencies/CMakeLists.txt b/Tests/RunCMake/add_dependencies/CMakeLists.txt
index 12cd3c7..74b3ff8 100644
--- a/Tests/RunCMake/add_dependencies/CMakeLists.txt
+++ b/Tests/RunCMake/add_dependencies/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/alias_targets/CMakeLists.txt b/Tests/RunCMake/alias_targets/CMakeLists.txt
index 12cd3c7..74b3ff8 100644
--- a/Tests/RunCMake/alias_targets/CMakeLists.txt
+++ b/Tests/RunCMake/alias_targets/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/alias_targets/invalid-name.cmake b/Tests/RunCMake/alias_targets/invalid-name.cmake
index bbd39e3..01983e5 100644
--- a/Tests/RunCMake/alias_targets/invalid-name.cmake
+++ b/Tests/RunCMake/alias_targets/invalid-name.cmake
@@ -1,4 +1,4 @@
-
+cmake_minimum_required(VERSION 2.8.12)
 enable_language(CXX)
 
 add_library(foo empty.cpp)
diff --git a/Tests/RunCMake/build_command/CMakeLists.txt b/Tests/RunCMake/build_command/CMakeLists.txt
index 73e6a78..f1a83e8 100644
--- a/Tests/RunCMake/build_command/CMakeLists.txt
+++ b/Tests/RunCMake/build_command/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 if(NOT NoProject)
   project(${RunCMake_TEST} NONE)
 endif()
diff --git a/Tests/RunCMake/cmake_language/call_invalid_command.cmake b/Tests/RunCMake/cmake_language/call_invalid_command.cmake
index 88bf08c..585aad4 100644
--- a/Tests/RunCMake/cmake_language/call_invalid_command.cmake
+++ b/Tests/RunCMake/cmake_language/call_invalid_command.cmake
@@ -9,6 +9,6 @@
     OUTPUT_QUIET ERROR_QUIET
     RESULT_VARIABLE result)
   if (NOT result)
-    message (SEND_ERROR "cmake_language(CALL ${command}) unexpectedly successfull.")
+    message (SEND_ERROR "cmake_language(CALL ${command}) unexpectedly successful.")
   endif()
 endforeach()
diff --git a/Tests/RunCMake/cmake_minimum_required/Before2812-stderr.txt b/Tests/RunCMake/cmake_minimum_required/Before2812-stderr.txt
new file mode 100644
index 0000000..7d40dcb
--- /dev/null
+++ b/Tests/RunCMake/cmake_minimum_required/Before2812-stderr.txt
@@ -0,0 +1,26 @@
+^CMake Deprecation Warning at Before2812.cmake:1 \(cmake_minimum_required\):
+  Compatibility with CMake < 2.8.12 will be removed from a future version of
+  CMake.
+
+  Update the VERSION argument <min> value or use a ...<max> suffix to tell
+  CMake that the project does not need compatibility with older versions.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
++
+CMake Deprecation Warning at Before2812.cmake:2 \(cmake_policy\):
+  Compatibility with CMake < 2.8.12 will be removed from a future version of
+  CMake.
+
+  Update the VERSION argument <min> value or use a ...<max> suffix to tell
+  CMake that the project does not need compatibility with older versions.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
++
+CMake Deprecation Warning at Before2812.cmake:6 \(cmake_policy\):
+  Compatibility with CMake < 2.8.12 will be removed from a future version of
+  CMake.
+
+  Update the VERSION argument <min> value or use a ...<max> suffix to tell
+  CMake that the project does not need compatibility with older versions.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/cmake_minimum_required/Before2812.cmake b/Tests/RunCMake/cmake_minimum_required/Before2812.cmake
new file mode 100644
index 0000000..220e359
--- /dev/null
+++ b/Tests/RunCMake/cmake_minimum_required/Before2812.cmake
@@ -0,0 +1,6 @@
+cmake_minimum_required(VERSION 2.8.11)
+cmake_policy(VERSION 2.6)
+cmake_policy(PUSH)
+cmake_policy(VERSION 2.6) # simulate pre-3.18 install(EXPORT)-generated call
+cmake_policy(POP)
+cmake_policy(VERSION 2.8.11)
diff --git a/Tests/RunCMake/cmake_minimum_required/CMakeLists.txt b/Tests/RunCMake/cmake_minimum_required/CMakeLists.txt
index e8db6b0..667561e 100644
--- a/Tests/RunCMake/cmake_minimum_required/CMakeLists.txt
+++ b/Tests/RunCMake/cmake_minimum_required/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8)
+cmake_minimum_required(VERSION 2.8.12)
 project(${RunCMake_TEST} NONE)
-include(${RunCMake_TEST}.cmake)
+include(${RunCMake_TEST}.cmake NO_POLICY_SCOPE)
diff --git a/Tests/RunCMake/cmake_minimum_required/CompatBefore24-stderr.txt b/Tests/RunCMake/cmake_minimum_required/CompatBefore24-stderr.txt
index a874466..81d26d2 100644
--- a/Tests/RunCMake/cmake_minimum_required/CompatBefore24-stderr.txt
+++ b/Tests/RunCMake/cmake_minimum_required/CompatBefore24-stderr.txt
@@ -1,3 +1,12 @@
+^CMake Deprecation Warning at CompatBefore24.cmake:1 \(cmake_minimum_required\):
+  Compatibility with CMake < 2.8.12 will be removed from a future version of
+  CMake.
+
+  Update the VERSION argument <min> value or use a ...<max> suffix to tell
+  CMake that the project does not need compatibility with older versions.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
++
 CMake Error in CMakeLists.txt:
   You have set CMAKE_BACKWARDS_COMPATIBILITY to a CMake version less than
   2.4.  This version of CMake only supports backwards compatibility with
diff --git a/Tests/RunCMake/cmake_minimum_required/RunCMakeTest.cmake b/Tests/RunCMake/cmake_minimum_required/RunCMakeTest.cmake
index 1030211..3a959bb 100644
--- a/Tests/RunCMake/cmake_minimum_required/RunCMakeTest.cmake
+++ b/Tests/RunCMake/cmake_minimum_required/RunCMakeTest.cmake
@@ -4,6 +4,7 @@
 run_cmake(CompatBefore24)
 run_cmake(Future)
 run_cmake(PolicyBefore24)
+run_cmake(Before2812)
 run_cmake(Range)
 run_cmake(RangeBad)
 run_cmake(Unknown)
diff --git a/Tests/RunCMake/configure_file/NoSourcePermissions.cmake b/Tests/RunCMake/configure_file/NoSourcePermissions.cmake
new file mode 100644
index 0000000..c6ad131
--- /dev/null
+++ b/Tests/RunCMake/configure_file/NoSourcePermissions.cmake
@@ -0,0 +1,10 @@
+configure_file(NoSourcePermissions.sh NoSourcePermissions.sh.out
+               NO_SOURCE_PERMISSIONS)
+
+if (UNIX)
+  execute_process(COMMAND ${CMAKE_CURRENT_BINARY_DIR}/NoSourcePermissions.sh.out
+                  RESULT_VARIABLE result)
+  if (result EQUAL "0")
+    message(FATAL_ERROR "Copied file has executable permissions")
+  endif()
+endif()
diff --git a/Tests/RunCMake/configure_file/NoSourcePermissions.sh b/Tests/RunCMake/configure_file/NoSourcePermissions.sh
new file mode 100755
index 0000000..0aa8f41
--- /dev/null
+++ b/Tests/RunCMake/configure_file/NoSourcePermissions.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+#Testing NO_SOURCE_PERMISSIONS option of configure_file.
diff --git a/Tests/RunCMake/configure_file/RunCMakeTest.cmake b/Tests/RunCMake/configure_file/RunCMakeTest.cmake
index 32a0770..71694fb 100644
--- a/Tests/RunCMake/configure_file/RunCMakeTest.cmake
+++ b/Tests/RunCMake/configure_file/RunCMakeTest.cmake
@@ -15,6 +15,7 @@
 run_cmake(NewLineStyle-WrongArg)
 run_cmake(NewLineStyle-ValidArg)
 run_cmake(NewLineStyle-COPYONLY)
+run_cmake(NoSourcePermissions)
 
 if(RunCMake_GENERATOR MATCHES "Make")
   # Use a single build tree for a few tests without cleaning.
diff --git a/Tests/RunCMake/ctest_memcheck/CMakeLists.txt.in b/Tests/RunCMake/ctest_memcheck/CMakeLists.txt.in
index 3b8edf4..68a0fcb 100644
--- a/Tests/RunCMake/ctest_memcheck/CMakeLists.txt.in
+++ b/Tests/RunCMake/ctest_memcheck/CMakeLists.txt.in
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 2.8.9)
+cmake_minimum_required(VERSION 3.3)
 project(CTestTestMemcheck@CASE_NAME@ NONE)
 include(CTest)
 
diff --git a/Tests/RunCMake/interface_library/genex_link-result.txt b/Tests/RunCMake/ctest_memcheck/DummyCudaMemcheck-result.txt
similarity index 100%
copy from Tests/RunCMake/interface_library/genex_link-result.txt
copy to Tests/RunCMake/ctest_memcheck/DummyCudaMemcheck-result.txt
diff --git a/Tests/RunCMake/ctest_memcheck/DummyCudaMemcheck-stderr.txt b/Tests/RunCMake/ctest_memcheck/DummyCudaMemcheck-stderr.txt
new file mode 100644
index 0000000..d302b5c
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/DummyCudaMemcheck-stderr.txt
@@ -0,0 +1 @@
+Defect count: 23
diff --git a/Tests/RunCMake/ctest_memcheck/DummyCudaMemcheck-stdout.txt b/Tests/RunCMake/ctest_memcheck/DummyCudaMemcheck-stdout.txt
new file mode 100644
index 0000000..034ee1e
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/DummyCudaMemcheck-stdout.txt
@@ -0,0 +1,13 @@
+Memory checking results:
+Uninitialized __global__ memory read - 1
+Unused memory - 1
+Host API memory access error - 1
+Barrier error - 2
+Invalid __global__ read - 1
+cudaErrorLaunchFailure - 2
+Fatal UVM GPU fault - 1
+Fatal UVM CPU fault - 1
+Memory leak - 1
+Potential WAR hazard detected - 4
+Potential RAW hazard detected - 4
+Race reported - 4
diff --git a/Tests/RunCMake/ctest_memcheck/RunCMakeTest.cmake b/Tests/RunCMake/ctest_memcheck/RunCMakeTest.cmake
index ab4c5ab..2b3165b 100644
--- a/Tests/RunCMake/ctest_memcheck/RunCMakeTest.cmake
+++ b/Tests/RunCMake/ctest_memcheck/RunCMakeTest.cmake
@@ -175,3 +175,15 @@
 unset(CTEST_EXTRA_CODE)
 unset(CTEST_MEMCHECK_ARGS)
 unset(CTEST_SUFFIX_CODE)
+
+#-----------------------------------------------------------------------------
+set(CMAKELISTS_EXTRA_CODE
+"add_test(NAME TestSan COMMAND \"${CMAKE_COMMAND}\"
+-P \"${RunCMake_SOURCE_DIR}/testCudaMemcheck.cmake\")
+")
+set(CTEST_SUFFIX_CODE "message(\"Defect count: \${defect_count}\")")
+set(CTEST_MEMCHECK_ARGS "DEFECT_COUNT defect_count")
+run_mc_test(DummyCudaMemcheck "${PSEUDO_CUDA_MEMCHECK}")
+unset(CTEST_MEMCHECK_ARGS)
+unset(CTEST_SUFFIX_CODE)
+unset(CTEST_EXTRA_CODE)
diff --git a/Tests/RunCMake/ctest_memcheck/test.cmake.in b/Tests/RunCMake/ctest_memcheck/test.cmake.in
index 50b4b6a..eedf080 100644
--- a/Tests/RunCMake/ctest_memcheck/test.cmake.in
+++ b/Tests/RunCMake/ctest_memcheck/test.cmake.in
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 2.8.9)
+cmake_minimum_required(VERSION 3.3)
 
 # Settings:
 set(CTEST_SITE                          "@SITE@")
diff --git a/Tests/RunCMake/ctest_memcheck/testCudaMemcheck.cmake b/Tests/RunCMake/ctest_memcheck/testCudaMemcheck.cmake
new file mode 100644
index 0000000..adc7a1a
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/testCudaMemcheck.cmake
@@ -0,0 +1,279 @@
+# this file simulates an execution of cuda-memcheck
+
+set(LOG_FILE "$ENV{PSEUDO_LOGFILE}")
+message("LOG_FILE=[${LOG_FILE}]")
+
+# clear the log file
+file(REMOVE "${LOG_FILE}")
+
+# create an error of each type of sanitizer tool and failure
+
+# initcheck
+file(APPEND "${LOG_FILE}"
+"========= CUDA-MEMCHECK
+========= Uninitialized __global__ memory read of size 4
+=========     at 0x00000020 in test(int*, int*)
+=========     by thread (0,0,0) in block (0,0,0)
+=========     Address 0x1303d80000
+=========     Saved host backtrace up to driver entry point
+=========     Host Frame:/lib64/libcuda.so.1 (cuLaunchKernel + 0x346) [0x297db6]
+=========     Host Frame:./uninit-read [0x101d9]
+=========     Host Frame:./uninit-read [0x10267]
+=========     Host Frame:./uninit-read [0x465b5]
+=========     Host Frame:./uninit-read [0x3342]
+=========     Host Frame:./uninit-read [0x3143]
+=========     Host Frame:/lib64/libc.so.6 (__libc_start_main + 0xf5) [0x22505]
+=========     Host Frame:./uninit-read [0x31e2]
+=========
+========= Unused memory in allocation 0x1303d80000 of size 16 bytes
+=========     Not written any memory.
+=========     100.00% of allocation were unused.
+=========     Saved host backtrace up to driver entry point
+=========     Host Frame:/lib64/libcuda.so.1 (cuMemAlloc_v2 + 0x1b7) [0x26ec97]
+=========     Host Frame:./uninit-read [0x2bbd3]
+=========     Host Frame:./uninit-read [0x71ab]
+=========     Host Frame:./uninit-read [0x3c84f]
+=========     Host Frame:./uninit-read [0x3111]
+=========     Host Frame:/lib64/libc.so.6 (__libc_start_main + 0xf5) [0x22505]
+=========     Host Frame:./uninit-read [0x31e2]
+=========
+========= Host API memory access error at host access to 0x1303fd1400 of size 25600 bytes
+=========     Uninitialized access at 0x1303fd4600 on access by cudaMemcopy source.
+=========     Saved host backtrace up to driver entry point at error
+=========     Host Frame:/usr/lib/x86_64-linux-gnu/libcuda.so.1 (cuMemcpyDtoH_v2 + 0x1ec) [0x29200c]
+=========     Host Frame:/usr/local/cuda/targets/x86_64-linux/lib/libcudart.so.10.1 [0x38aaa]
+=========     Host Frame:/usr/local/cuda/targets/x86_64-linux/lib/libcudart.so.10.1 [0x18946]
+=========     Host Frame:/usr/local/cuda/targets/x86_64-linux/lib/libcudart.so.10.1 (cudaMemcpy + 0x1a2) [0x3b8c2]
+=========     Host Frame:/something/somewhere [0xcafe]
+=========
+========= ERROR SUMMARY: 2 errors
+")
+
+
+# synccheck
+file(APPEND "${LOG_FILE}"
+"========= CUDA-MEMCHECK
+========= Barrier error detected. Divergent thread(s) in warp
+=========     at 0x00000058 in test(int*, int*)
+=========     by thread (1,0,0) in block (0,0,0)
+=========     Device Frame:test(int*, int*) (test(int*, int*) : 0x60)
+=========     Saved host backtrace up to driver entry point at kernel launch time
+=========     Host Frame:/lib64/libcuda.so.1 (cuLaunchKernel + 0x346) [0x297db6]
+=========     Host Frame:./sync [0x101d9]
+=========     Host Frame:./sync [0x10267]
+=========     Host Frame:./sync [0x465b5]
+=========     Host Frame:./sync [0x3342]
+=========     Host Frame:./sync [0x314a]
+=========     Host Frame:/lib64/libc.so.6 (__libc_start_main + 0xf5) [0x22505]
+=========     Host Frame:./sync [0x31e2]
+=========
+========= Barrier error detected. Divergent thread(s) in warp
+=========     at 0x00000058 in test(int*, int*)
+=========     by thread (0,0,0) in block (0,0,0)
+=========     Device Frame:test(int*, int*) (test(int*, int*) : 0x60)
+=========     Saved host backtrace up to driver entry point at kernel launch time
+=========     Host Frame:/lib64/libcuda.so.1 (cuLaunchKernel + 0x346) [0x297db6]
+=========     Host Frame:./sync [0x101d9]
+=========     Host Frame:./sync [0x10267]
+=========     Host Frame:./sync [0x465b5]
+=========     Host Frame:./sync [0x3342]
+=========     Host Frame:./sync [0x314a]
+=========     Host Frame:/lib64/libc.so.6 (__libc_start_main + 0xf5) [0x22505]
+=========     Host Frame:./sync [0x31e2]
+=========
+========= ERROR SUMMARY: 2 errors
+")
+
+# memcheck
+file(APPEND "${LOG_FILE}"
+"========= CUDA-MEMCHECK
+========= Invalid __global__ read of size 4
+=========     at 0x00000020 in test(int*, int*)
+=========     by thread (0,0,0) in block (0,0,0)
+=========     Address 0x00000000 is out of bounds
+=========     Saved host backtrace up to driver entry point at kernel launch time
+=========     Host Frame:/lib64/libcuda.so.1 (cuLaunchKernel + 0x346) [0x297db6]
+=========     Host Frame:./invalid-read [0x101d9]
+=========     Host Frame:./invalid-read [0x10267]
+=========     Host Frame:./invalid-read [0x465b5]
+=========     Host Frame:./invalid-read [0x3342]
+=========     Host Frame:./invalid-read [0x3142]
+=========     Host Frame:/lib64/libc.so.6 (__libc_start_main + 0xf5) [0x22505]
+=========     Host Frame:./invalid-read [0x31e2]
+=========
+========= Program hit cudaErrorLaunchFailure (error 719) due to \"unspecified launch failure\" on CUDA API call to cudaDeviceSynchronize.
+=========     Saved host backtrace up to driver entry point at error
+=========     Host Frame:/lib64/libcuda.so.1 [0x3ac5a3]
+=========     Host Frame:./invalid-read [0x2e576]
+=========     Host Frame:./invalid-read [0x3147]
+=========     Host Frame:/lib64/libc.so.6 (__libc_start_main + 0xf5) [0x22505]
+=========     Host Frame:./invalid-read [0x31e2]
+=========
+========= Program hit cudaErrorLaunchFailure (error 719) due to \"unspecified launch failure\" on CUDA API call to cudaFree.
+=========     Saved host backtrace up to driver entry point at error
+=========     Host Frame:/lib64/libcuda.so.1 [0x3ac5a3]
+=========     Host Frame:./invalid-read [0x3c106]
+=========     Host Frame:./invalid-read [0x3150]
+=========     Host Frame:/lib64/libc.so.6 (__libc_start_main + 0xf5) [0x22505]
+=========     Host Frame:./invalid-read [0x31e2]
+=========
+========= Fatal UVM GPU fault of type invalid pde due to invalid address
+=========     during atomic access to address 0x20be00000
+=========
+========= Fatal UVM CPU fault due to invalid operation
+=========     during read access to address 0x1357c92000
+=========
+========= LEAK SUMMARY: 0 bytes leaked in 0 allocations
+========= ERROR SUMMARY: 3 errors
+")
+
+# memcheck with leak-check full
+file(APPEND "${LOG_FILE}"
+"========= CUDA-MEMCHECK
+========= Leaked 10 bytes at 0x1303d80000
+=========     Saved host backtrace up to driver entry point at cudaMalloc time
+=========     Host Frame:/lib64/libcuda.so.1 (cuMemAlloc_v2 + 0x1b7) [0x26ec97]
+=========     Host Frame:./leak [0x2bab3]
+=========     Host Frame:./leak [0x708b]
+=========     Host Frame:./leak [0x3c72f]
+=========     Host Frame:./leak [0x3113]
+=========     Host Frame:/lib64/libc.so.6 (__libc_start_main + 0xf5) [0x22505]
+=========     Host Frame:./leak [0x3174]
+=========
+========= LEAK SUMMARY: 10 bytes leaked in 1 allocations
+========= ERROR SUMMARY: 1 error
+")
+
+# racecheck with racecheck-report all
+file(APPEND "${LOG_FILE}"
+"========= CUDA-MEMCHECK
+========= WARN:(Warp Level Programming) Potential WAR hazard detected at __shared__ 0x3 in block (0, 0, 0) :
+=========     Read Thread (31, 0, 0) at 0x00000170 in ./race.cu:4:test(int*, int*)
+=========     Write Thread (0, 0, 0) at 0x000001a8 in ./race.cu:4:test(int*, int*)
+=========     Current Value : 0, Incoming Value : 0
+=========     Saved host backtrace up to driver entry point at kernel launch time
+=========     Host Frame:/lib64/libcuda.so.1 (cuLaunchKernel + 0x346) [0x297db6]
+=========     Host Frame:./race [0x101d9]
+=========     Host Frame:./race [0x10267]
+=========     Host Frame:./race [0x465b5]
+=========     Host Frame:./race [0x3342]
+=========     Host Frame:./race [0x314a]
+=========     Host Frame:/lib64/libc.so.6 (__libc_start_main + 0xf5) [0x22505]
+=========     Host Frame:./race [0x31e2]
+=========
+========= WARN:(Warp Level Programming) Potential WAR hazard detected at __shared__ 0x2 in block (0, 0, 0) :
+=========     Read Thread (31, 0, 0) at 0x00000170 in ./race.cu:4:test(int*, int*)
+=========     Write Thread (0, 0, 0) at 0x000001a8 in ./race.cu:4:test(int*, int*)
+=========     Current Value : 0, Incoming Value : 0
+=========     Saved host backtrace up to driver entry point at kernel launch time
+=========     Host Frame:/lib64/libcuda.so.1 (cuLaunchKernel + 0x346) [0x297db6]
+=========     Host Frame:./race [0x101d9]
+=========     Host Frame:./race [0x10267]
+=========     Host Frame:./race [0x465b5]
+=========     Host Frame:./race [0x3342]
+=========     Host Frame:./race [0x314a]
+=========     Host Frame:/lib64/libc.so.6 (__libc_start_main + 0xf5) [0x22505]
+=========     Host Frame:./race [0x31e2]
+=========
+========= WARN:(Warp Level Programming) Potential WAR hazard detected at __shared__ 0x1 in block (0, 0, 0) :
+=========     Read Thread (31, 0, 0) at 0x00000170 in ./race.cu:4:test(int*, int*)
+=========     Write Thread (0, 0, 0) at 0x000001a8 in ./race.cu:4:test(int*, int*)
+=========     Current Value : 0, Incoming Value : 0
+=========     Saved host backtrace up to driver entry point at kernel launch time
+=========     Host Frame:/lib64/libcuda.so.1 (cuLaunchKernel + 0x346) [0x297db6]
+=========     Host Frame:./race [0x101d9]
+=========     Host Frame:./race [0x10267]
+=========     Host Frame:./race [0x465b5]
+=========     Host Frame:./race [0x3342]
+=========     Host Frame:./race [0x314a]
+=========     Host Frame:/lib64/libc.so.6 (__libc_start_main + 0xf5) [0x22505]
+=========     Host Frame:./race [0x31e2]
+=========
+========= WARN:(Warp Level Programming) Potential WAR hazard detected at __shared__ 0x0 in block (0, 0, 0) :
+=========     Read Thread (31, 0, 0) at 0x00000170 in ./race.cu:4:test(int*, int*)
+=========     Write Thread (0, 0, 0) at 0x000001a8 in ./race.cu:4:test(int*, int*)
+=========     Current Value : 0, Incoming Value : 1
+=========     Saved host backtrace up to driver entry point at kernel launch time
+=========     Host Frame:/lib64/libcuda.so.1 (cuLaunchKernel + 0x346) [0x297db6]
+=========     Host Frame:./race [0x101d9]
+=========     Host Frame:./race [0x10267]
+=========     Host Frame:./race [0x465b5]
+=========     Host Frame:./race [0x3342]
+=========     Host Frame:./race [0x314a]
+=========     Host Frame:/lib64/libc.so.6 (__libc_start_main + 0xf5) [0x22505]
+=========     Host Frame:./race [0x31e2]
+=========
+========= WARN:(Warp Level Programming) Potential RAW hazard detected at __shared__ 0x3 in block (0, 0, 0) :
+=========     Write Thread (31, 0, 0) at 0x00000148 in ./race.cu:3:test(int*, int*)
+=========     Read Thread (0, 0, 0) at 0x00000170 in ./race.cu:4:test(int*, int*)
+=========     Current Value : 0
+=========     Saved host backtrace up to driver entry point at kernel launch time
+=========     Host Frame:/lib64/libcuda.so.1 (cuLaunchKernel + 0x346) [0x297db6]
+=========     Host Frame:./race [0x101d9]
+=========     Host Frame:./race [0x10267]
+=========     Host Frame:./race [0x465b5]
+=========     Host Frame:./race [0x3342]
+=========     Host Frame:./race [0x314a]
+=========     Host Frame:/lib64/libc.so.6 (__libc_start_main + 0xf5) [0x22505]
+=========     Host Frame:./race [0x31e2]
+=========
+========= WARN:(Warp Level Programming) Potential RAW hazard detected at __shared__ 0x2 in block (0, 0, 0) :
+=========     Write Thread (31, 0, 0) at 0x00000148 in ./race.cu:3:test(int*, int*)
+=========     Read Thread (0, 0, 0) at 0x00000170 in ./race.cu:4:test(int*, int*)
+=========     Current Value : 0
+=========     Saved host backtrace up to driver entry point at kernel launch time
+=========     Host Frame:/lib64/libcuda.so.1 (cuLaunchKernel + 0x346) [0x297db6]
+=========     Host Frame:./race [0x101d9]
+=========     Host Frame:./race [0x10267]
+=========     Host Frame:./race [0x465b5]
+=========     Host Frame:./race [0x3342]
+=========     Host Frame:./race [0x314a]
+=========     Host Frame:/lib64/libc.so.6 (__libc_start_main + 0xf5) [0x22505]
+=========     Host Frame:./race [0x31e2]
+=========
+========= WARN:(Warp Level Programming) Potential RAW hazard detected at __shared__ 0x1 in block (0, 0, 0) :
+=========     Write Thread (31, 0, 0) at 0x00000148 in ./race.cu:3:test(int*, int*)
+=========     Read Thread (0, 0, 0) at 0x00000170 in ./race.cu:4:test(int*, int*)
+=========     Current Value : 0
+=========     Saved host backtrace up to driver entry point at kernel launch time
+=========     Host Frame:/lib64/libcuda.so.1 (cuLaunchKernel + 0x346) [0x297db6]
+=========     Host Frame:./race [0x101d9]
+=========     Host Frame:./race [0x10267]
+=========     Host Frame:./race [0x465b5]
+=========     Host Frame:./race [0x3342]
+=========     Host Frame:./race [0x314a]
+=========     Host Frame:/lib64/libc.so.6 (__libc_start_main + 0xf5) [0x22505]
+=========     Host Frame:./race [0x31e2]
+=========
+========= WARN:(Warp Level Programming) Potential RAW hazard detected at __shared__ 0x0 in block (0, 0, 0) :
+=========     Write Thread (31, 0, 0) at 0x00000148 in ./race.cu:3:test(int*, int*)
+=========     Read Thread (0, 0, 0) at 0x00000170 in ./race.cu:4:test(int*, int*)
+=========     Current Value : 0
+=========     Saved host backtrace up to driver entry point at kernel launch time
+=========     Host Frame:/lib64/libcuda.so.1 (cuLaunchKernel + 0x346) [0x297db6]
+=========     Host Frame:./race [0x101d9]
+=========     Host Frame:./race [0x10267]
+=========     Host Frame:./race [0x465b5]
+=========     Host Frame:./race [0x3342]
+=========     Host Frame:./race [0x314a]
+=========     Host Frame:/lib64/libc.so.6 (__libc_start_main + 0xf5) [0x22505]
+=========     Host Frame:./race [0x31e2]
+=========
+========= WARN: Race reported between Read access at 0x00000170 in ./race.cu:4:test(int*, int*)
+=========     and Write access at 0x00000148 in ./race.cu:3:test(int*, int*) [4 hazards]
+=========     and Write access at 0x000001a8 in ./race.cu:4:test(int*, int*) [4 hazards]
+=========
+========= WARN: Race reported between Write access at 0x00000148 in ./race.cu:3:test(int*, int*)
+=========     and Write access at 0x00000148 in ./race.cu:3:test(int*, int*) [124 hazards]
+=========     and Read access at 0x00000170 in ./race.cu:4:test(int*, int*) [4 hazards]
+=========
+========= WARN: Race reported between Write access at 0x000001a8 in ./race.cu:4:test(int*, int*)
+=========     and Write access at 0x000001a8 in ./race.cu:4:test(int*, int*) [124 hazards]
+=========     and Read access at 0x00000170 in ./race.cu:4:test(int*, int*) [4 hazards]
+=========
+========= WARN: Race reported between Write access at 0x00000148 in ./race.cu:3:test(int*, int*)
+=========     and Write access at 0x00000148 in ./race.cu:3:test(int*, int*) [124 hazards]
+=========     and Read access at 0x00000170 in ./race.cu:4:test(int*, int*) [4 hazards]
+=========
+========= RACECHECK SUMMARY: 12 hazards displayed (0 errors, 12 warnings)
+")
diff --git a/Tests/RunCMake/ctest_update/test.cmake.in b/Tests/RunCMake/ctest_update/test.cmake.in
index 25b8423..01aab26 100644
--- a/Tests/RunCMake/ctest_update/test.cmake.in
+++ b/Tests/RunCMake/ctest_update/test.cmake.in
@@ -10,7 +10,7 @@
 set(CTEST_CMAKE_GENERATOR_TOOLSET       "@RunCMake_GENERATOR_TOOLSET@")
 set(CTEST_BUILD_CONFIGURATION           "$ENV{CMAKE_CONFIG_TYPE}")
 
-# FIXME: update test to do someting meaningful with this.
+# FIXME: update test to do something meaningful with this.
 set(CTEST_UPDATE_COMMAND                "not-actually-used")
 
 set(ctest_test_args "@CASE_CTEST_UPDATE_ARGS@")
diff --git a/Tests/RunCMake/export/CMakeLists.txt b/Tests/RunCMake/export/CMakeLists.txt
index 12cd3c7..74b3ff8 100644
--- a/Tests/RunCMake/export/CMakeLists.txt
+++ b/Tests/RunCMake/export/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/interface_library/global-interface-result.txt b/Tests/RunCMake/file/DOWNLOAD-no-save-hash-result.txt
similarity index 100%
copy from Tests/RunCMake/interface_library/global-interface-result.txt
copy to Tests/RunCMake/file/DOWNLOAD-no-save-hash-result.txt
diff --git a/Tests/RunCMake/file/DOWNLOAD-no-save-hash-stderr.txt b/Tests/RunCMake/file/DOWNLOAD-no-save-hash-stderr.txt
new file mode 100644
index 0000000..b0f0d19
--- /dev/null
+++ b/Tests/RunCMake/file/DOWNLOAD-no-save-hash-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at DOWNLOAD-no-save-hash\.cmake:[0-9]+ \(file\):
+  file DOWNLOAD cannot calculate hash if file is not saved\.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/file/DOWNLOAD-no-save-hash.cmake b/Tests/RunCMake/file/DOWNLOAD-no-save-hash.cmake
new file mode 100644
index 0000000..ce959a7
--- /dev/null
+++ b/Tests/RunCMake/file/DOWNLOAD-no-save-hash.cmake
@@ -0,0 +1,8 @@
+if(NOT "${CMAKE_CURRENT_SOURCE_DIR}" MATCHES "^/")
+  set(slash /)
+endif()
+file(DOWNLOAD
+  "file://${slash}${CMAKE_CURRENT_SOURCE_DIR}/DOWNLOAD-no-save-md5.txt"
+  EXPECTED_HASH MD5=55555555555555555555555555555555
+  STATUS status
+  )
diff --git a/Tests/RunCMake/file/DOWNLOAD-no-save-hash.txt b/Tests/RunCMake/file/DOWNLOAD-no-save-hash.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/file/DOWNLOAD-no-save-hash.txt
diff --git a/Tests/RunCMake/file/RunCMakeTest.cmake b/Tests/RunCMake/file/RunCMakeTest.cmake
index a4de1d3..8d84943 100644
--- a/Tests/RunCMake/file/RunCMakeTest.cmake
+++ b/Tests/RunCMake/file/RunCMakeTest.cmake
@@ -11,6 +11,7 @@
 run_cmake(DOWNLOAD-tls-cainfo-not-set)
 run_cmake(DOWNLOAD-tls-verify-not-set)
 run_cmake(DOWNLOAD-pass-not-set)
+run_cmake(DOWNLOAD-no-save-hash)
 run_cmake(TOUCH)
 run_cmake(TOUCH-error-in-source-directory)
 run_cmake(TOUCH-error-missing-directory)
diff --git a/Tests/RunCMake/find_dependency/CMakeLists.txt b/Tests/RunCMake/find_dependency/CMakeLists.txt
index 12cd3c7..74b3ff8 100644
--- a/Tests/RunCMake/find_dependency/CMakeLists.txt
+++ b/Tests/RunCMake/find_dependency/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/find_package/CMakeLists.txt b/Tests/RunCMake/find_package/CMakeLists.txt
index 12cd3c7..74b3ff8 100644
--- a/Tests/RunCMake/find_package/CMakeLists.txt
+++ b/Tests/RunCMake/find_package/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/find_package/MissingNormalWarnNoModuleOld-stderr.txt b/Tests/RunCMake/find_package/MissingNormalWarnNoModuleOld-stderr.txt
index b336b56..ebfd7d0 100644
--- a/Tests/RunCMake/find_package/MissingNormalWarnNoModuleOld-stderr.txt
+++ b/Tests/RunCMake/find_package/MissingNormalWarnNoModuleOld-stderr.txt
@@ -1,9 +1,10 @@
 CMake Warning \(dev\) at MissingNormalWarnNoModuleOld.cmake:2 \(find_package\):
-  find_package called without NO_MODULE option and no FindNotHere.cmake
-  module is in CMAKE_MODULE_PATH.  Add NO_MODULE to exclusively request
-  Config mode and search for a package configuration file provided by NotHere
-  \(NotHereConfig.cmake or nothere-config.cmake\).  Otherwise make
-  FindNotHere.cmake available in CMAKE_MODULE_PATH.
+  find_package called without either MODULE or CONFIG option and no
+  FindNotHere.cmake module is in CMAKE_MODULE_PATH.  Add MODULE to
+  exclusively request Module mode and fail if FindNotHere.cmake is missing.
+  Add CONFIG to exclusively request Config mode and search for a package
+  configuration file provided by NotHere \(NotHereConfig.cmake or
+  nothere-config.cmake\).
 
   \(Variable CMAKE_FIND_PACKAGE_WARN_NO_MODULE enabled this warning.\)
 Call Stack \(most recent call first\):
diff --git a/Tests/RunCMake/find_program/BundleSpaceInName-stdout.txt b/Tests/RunCMake/find_program/BundleSpaceInName-stdout.txt
new file mode 100644
index 0000000..331d465
--- /dev/null
+++ b/Tests/RunCMake/find_program/BundleSpaceInName-stdout.txt
@@ -0,0 +1 @@
+-- FakeApp_EXECUTABLE='.*/Tests/RunCMake/find_program/BundleSpaceInName-build/Fake app.app/Contents/MacOS/Fake app'
diff --git a/Tests/RunCMake/find_program/BundleSpaceInName.cmake b/Tests/RunCMake/find_program/BundleSpaceInName.cmake
new file mode 100644
index 0000000..9152d5b
--- /dev/null
+++ b/Tests/RunCMake/find_program/BundleSpaceInName.cmake
@@ -0,0 +1,8 @@
+set(fakeApp "${CMAKE_CURRENT_BINARY_DIR}/Fake app.app/Contents/MacOS/Fake app")
+file(WRITE "${fakeApp}" "#!/bin/sh\n")
+execute_process(COMMAND chmod a+rx "${fakeApp}")
+
+find_program(FakeApp_EXECUTABLE NAMES "Fake app" NO_DEFAULT_PATH
+  PATHS "${CMAKE_CURRENT_BINARY_DIR}"
+)
+message(STATUS "FakeApp_EXECUTABLE='${FakeApp_EXECUTABLE}'")
diff --git a/Tests/RunCMake/find_program/CMP0109-Common.cmake b/Tests/RunCMake/find_program/CMP0109-Common.cmake
new file mode 100644
index 0000000..525413a
--- /dev/null
+++ b/Tests/RunCMake/find_program/CMP0109-Common.cmake
@@ -0,0 +1,7 @@
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/ExeNoRead" "#!/bin/sh\n")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/ReadNoExe" "#ReadNoExe")
+execute_process(COMMAND chmod -r+x "${CMAKE_CURRENT_BINARY_DIR}/ExeNoRead")
+find_program(ExeNoRead_EXECUTABLE NAMES ExeNoRead NO_DEFAULT_PATH PATHS "${CMAKE_CURRENT_BINARY_DIR}")
+message(STATUS "ExeNoRead_EXECUTABLE='${ExeNoRead_EXECUTABLE}'")
+find_program(ReadNoExe_EXECUTABLE NAMES ReadNoExe NO_DEFAULT_PATH PATHS "${CMAKE_CURRENT_BINARY_DIR}")
+message(STATUS "ReadNoExe_EXECUTABLE='${ReadNoExe_EXECUTABLE}'")
diff --git a/Tests/RunCMake/find_program/CMP0109-NEW-stdout.txt b/Tests/RunCMake/find_program/CMP0109-NEW-stdout.txt
new file mode 100644
index 0000000..2744463
--- /dev/null
+++ b/Tests/RunCMake/find_program/CMP0109-NEW-stdout.txt
@@ -0,0 +1,2 @@
+-- ExeNoRead_EXECUTABLE='.*/Tests/RunCMake/find_program/CMP0109-NEW-build/ExeNoRead'
+-- ReadNoExe_EXECUTABLE='ReadNoExe_EXECUTABLE-NOTFOUND'
diff --git a/Tests/RunCMake/find_program/CMP0109-NEW.cmake b/Tests/RunCMake/find_program/CMP0109-NEW.cmake
new file mode 100644
index 0000000..b4a4033
--- /dev/null
+++ b/Tests/RunCMake/find_program/CMP0109-NEW.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0109 NEW)
+include(CMP0109-Common.cmake)
diff --git a/Tests/RunCMake/find_program/CMP0109-OLD-stdout.txt b/Tests/RunCMake/find_program/CMP0109-OLD-stdout.txt
new file mode 100644
index 0000000..1a0e2a8
--- /dev/null
+++ b/Tests/RunCMake/find_program/CMP0109-OLD-stdout.txt
@@ -0,0 +1,2 @@
+-- ExeNoRead_EXECUTABLE='ExeNoRead_EXECUTABLE-NOTFOUND'
+-- ReadNoExe_EXECUTABLE='.*/Tests/RunCMake/find_program/CMP0109-OLD-build/ReadNoExe'
diff --git a/Tests/RunCMake/find_program/CMP0109-OLD.cmake b/Tests/RunCMake/find_program/CMP0109-OLD.cmake
new file mode 100644
index 0000000..8260161
--- /dev/null
+++ b/Tests/RunCMake/find_program/CMP0109-OLD.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0109 OLD)
+include(CMP0109-Common.cmake)
diff --git a/Tests/RunCMake/find_program/CMP0109-WARN-stderr.txt b/Tests/RunCMake/find_program/CMP0109-WARN-stderr.txt
new file mode 100644
index 0000000..202fc6d
--- /dev/null
+++ b/Tests/RunCMake/find_program/CMP0109-WARN-stderr.txt
@@ -0,0 +1,29 @@
+^CMake Warning \(dev\) at CMP0109-Common.cmake:4 \(find_program\):
+  Policy CMP0109 is not set: find_program\(\) requires permission to execute
+  but not to read.  Run "cmake --help-policy CMP0109" for policy details.
+  Use the cmake_policy command to set the policy and suppress this warning.
+
+  The file
+
+    .*/Tests/RunCMake/find_program/CMP0109-WARN-build/ExeNoRead
+
+  is executable but not readable.  CMake is ignoring it for compatibility.
+Call Stack \(most recent call first\):
+  CMP0109-WARN.cmake:1 \(include\)
+  CMakeLists.txt:3 \(include\)
+This warning is for project developers.  Use -Wno-dev to suppress it.
++
+CMake Warning \(dev\) at CMP0109-Common.cmake:6 \(find_program\):
+  Policy CMP0109 is not set: find_program\(\) requires permission to execute
+  but not to read.  Run "cmake --help-policy CMP0109" for policy details.
+  Use the cmake_policy command to set the policy and suppress this warning.
+
+  The file
+
+    .*/Tests/RunCMake/find_program/CMP0109-WARN-build/ReadNoExe
+
+  is readable but not executable.  CMake is using it for compatibility.
+Call Stack \(most recent call first\):
+  CMP0109-WARN.cmake:1 \(include\)
+  CMakeLists.txt:3 \(include\)
+This warning is for project developers.  Use -Wno-dev to suppress it.$
diff --git a/Tests/RunCMake/find_program/CMP0109-WARN-stdout.txt b/Tests/RunCMake/find_program/CMP0109-WARN-stdout.txt
new file mode 100644
index 0000000..baf560f
--- /dev/null
+++ b/Tests/RunCMake/find_program/CMP0109-WARN-stdout.txt
@@ -0,0 +1,2 @@
+-- ExeNoRead_EXECUTABLE='ExeNoRead_EXECUTABLE-NOTFOUND'
+-- ReadNoExe_EXECUTABLE='.*/Tests/RunCMake/find_program/CMP0109-WARN-build/ReadNoExe'
diff --git a/Tests/RunCMake/find_program/CMP0109-WARN.cmake b/Tests/RunCMake/find_program/CMP0109-WARN.cmake
new file mode 100644
index 0000000..a3d59af
--- /dev/null
+++ b/Tests/RunCMake/find_program/CMP0109-WARN.cmake
@@ -0,0 +1 @@
+include(CMP0109-Common.cmake)
diff --git a/Tests/RunCMake/find_program/ExeNoRead-stdout.txt b/Tests/RunCMake/find_program/ExeNoRead-stdout.txt
deleted file mode 100644
index f231178..0000000
--- a/Tests/RunCMake/find_program/ExeNoRead-stdout.txt
+++ /dev/null
@@ -1 +0,0 @@
--- ExeNoRead_EXECUTABLE='ExeNoRead_EXECUTABLE-NOTFOUND'
diff --git a/Tests/RunCMake/find_program/ExeNoRead.cmake b/Tests/RunCMake/find_program/ExeNoRead.cmake
deleted file mode 100644
index 7e22dc5..0000000
--- a/Tests/RunCMake/find_program/ExeNoRead.cmake
+++ /dev/null
@@ -1,4 +0,0 @@
-file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/ExeNoRead" "#!/bin/sh\n")
-execute_process(COMMAND chmod -r+x "${CMAKE_CURRENT_BINARY_DIR}/ExeNoRead")
-find_program(ExeNoRead_EXECUTABLE NAMES ExeNoRead NO_DEFAULT_PATH PATHS "${CMAKE_CURRENT_BINARY_DIR}")
-message(STATUS "ExeNoRead_EXECUTABLE='${ExeNoRead_EXECUTABLE}'")
diff --git a/Tests/RunCMake/find_program/RunCMakeTest.cmake b/Tests/RunCMake/find_program/RunCMakeTest.cmake
index 2bb777b..3e23920 100644
--- a/Tests/RunCMake/find_program/RunCMakeTest.cmake
+++ b/Tests/RunCMake/find_program/RunCMakeTest.cmake
@@ -17,6 +17,12 @@
     OUTPUT_STRIP_TRAILING_WHITESPACE)
 
   if(NOT "${uid}" STREQUAL "0")
-    run_cmake(ExeNoRead)
+    run_cmake(CMP0109-WARN)
+    run_cmake(CMP0109-OLD)
+    run_cmake(CMP0109-NEW)
   endif()
 endif()
+
+if(APPLE)
+  run_cmake(BundleSpaceInName)
+endif()
diff --git a/Tests/RunCMake/foreach/foreach-ZIP_LISTS-multiple-iter-vars-test.cmake b/Tests/RunCMake/foreach/foreach-ZIP_LISTS-multiple-iter-vars-test.cmake
index 9647dea..3b03ed7 100644
--- a/Tests/RunCMake/foreach/foreach-ZIP_LISTS-multiple-iter-vars-test.cmake
+++ b/Tests/RunCMake/foreach/foreach-ZIP_LISTS-multiple-iter-vars-test.cmake
@@ -8,13 +8,13 @@
     list(APPEND CMAKE_MESSAGE_INDENT "| ")
     foreach(first second third IN ZIP_LISTS ${list_var_1} ${list_var_2} ${list_var_3})
         if(NOT first)
-            set(first "[undefiend]")
+            set(first "[undefined]")
         endif()
         if(NOT second)
-            set(second "[undefiend]")
+            set(second "[undefined]")
         endif()
         if(NOT third)
-            set(third "[undefiend]")
+            set(third "[undefined]")
         endif()
         if(NOT _arg_MUTE)
             message(STATUS "${first}, ${second}, ${third}")
diff --git a/Tests/RunCMake/foreach/foreach-ZIP_LISTS-test-stdout.txt b/Tests/RunCMake/foreach/foreach-ZIP_LISTS-test-stdout.txt
index 25433fd..4730a86 100644
--- a/Tests/RunCMake/foreach/foreach-ZIP_LISTS-test-stdout.txt
+++ b/Tests/RunCMake/foreach/foreach-ZIP_LISTS-test-stdout.txt
@@ -14,6 +14,6 @@
 --     | one, satu, raz
 --     | two, dua, dva
 --     | three, tiga, tri
---     | \[undefiend\], empat, \[undefiend\]
+--     | \[undefined\], empat, \[undefined\]
 --     End output
 --   <<< test variable value restored -- PASSED >>>
diff --git a/Tests/RunCMake/foreach/foreach-ZIP_LISTS-test.cmake b/Tests/RunCMake/foreach/foreach-ZIP_LISTS-test.cmake
index 56cfe64..aa0ed07 100644
--- a/Tests/RunCMake/foreach/foreach-ZIP_LISTS-test.cmake
+++ b/Tests/RunCMake/foreach/foreach-ZIP_LISTS-test.cmake
@@ -9,7 +9,7 @@
     foreach(num IN ZIP_LISTS ${list_var_1} ${list_var_2} ${list_var_3})
         foreach(i RANGE 2)
             if(NOT num_${i})
-                set(num_${i} "[undefiend]")
+                set(num_${i} "[undefined]")
             endif()
         endforeach()
         if(NOT _arg_MUTE)
diff --git a/Tests/RunCMake/interface_library/target_commands-result.txt b/Tests/RunCMake/get_filename_component/IncorrectArguments-result.txt
similarity index 100%
copy from Tests/RunCMake/interface_library/target_commands-result.txt
copy to Tests/RunCMake/get_filename_component/IncorrectArguments-result.txt
diff --git a/Tests/RunCMake/get_filename_component/IncorrectArguments-stderr.txt b/Tests/RunCMake/get_filename_component/IncorrectArguments-stderr.txt
new file mode 100644
index 0000000..af08afa
--- /dev/null
+++ b/Tests/RunCMake/get_filename_component/IncorrectArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at IncorrectArguments.cmake:1 \(get_filename_component\):
+  get_filename_component called with incorrect number of arguments
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/get_filename_component/IncorrectArguments.cmake b/Tests/RunCMake/get_filename_component/IncorrectArguments.cmake
new file mode 100644
index 0000000..e329e29
--- /dev/null
+++ b/Tests/RunCMake/get_filename_component/IncorrectArguments.cmake
@@ -0,0 +1,2 @@
+get_filename_component(var)
+message("The error is fatal, so this should not print")
diff --git a/Tests/RunCMake/get_filename_component/RunCMakeTest.cmake b/Tests/RunCMake/get_filename_component/RunCMakeTest.cmake
index 156fc8f..a7820a0 100644
--- a/Tests/RunCMake/get_filename_component/RunCMakeTest.cmake
+++ b/Tests/RunCMake/get_filename_component/RunCMakeTest.cmake
@@ -1,4 +1,5 @@
 include(RunCMake)
 
+run_cmake(IncorrectArguments)
 run_cmake(KnownComponents)
 run_cmake(UnknownComponent)
diff --git a/Tests/RunCMake/get_filename_component/UnknownComponent-stderr.txt b/Tests/RunCMake/get_filename_component/UnknownComponent-stderr.txt
index b146e5b..f86a688 100644
--- a/Tests/RunCMake/get_filename_component/UnknownComponent-stderr.txt
+++ b/Tests/RunCMake/get_filename_component/UnknownComponent-stderr.txt
@@ -1,4 +1,4 @@
-CMake Error at UnknownComponent.cmake:1 \(get_filename_component\):
+^CMake Error at UnknownComponent.cmake:1 \(get_filename_component\):
   get_filename_component unknown component BOGUS
 Call Stack \(most recent call first\):
-  CMakeLists.txt:[0-9]+ \(include\)
+  CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/get_filename_component/UnknownComponent.cmake b/Tests/RunCMake/get_filename_component/UnknownComponent.cmake
index 06abc51..19521ba 100644
--- a/Tests/RunCMake/get_filename_component/UnknownComponent.cmake
+++ b/Tests/RunCMake/get_filename_component/UnknownComponent.cmake
@@ -1 +1,2 @@
 get_filename_component(var "/path/to/filename.ext.in" BOGUS)
+message("The error is fatal, so this should not print")
diff --git a/Tests/RunCMake/get_property/CMakeLists.txt b/Tests/RunCMake/get_property/CMakeLists.txt
index 12cd3c7..74b3ff8 100644
--- a/Tests/RunCMake/get_property/CMakeLists.txt
+++ b/Tests/RunCMake/get_property/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/if/CMakeLists.txt b/Tests/RunCMake/if/CMakeLists.txt
index 12cd3c7..74b3ff8 100644
--- a/Tests/RunCMake/if/CMakeLists.txt
+++ b/Tests/RunCMake/if/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/include/CMakeLists.txt b/Tests/RunCMake/include/CMakeLists.txt
index 12cd3c7..4b3de84 100644
--- a/Tests/RunCMake/include/CMakeLists.txt
+++ b/Tests/RunCMake/include/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 2.8.12)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/include_external_msproject/CMakeLists.txt b/Tests/RunCMake/include_external_msproject/CMakeLists.txt
index 12cd3c7..74b3ff8 100644
--- a/Tests/RunCMake/include_external_msproject/CMakeLists.txt
+++ b/Tests/RunCMake/include_external_msproject/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/include_external_msproject/check_utils.cmake b/Tests/RunCMake/include_external_msproject/check_utils.cmake
index 0a2ba63..0162519 100644
--- a/Tests/RunCMake/include_external_msproject/check_utils.cmake
+++ b/Tests/RunCMake/include_external_msproject/check_utils.cmake
@@ -63,7 +63,7 @@
     return()
   endif()
 
-  # probably whould be better to use configuration name
+  # probably would be better to use configuration name
   # extracted from CMAKE_CONFIGURATION_TYPES than just hardcoded "Debug" instead
   set(REG_EXP "^(\t)*\\{${FOUND_GUID}\\}\\.Debug[^ ]*\\.ActiveCfg = Debug\\|${PLATFORM_NAME}$")
   check_line_exists(${TARGET_FILE} REG_EXP)
diff --git a/Tests/RunCMake/interface_library/RunCMakeTest.cmake b/Tests/RunCMake/interface_library/RunCMakeTest.cmake
deleted file mode 100644
index 5a6af1d..0000000
--- a/Tests/RunCMake/interface_library/RunCMakeTest.cmake
+++ /dev/null
@@ -1,13 +0,0 @@
-include(RunCMake)
-
-run_cmake(invalid_name)
-run_cmake(target_commands)
-run_cmake(no_shared_libs)
-run_cmake(whitelist)
-run_cmake(invalid_signature)
-run_cmake(global-interface)
-run_cmake(genex_link)
-run_cmake(add_custom_command-TARGET)
-run_cmake(IMPORTED_LIBNAME-bad-value)
-run_cmake(IMPORTED_LIBNAME-non-iface)
-run_cmake(IMPORTED_LIBNAME-non-imported)
diff --git a/Tests/RunCMake/interface_library/whitelist-result.txt b/Tests/RunCMake/interface_library/whitelist-result.txt
deleted file mode 100644
index d00491f..0000000
--- a/Tests/RunCMake/interface_library/whitelist-result.txt
+++ /dev/null
@@ -1 +0,0 @@
-1
diff --git a/Tests/RunCMake/interface_library/whitelist-stderr.txt b/Tests/RunCMake/interface_library/whitelist-stderr.txt
deleted file mode 100644
index 577c0cc..0000000
--- a/Tests/RunCMake/interface_library/whitelist-stderr.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-CMake Error at whitelist.cmake:4 \(set_property\):
-  INTERFACE_LIBRARY targets may only have whitelisted properties.  The
-  property "OUTPUT_NAME" is not allowed.
-Call Stack \(most recent call first\):
-  CMakeLists.txt:3 \(include\)
-
-
-CMake Error at whitelist.cmake:5 \(set_property\):
-  INTERFACE_LIBRARY targets may only have whitelisted properties.  The
-  property "OUTPUT_NAME" is not allowed.
-Call Stack \(most recent call first\):
-  CMakeLists.txt:3 \(include\)
-
-
-CMake Error at whitelist.cmake:6 \(get_target_property\):
-  INTERFACE_LIBRARY targets may only have whitelisted properties.  The
-  property "OUTPUT_NAME" is not allowed.
-Call Stack \(most recent call first\):
-  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/interface_library/whitelist.cmake b/Tests/RunCMake/interface_library/whitelist.cmake
deleted file mode 100644
index 0db6375..0000000
--- a/Tests/RunCMake/interface_library/whitelist.cmake
+++ /dev/null
@@ -1,25 +0,0 @@
-
-add_library(iface INTERFACE)
-
-set_property(TARGET iface PROPERTY OUTPUT_NAME output)
-set_property(TARGET iface APPEND PROPERTY OUTPUT_NAME append)
-get_target_property(outname iface OUTPUT_NAME)
-
-# Properties starting with `_` are allowed.
-set_property(TARGET iface PROPERTY "_custom_property" output)
-set_property(TARGET iface APPEND PROPERTY "_custom_property" append)
-get_target_property(outname iface "_custom_property")
-
-# Properties starting with a lowercase letter are allowed.
-set_property(TARGET iface PROPERTY "custom_property" output)
-set_property(TARGET iface APPEND PROPERTY "custom_property" append)
-get_target_property(outname iface "custom_property")
-
-# PUBLIC_HEADER / PRIVATE_HEADER properties are allowed
-set_property(TARGET iface PROPERTY PUBLIC_HEADER foo.h)
-set_property(TARGET iface APPEND PROPERTY PUBLIC_HEADER bar.h)
-get_target_property(outname iface PUBLIC_HEADER)
-
-set_property(TARGET iface PROPERTY PRIVATE_HEADER foo.h)
-set_property(TARGET iface APPEND PROPERTY PRIVATE_HEADER bar.h)
-get_target_property(outname iface PRIVATE_HEADER)
diff --git a/Tests/RunCMake/list/CMakeLists.txt b/Tests/RunCMake/list/CMakeLists.txt
index 12cd3c7..4b3de84 100644
--- a/Tests/RunCMake/list/CMakeLists.txt
+++ b/Tests/RunCMake/list/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 2.8.12)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/list/GET-CMP0007-WARN-stderr.txt b/Tests/RunCMake/list/GET-CMP0007-WARN-stderr.txt
index a0f8837..9103bd2 100644
--- a/Tests/RunCMake/list/GET-CMP0007-WARN-stderr.txt
+++ b/Tests/RunCMake/list/GET-CMP0007-WARN-stderr.txt
@@ -1,4 +1,13 @@
-^CMake Warning \(dev\) at GET-CMP0007-WARN.cmake:4 \(list\):
+^CMake Deprecation Warning at GET-CMP0007-WARN.cmake:1 \(cmake_policy\):
+  Compatibility with CMake < 2.8.12 will be removed from a future version of
+  CMake.
+
+  Update the VERSION argument <min> value or use a ...<max> suffix to tell
+  CMake that the project does not need compatibility with older versions.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
++
+CMake Warning \(dev\) at GET-CMP0007-WARN.cmake:4 \(list\):
   Policy CMP0007 is not set: list command no longer ignores empty elements.
   Run "cmake --help-policy CMP0007" for policy details.  Use the cmake_policy
   command to set the policy and suppress this warning.  List has value =
diff --git a/Tests/RunCMake/math/CMakeLists.txt b/Tests/RunCMake/math/CMakeLists.txt
index 12cd3c7..74b3ff8 100644
--- a/Tests/RunCMake/math/CMakeLists.txt
+++ b/Tests/RunCMake/math/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/message/CMakeLists.txt b/Tests/RunCMake/message/CMakeLists.txt
index 12cd3c7..74b3ff8 100644
--- a/Tests/RunCMake/message/CMakeLists.txt
+++ b/Tests/RunCMake/message/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/no_install_prefix/CMakeLists.txt b/Tests/RunCMake/no_install_prefix/CMakeLists.txt
index 12cd3c7..74b3ff8 100644
--- a/Tests/RunCMake/no_install_prefix/CMakeLists.txt
+++ b/Tests/RunCMake/no_install_prefix/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/project/CMakeLists.txt b/Tests/RunCMake/project/CMakeLists.txt
index 12cd3c7..4b3de84 100644
--- a/Tests/RunCMake/project/CMakeLists.txt
+++ b/Tests/RunCMake/project/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 2.8.12)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/string/CMakeLists.txt b/Tests/RunCMake/string/CMakeLists.txt
index 12cd3c7..74b3ff8 100644
--- a/Tests/RunCMake/string/CMakeLists.txt
+++ b/Tests/RunCMake/string/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/target_link_libraries/CMP0023-WARN-2.cmake b/Tests/RunCMake/target_link_libraries/CMP0023-WARN-2.cmake
index 2e9cba8..6c72546 100644
--- a/Tests/RunCMake/target_link_libraries/CMP0023-WARN-2.cmake
+++ b/Tests/RunCMake/target_link_libraries/CMP0023-WARN-2.cmake
@@ -1,4 +1,4 @@
-
+cmake_minimum_required(VERSION 2.8.11)
 project(CMP0022-WARN)
 
 add_library(foo SHARED empty_vs6_1.cpp)
diff --git a/Tests/RunCMake/target_link_libraries/CMP0023-WARN.cmake b/Tests/RunCMake/target_link_libraries/CMP0023-WARN.cmake
index fcc8da0..dfdf70b 100644
--- a/Tests/RunCMake/target_link_libraries/CMP0023-WARN.cmake
+++ b/Tests/RunCMake/target_link_libraries/CMP0023-WARN.cmake
@@ -1,4 +1,4 @@
-
+cmake_minimum_required(VERSION 2.8.11)
 project(CMP0022-WARN)
 
 add_library(foo SHARED empty_vs6_1.cpp)
diff --git a/Tests/RunCMake/target_link_libraries/CMakeLists.txt b/Tests/RunCMake/target_link_libraries/CMakeLists.txt
index 8f85fbf..667561e 100644
--- a/Tests/RunCMake/target_link_libraries/CMakeLists.txt
+++ b/Tests/RunCMake/target_link_libraries/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 2.8.12)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake NO_POLICY_SCOPE)
diff --git a/Tests/RunCMake/target_link_libraries/StaticPrivateDepNotExported.cmake b/Tests/RunCMake/target_link_libraries/StaticPrivateDepNotExported.cmake
index 9b97918..9f86b18 100644
--- a/Tests/RunCMake/target_link_libraries/StaticPrivateDepNotExported.cmake
+++ b/Tests/RunCMake/target_link_libraries/StaticPrivateDepNotExported.cmake
@@ -1,4 +1,3 @@
-cmake_policy(SET CMP0022 NEW)
 enable_language(C)
 add_library(foo STATIC empty.c)
 add_library(not_exported STATIC empty.c)
diff --git a/Tests/RunCMake/target_link_libraries/StaticPrivateDepNotTarget.cmake b/Tests/RunCMake/target_link_libraries/StaticPrivateDepNotTarget.cmake
index 7122ae9..20ec438 100644
--- a/Tests/RunCMake/target_link_libraries/StaticPrivateDepNotTarget.cmake
+++ b/Tests/RunCMake/target_link_libraries/StaticPrivateDepNotTarget.cmake
@@ -1,4 +1,3 @@
-cmake_policy(SET CMP0022 NEW)
 enable_language(C)
 add_library(foo STATIC empty.c)
 target_link_libraries(foo PRIVATE not_a_target)
diff --git a/Tests/RunCMake/try_compile/CMP0056.cmake b/Tests/RunCMake/try_compile/CMP0056.cmake
index e8d3d4a..2ab79d5 100644
--- a/Tests/RunCMake/try_compile/CMP0056.cmake
+++ b/Tests/RunCMake/try_compile/CMP0056.cmake
@@ -1,3 +1,4 @@
+cmake_minimum_required(VERSION 3.1)
 enable_language(C)
 set(obj "${CMAKE_C_OUTPUT_EXTENSION}")
 if(BORLAND)
diff --git a/Tests/RunCMake/try_compile/CMakeLists.txt b/Tests/RunCMake/try_compile/CMakeLists.txt
index 12cd3c7..74b3ff8 100644
--- a/Tests/RunCMake/try_compile/CMakeLists.txt
+++ b/Tests/RunCMake/try_compile/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/try_compile/CudaStandard-stderr.txt b/Tests/RunCMake/try_compile/CudaStandard-stderr.txt
index 3c6bdf6..bcf95d5 100644
--- a/Tests/RunCMake/try_compile/CudaStandard-stderr.txt
+++ b/Tests/RunCMake/try_compile/CudaStandard-stderr.txt
@@ -1,5 +1,5 @@
 ^CMake Error at .*/Tests/RunCMake/try_compile/CudaStandard-build/CMakeFiles/CMakeTmp/CMakeLists.txt:[0-9]+ \(add_executable\):
-  CUDA_STANDARD is set to invalid value '3'
+  CUDA_STANDARD is set to invalid value '4'
 +
 CMake Error at CudaStandard.cmake:[0-9]+ \(try_compile\):
   Failed to generate test project build system.
diff --git a/Tests/RunCMake/try_compile/CudaStandard.cmake b/Tests/RunCMake/try_compile/CudaStandard.cmake
index 96da422..a230424 100644
--- a/Tests/RunCMake/try_compile/CudaStandard.cmake
+++ b/Tests/RunCMake/try_compile/CudaStandard.cmake
@@ -1,7 +1,7 @@
 enable_language(CUDA)
 try_compile(result ${CMAKE_CURRENT_BINARY_DIR}
   SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src.cu
-  CUDA_STANDARD 3
+  CUDA_STANDARD 4
   OUTPUT_VARIABLE out
   )
 message("try_compile output:\n${out}")
diff --git a/Tests/RunCMake/try_compile/proj/CMakeLists.txt b/Tests/RunCMake/try_compile/proj/CMakeLists.txt
index 78a87c0..652f5b6 100644
--- a/Tests/RunCMake/try_compile/proj/CMakeLists.txt
+++ b/Tests/RunCMake/try_compile/proj/CMakeLists.txt
@@ -1,2 +1,2 @@
-cmake_minimum_required(VERSION 2.8.10)
+cmake_minimum_required(VERSION 3.3)
 project(TestProject NONE)
diff --git a/Tests/RunCMake/try_run/CMakeLists.txt b/Tests/RunCMake/try_run/CMakeLists.txt
index e034780..e93f0b6 100644
--- a/Tests/RunCMake/try_run/CMakeLists.txt
+++ b/Tests/RunCMake/try_run/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.0)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} C)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/variable_watch/CMakeLists.txt b/Tests/RunCMake/variable_watch/CMakeLists.txt
index 12cd3c7..74b3ff8 100644
--- a/Tests/RunCMake/variable_watch/CMakeLists.txt
+++ b/Tests/RunCMake/variable_watch/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/while/CMakeLists.txt b/Tests/RunCMake/while/CMakeLists.txt
index 12cd3c7..74b3ff8 100644
--- a/Tests/RunCMake/while/CMakeLists.txt
+++ b/Tests/RunCMake/while/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/SetLang/CMakeLists.txt b/Tests/SetLang/CMakeLists.txt
index 9de4fc6..616421e 100644
--- a/Tests/SetLang/CMakeLists.txt
+++ b/Tests/SetLang/CMakeLists.txt
@@ -15,3 +15,10 @@
   add_library(stay stay_c.c stay_cxx.cxx)
   set_property(TARGET stay PROPERTY COMPILE_OPTIONS "-TP")
 endif()
+
+if((CMAKE_C_COMPILER_ID MATCHES "(GNU|Clang|MSVC|Borland|Embarcadero|Intel|TI|XL)"))
+  add_library(zoom zoom.zzz)
+  set_source_files_properties(zoom.zzz PROPERTIES LANGUAGE CXX)
+  target_link_libraries(SetLang zoom)
+  target_compile_definitions(SetLang PRIVATE WITH_ZOOM)
+endif()
diff --git a/Tests/SetLang/bar.c b/Tests/SetLang/bar.c
index b934356..515e8c2 100644
--- a/Tests/SetLang/bar.c
+++ b/Tests/SetLang/bar.c
@@ -1,10 +1,22 @@
 #include <stdio.h>
 
 int foo();
+
+#ifdef WITH_ZOOM
+int zoom();
+#endif
+
 class A
 {
 public:
-  A() { this->i = foo(); }
+  A()
+  {
+    this->i = foo();
+#ifdef WITH_ZOOM
+    i += zoom();
+    i -= zoom();
+#endif
+  }
   int i;
 };
 
diff --git a/Tests/SetLang/zoom.zzz b/Tests/SetLang/zoom.zzz
new file mode 100644
index 0000000..a0c8899
--- /dev/null
+++ b/Tests/SetLang/zoom.zzz
@@ -0,0 +1,7 @@
+int zoom()
+{
+  int r = 10;
+  r++;
+  int ret = r + 10;
+  return ret;
+}
diff --git a/Tests/UseSWIG/CMakeLists.txt b/Tests/UseSWIG/CMakeLists.txt
index d102846..7046fab 100644
--- a/Tests/UseSWIG/CMakeLists.txt
+++ b/Tests/UseSWIG/CMakeLists.txt
@@ -33,6 +33,16 @@
     --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
     )
 endif()
+add_test(NAME UseSWIG.NamespaceCsharp COMMAND
+  ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+  --build-and-test
+  "${CMake_SOURCE_DIR}/Tests/UseSWIG/NamespaceCsharp"
+  "${CMake_BINARY_DIR}/Tests/UseSWIG/NamespaceCsharp"
+  ${build_generator_args}
+  --build-project TestNamespaceCsharp
+  --build-options ${build_options}
+  --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+  )
 
 add_test(NAME UseSWIG.BasicPython COMMAND
   ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
diff --git a/Tests/UseSWIG/NamespaceCsharp/CMakeLists.txt b/Tests/UseSWIG/NamespaceCsharp/CMakeLists.txt
new file mode 100644
index 0000000..39566a8
--- /dev/null
+++ b/Tests/UseSWIG/NamespaceCsharp/CMakeLists.txt
@@ -0,0 +1,25 @@
+cmake_minimum_required(VERSION 3.12...3.13)
+
+project(TestNamsespaceCsharp CXX)
+
+include(CTest)
+
+find_package(SWIG REQUIRED)
+include(${SWIG_USE_FILE})
+
+set(UseSWIG_MODULE_VERSION 2)
+
+
+add_library(ns_example STATIC ns_example.cpp)
+target_include_directories(ns_example PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}")
+
+set_property(SOURCE ns_example.i PROPERTY CPLUSPLUS ON)
+
+swig_add_library(ns_csharp TYPE SHARED LANGUAGE csharp SOURCES ns_example.i)
+set_target_properties(ns_csharp PROPERTIES SWIG_USE_TARGET_INCLUDE_DIRECTORIES TRUE)
+
+target_link_libraries(ns_csharp PRIVATE ns_example)
+
+get_target_property(NS_CSHARP_SUPPORT_FILES_DIR ns_csharp SWIG_SUPPORT_FILES_DIRECTORY)
+
+add_test(NAME NamespaceCsharp COMMAND "${CMAKE_COMMAND}" "-DSUPPORT_FILES_DIRECTORY=${NS_CSHARP_SUPPORT_FILES_DIR}" -P "${CMAKE_CURRENT_SOURCE_DIR}/ValidateSupportFiles.cmake")
diff --git a/Tests/UseSWIG/NamespaceCsharp/ValidateSupportFiles.cmake b/Tests/UseSWIG/NamespaceCsharp/ValidateSupportFiles.cmake
new file mode 100644
index 0000000..828d54c
--- /dev/null
+++ b/Tests/UseSWIG/NamespaceCsharp/ValidateSupportFiles.cmake
@@ -0,0 +1,8 @@
+
+file (GLOB_RECURSE files LIST_DIRECTORIES TRUE RELATIVE "${SUPPORT_FILES_DIRECTORY}" "${SUPPORT_FILES_DIRECTORY}/*")
+
+list(SORT files)
+
+if (NOT files STREQUAL "NSExample.cs;NSExamplePINVOKE.cs;ns;ns/my_class_in_namespace.cs")
+  message (FATAL_ERROR "Support files not correctly collected.")
+endif()
diff --git a/Tests/UseSWIG/NamespaceCsharp/ns_example.cpp b/Tests/UseSWIG/NamespaceCsharp/ns_example.cpp
new file mode 100644
index 0000000..a03dbad
--- /dev/null
+++ b/Tests/UseSWIG/NamespaceCsharp/ns_example.cpp
@@ -0,0 +1,14 @@
+#include "ns_example.hpp"
+
+namespace ns {
+
+void my_class_in_namespace::add(int value)
+{
+  Sum += value;
+}
+
+int my_class_in_namespace::get_sum() const
+{
+  return Sum;
+}
+}
diff --git a/Tests/UseSWIG/NamespaceCsharp/ns_example.hpp b/Tests/UseSWIG/NamespaceCsharp/ns_example.hpp
new file mode 100644
index 0000000..65b9ab5
--- /dev/null
+++ b/Tests/UseSWIG/NamespaceCsharp/ns_example.hpp
@@ -0,0 +1,19 @@
+#pragma once
+
+namespace ns {
+
+class my_class_in_namespace
+{
+public:
+  my_class_in_namespace()
+    : Sum(0)
+  {
+  }
+
+  void add(int value);
+  int get_sum() const;
+
+private:
+  int Sum;
+};
+}
diff --git a/Tests/UseSWIG/NamespaceCsharp/ns_example.i b/Tests/UseSWIG/NamespaceCsharp/ns_example.i
new file mode 100644
index 0000000..036f7ca
--- /dev/null
+++ b/Tests/UseSWIG/NamespaceCsharp/ns_example.i
@@ -0,0 +1,8 @@
+%module NSExample
+
+%{
+#include "ns_example.hpp"
+%}
+
+%nspace ns::my_class_in_namespace;
+%include "ns_example.hpp"
diff --git a/Tests/VSNsightTegra/AndroidManifest.xml b/Tests/VSAndroid/AndroidManifest.xml
similarity index 100%
rename from Tests/VSNsightTegra/AndroidManifest.xml
rename to Tests/VSAndroid/AndroidManifest.xml
diff --git a/Tests/VSNsightTegra/CMakeLists.txt b/Tests/VSAndroid/CMakeLists.txt
similarity index 98%
rename from Tests/VSNsightTegra/CMakeLists.txt
rename to Tests/VSAndroid/CMakeLists.txt
index 6d74f2f..73b1e07 100644
--- a/Tests/VSNsightTegra/CMakeLists.txt
+++ b/Tests/VSAndroid/CMakeLists.txt
@@ -1,5 +1,5 @@
 cmake_minimum_required(VERSION 3.3)
-project(VSNsightTegra C CXX)
+project(VSAndroid C CXX)
 
 set(CMAKE_ANDROID_ARCH armv7-a)
 set(CMAKE_ANDROID_STL_TYPE stlport_shared)
diff --git a/Tests/VSNsightTegra/build.xml b/Tests/VSAndroid/build.xml
similarity index 100%
rename from Tests/VSNsightTegra/build.xml
rename to Tests/VSAndroid/build.xml
diff --git a/Tests/VSNsightTegra/jni/first.c b/Tests/VSAndroid/jni/first.c
similarity index 100%
rename from Tests/VSNsightTegra/jni/first.c
rename to Tests/VSAndroid/jni/first.c
diff --git a/Tests/VSNsightTegra/jni/first.h b/Tests/VSAndroid/jni/first.h
similarity index 100%
rename from Tests/VSNsightTegra/jni/first.h
rename to Tests/VSAndroid/jni/first.h
diff --git a/Tests/VSNsightTegra/jni/second.c b/Tests/VSAndroid/jni/second.c
similarity index 100%
rename from Tests/VSNsightTegra/jni/second.c
rename to Tests/VSAndroid/jni/second.c
diff --git a/Tests/VSNsightTegra/proguard-android.txt b/Tests/VSAndroid/proguard-android.txt
similarity index 100%
rename from Tests/VSNsightTegra/proguard-android.txt
rename to Tests/VSAndroid/proguard-android.txt
diff --git a/Tests/VSNsightTegra/res/values/strings.xml b/Tests/VSAndroid/res/values/strings.xml
similarity index 100%
rename from Tests/VSNsightTegra/res/values/strings.xml
rename to Tests/VSAndroid/res/values/strings.xml
diff --git a/Tests/VSNsightTegra/src/com/example/twolibs/TwoLibs.java b/Tests/VSAndroid/src/com/example/twolibs/TwoLibs.java
similarity index 100%
rename from Tests/VSNsightTegra/src/com/example/twolibs/TwoLibs.java
rename to Tests/VSAndroid/src/com/example/twolibs/TwoLibs.java
diff --git a/Tests/VSWinStorePhone/CMakeLists.txt b/Tests/VSWinStorePhone/CMakeLists.txt
index 558d5de..56e4c1d 100644
--- a/Tests/VSWinStorePhone/CMakeLists.txt
+++ b/Tests/VSWinStorePhone/CMakeLists.txt
@@ -114,7 +114,7 @@
 set_property(SOURCE ${STRING_FILES} PROPERTY VS_TOOL_OVERRIDE "PRIResource")
 set_property(SOURCE ${DEBUG_CONTENT_FILES} PROPERTY VS_DEPLOYMENT_CONTENT $<CONFIG:Debug>)
 set_property(SOURCE ${RELEASE_CONTENT_FILES} PROPERTY
-  VS_DEPLOYMENT_CONTENT $<OR:$<CONFIG:Release>,$<CONFIG:RelWithDebInfo>,$<CONFIG:MinSizeRel>>)
+  VS_DEPLOYMENT_CONTENT $<CONFIG:Release,RelWithDebInfo,MinSizeRel>)
 
 set_property(SOURCE ${PIXELSHADER_FILES} PROPERTY VS_SHADER_TYPE Pixel)
 set_property(SOURCE ${PIXELSHADER_FILES} PROPERTY VS_SHADER_ENTRYPOINT mainPS)
diff --git a/Tests/VariableUnusedViaSet/CMakeLists.txt b/Tests/VariableUnusedViaSet/CMakeLists.txt
deleted file mode 100644
index 0123ab2..0000000
--- a/Tests/VariableUnusedViaSet/CMakeLists.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-set(UNUSED_VARIABLE)
-# Warning should occur here
-set(UNUSED_VARIABLE "Usage")
-message(STATUS "${UNUSED_VARIABLE}")
diff --git a/Tests/VariableUnusedViaUnset/CMakeLists.txt b/Tests/VariableUnusedViaUnset/CMakeLists.txt
deleted file mode 100644
index 4b4031d..0000000
--- a/Tests/VariableUnusedViaUnset/CMakeLists.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-# NOTE: Changing lines in here changes the test results since the first
-# instance shouldn't warn, but the second should and they have the same message
-
-# A warning should NOT be issued for this line:
-set(UNUSED_VARIABLE)
-# Warning should occur here:
-set(UNUSED_VARIABLE)
-message(STATUS "${UNUSED_VARIABLE}")
diff --git a/Tests/XCTest/StaticLibExample/StaticLibExample.c b/Tests/XCTest/StaticLibExample/StaticLibExample.c
index b198f80..8d16eb5 100644
--- a/Tests/XCTest/StaticLibExample/StaticLibExample.c
+++ b/Tests/XCTest/StaticLibExample/StaticLibExample.c
@@ -1,6 +1,6 @@
 #include "StaticLibExample.h"
 
-int FourtyFour()
+int FourtyFour(void)
 {
   return 44;
 }
diff --git a/Tests/XCTest/StaticLibExample/StaticLibExample.h b/Tests/XCTest/StaticLibExample/StaticLibExample.h
index 147a909..88695b1 100644
--- a/Tests/XCTest/StaticLibExample/StaticLibExample.h
+++ b/Tests/XCTest/StaticLibExample/StaticLibExample.h
@@ -1 +1 @@
-int FourtyFour();
+int FourtyFour(void);
diff --git a/Utilities/Sphinx/CTestConfig.cmake b/Utilities/Sphinx/CTestConfig.cmake
index 9607e38..e5f4260 100644
--- a/Utilities/Sphinx/CTestConfig.cmake
+++ b/Utilities/Sphinx/CTestConfig.cmake
@@ -6,7 +6,9 @@
 set(CTEST_PROJECT_NAME "CMake")
 set(CTEST_NIGHTLY_START_TIME "1:00:00 UTC")
 
-set(CTEST_DROP_METHOD "http")
+if(NOT CTEST_DROP_METHOD STREQUAL "https")
+  set(CTEST_DROP_METHOD "http")
+endif()
 set(CTEST_DROP_SITE "open.cdash.org")
 set(CTEST_DROP_LOCATION "/submit.php?project=CMake")
 set(CTEST_DROP_SITE_CDASH TRUE)
diff --git a/Utilities/Sphinx/update_versions.py b/Utilities/Sphinx/update_versions.py
new file mode 100755
index 0000000..893e7a7
--- /dev/null
+++ b/Utilities/Sphinx/update_versions.py
@@ -0,0 +1,115 @@
+#!/usr/bin/env python3
+"""
+This script inserts "versionadded" directive into every .rst document
+and every .cmake module with .rst documentation comment.
+"""
+import re
+import pathlib
+import subprocess
+import argparse
+
+tag_re = re.compile(r'^v3\.(\d+)\.(\d+)(?:-rc(\d+))?$')
+path_re = re.compile(r'Help/(?!dev|guide|manual|cpack_|release).*\.rst|Modules/[^/]*\.cmake$')
+
+def git_root():
+    result = subprocess.run(
+        ['git', 'rev-parse', '--show-toplevel'], check=True, universal_newlines=True, capture_output=True)
+    return pathlib.Path(result.stdout.strip())
+
+def git_tags():
+    result = subprocess.run(['git', 'tag'], check=True, universal_newlines=True, capture_output=True)
+    return [tag for tag in result.stdout.splitlines() if tag_re.match(tag)]
+
+def git_list_tree(ref):
+    result = subprocess.run(
+        ['git', 'ls-tree', '-r', '--full-name', '--name-only', ref, ':/'],
+        check=True, universal_newlines=True, capture_output=True)
+    return [path for path in result.stdout.splitlines() if path_re.match(path)]
+
+def tag_version(tag):
+    return re.sub(r'^v|\.0(-rc\d+)?$', '', tag)
+
+def tag_sortkey(tag):
+    return tuple(int(part or '1000') for part in tag_re.match(tag).groups())
+
+def make_version_map(baseline, since, next_version):
+    versions = {}
+    if next_version:
+        for path in git_list_tree('HEAD'):
+            versions[path] = next_version
+    for tag in sorted(git_tags(), key=tag_sortkey, reverse=True):
+        version = tag_version(tag)
+        for path in git_list_tree(tag):
+            versions[path] = version
+    if baseline:
+        for path in git_list_tree(baseline):
+            versions[path] = None
+    if since:
+        for path in git_list_tree(since):
+            versions.pop(path, None)
+    return versions
+
+cmake_version_re = re.compile(
+    rb'set\(CMake_VERSION_MAJOR\s+(\d+)\)\s+set\(CMake_VERSION_MINOR\s+(\d+)\)\s+set\(CMake_VERSION_PATCH\s+(\d+)\)', re.S)
+
+def cmake_version(path):
+    match = cmake_version_re.search(path.read_bytes())
+    major, minor, patch = map(int, match.groups())
+    minor += patch > 20000000
+    return f'{major}.{minor}'
+
+stamp_re = re.compile(
+    rb'(?P<PREFIX>(^|\[\.rst:\r?\n)[^\r\n]+\r?\n[*^\-=#]+(?P<NL>\r?\n))(?P<STAMP>\s*\.\. versionadded::[^\r\n]*\r?\n)?')
+stamp_pattern_add = rb'\g<PREFIX>\g<NL>.. versionadded:: VERSION\g<NL>'
+stamp_pattern_remove = rb'\g<PREFIX>'
+
+def update_file(path, version, overwrite):
+    try:
+        data = path.read_bytes()
+    except FileNotFoundError as e:
+        return False
+
+    def _replacement(match):
+        if not overwrite and match.start('STAMP') != -1:
+            return match.group()
+        if version:
+            pattern = stamp_pattern_add.replace(b'VERSION', version.encode('utf-8'))
+        else:
+            pattern = stamp_pattern_remove
+        return match.expand(pattern)
+
+    new_data, nrepl = stamp_re.subn(_replacement, data, 1)
+    if nrepl and new_data != data:
+        path.write_bytes(new_data)
+        return True
+    return False
+
+def update_repo(repo_root, version_map, overwrite):
+    total = 0
+    for path, version in version_map.items():
+        if update_file(repo_root / path, version, overwrite):
+            print(f"Version {version or '<none>':6} for {path}")
+            total += 1
+    print(f"Updated {total} file(s)")
+
+def main():
+    parser = argparse.ArgumentParser(allow_abbrev=False)
+    parser.add_argument('--overwrite', action='store_true', help="overwrite existing version tags")
+    parser.add_argument('--baseline', metavar='TAG', default='v3.0.0',
+        help="files present in this tag won't be stamped (default: v3.0.0)")
+    parser.add_argument('--since', metavar='TAG',
+        help="apply changes only to files added after this tag")
+    parser.add_argument('--next-version', metavar='VER',
+        help="version for files not present in any tag (default: from CMakeVersion.cmake)")
+    args = parser.parse_args()
+
+    try:
+        repo_root = git_root()
+        next_version = args.next_version or cmake_version(repo_root / 'Source/CMakeVersion.cmake')
+        version_map = make_version_map(args.baseline, args.since, next_version)
+        update_repo(repo_root, version_map, args.overwrite)
+    except subprocess.CalledProcessError as e:
+        print(f"Command '{' '.join(e.cmd)}' returned code {e.returncode}:\n{e.stderr.strip()}")
+
+if __name__ == '__main__':
+    main()
diff --git a/Utilities/cmlibuv/include/uv/unix.h b/Utilities/cmlibuv/include/uv/unix.h
index 82778ff..f30562e 100644
--- a/Utilities/cmlibuv/include/uv/unix.h
+++ b/Utilities/cmlibuv/include/uv/unix.h
@@ -47,6 +47,9 @@
 
 #ifdef CMAKE_BOOTSTRAP
 # include "posix.h"
+# if defined(__APPLE__)
+#  include <TargetConditionals.h>
+# endif
 #elif defined(__linux__)
 # include "linux.h"
 #elif defined (__MVS__)
diff --git a/Utilities/std/CMakeLists.txt b/Utilities/std/CMakeLists.txt
index 17a7aaa..23d9104 100644
--- a/Utilities/std/CMakeLists.txt
+++ b/Utilities/std/CMakeLists.txt
@@ -4,7 +4,9 @@
 set(CMAKE_CXX_EXTENSIONS FALSE)
 
 # source files for CMake std library
-set(SRCS cm/bits/string_view.cxx
+set(SRCS cm/bits/fs_path.cxx
+         cm/bits/string_view.cxx
+         cm/filesystem
          cm/memory
          cm/optional
          cm/shared_mutex
diff --git a/Utilities/std/cm/bits/fs_path.cxx b/Utilities/std/cm/bits/fs_path.cxx
new file mode 100644
index 0000000..8089998
--- /dev/null
+++ b/Utilities/std/cm/bits/fs_path.cxx
@@ -0,0 +1,1029 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file Copyright.txt or https://cmake.org/licensing for details.  */
+
+#include <cm/filesystem> // IWYU pragma: associated
+
+#if !defined(CMake_HAVE_CXX_FILESYSTEM)
+
+#  include <algorithm>
+#  include <cassert>
+#  include <cstddef>
+#  include <cstdlib>
+#  include <functional>
+#  include <string>
+#  include <utility>
+#  include <vector>
+#  if defined(_WIN32) && !defined(__CYGWIN__)
+#    include <cctype>
+#  endif
+#  if defined(_WIN32) || defined(__CYGWIN__)
+#    include <iterator>
+#  endif
+
+#  include <cm/memory>
+#  include <cm/string_view>
+#  include <cmext/string_view>
+
+namespace cm {
+namespace filesystem {
+namespace internals {
+
+class path_parser
+{
+#  if defined(__SUNPRO_CC) && defined(__sparc)
+  // Oracle DeveloperStudio C++ compiler generates wrong code if enum size
+  // is different than the default.
+  using enum_size = int;
+#  else
+  using enum_size = unsigned char;
+#  endif
+
+  enum class state : enum_size
+  {
+    before_begin,
+    in_root_name,
+    in_root_dir,
+    in_filename,
+    trailing_separator,
+    at_end
+  };
+
+  using pointer = char const*;
+
+public:
+  enum class seek_position : enum_size
+  {
+    root_name = static_cast<enum_size>(state::in_root_name),
+    root_directory = static_cast<enum_size>(state::in_root_dir)
+  };
+  enum class peek_fragment : enum_size
+  {
+    remainder,
+    path
+  };
+
+  path_parser(cm::string_view path, bool set_at_end = false)
+    : State(set_at_end ? state::at_end : state::before_begin)
+    , Path(path)
+  {
+  }
+
+  path_parser(const path_parser&) = default;
+
+  ~path_parser() = default;
+
+  void reset() noexcept { this->set_state(state::before_begin); }
+
+  void increment() noexcept
+  {
+    const pointer start = this->next_token();
+    const pointer end = this->after_end();
+
+    if (start == end) {
+      this->set_state(state::at_end);
+      return;
+    }
+
+    switch (this->State) {
+      case state::before_begin: {
+        auto pos = this->consume_root_name(start, end);
+        if (pos) {
+          this->set_state(state::in_root_name);
+        } else {
+          pos = this->consume_separator(start, end);
+          if (pos) {
+            this->set_state(state::in_root_dir);
+          } else {
+            this->consume_filename(start, end);
+            this->set_state(state::in_filename);
+          }
+        }
+        break;
+      }
+      case state::in_root_name: {
+        auto pos = this->consume_separator(start, end);
+        if (pos) {
+          this->set_state(state::in_root_dir);
+        } else {
+          this->consume_filename(start, end);
+          this->set_state(state::in_filename);
+        }
+        break;
+      }
+      case state::in_root_dir: {
+        this->consume_filename(start, end);
+        this->set_state(state::in_filename);
+        break;
+      }
+      case state::in_filename: {
+        auto posSep = this->consume_separator(start, end);
+        if (posSep != end) {
+          auto pos = this->consume_filename(posSep, end);
+          if (pos) {
+            return;
+          }
+        }
+        set_state(state::trailing_separator);
+        break;
+      }
+      case state::trailing_separator: {
+        this->set_state(state::at_end);
+        break;
+      }
+      case state::at_end:
+        // unreachable
+        std::abort();
+    }
+  }
+
+  void decrement() noexcept
+  {
+    const pointer rstart = this->current_token() - 1;
+    const pointer rend = this->before_start();
+
+    if (rstart == rend) {
+      this->set_state(state::before_begin);
+      return;
+    }
+
+    switch (this->State) {
+      case state::at_end: {
+        auto posSep = this->consume_separator(rstart, rend);
+        if (posSep) {
+          if (posSep == rend) {
+            this->set_state(state::in_root_dir);
+          } else {
+            auto pos = this->consume_root_name(posSep, rend, true);
+            if (pos == rend) {
+              this->set_state(state::in_root_dir);
+            } else {
+              this->set_state(state::trailing_separator);
+            }
+          }
+        } else {
+          auto pos = this->consume_root_name(rstart, rend);
+          if (pos == rend) {
+            this->set_state(state::in_root_name);
+          } else {
+            this->consume_filename(rstart, rend);
+            this->set_state(state::in_filename);
+          }
+        }
+        break;
+      }
+      case state::trailing_separator: {
+        this->consume_filename(rstart, rend);
+        this->set_state(state::in_filename);
+        break;
+      }
+      case state::in_filename: {
+        auto posSep = this->consume_separator(rstart, rend);
+        if (posSep == rend) {
+          this->set_state(state::in_root_dir);
+        } else {
+          auto pos = this->consume_root_name(posSep, rend, true);
+          if (pos == rend) {
+            this->set_state(state::in_root_dir);
+          } else {
+            this->consume_filename(posSep, rend);
+            this->set_state(state::in_filename);
+          }
+        }
+        break;
+      }
+      case state::in_root_dir: {
+        auto pos = this->consume_root_name(rstart, rend);
+        if (pos) {
+          this->set_state(state::in_root_name);
+        }
+        break;
+      }
+      case state::in_root_name:
+      case state::before_begin: {
+        // unreachable
+        std::abort();
+      }
+    }
+  }
+
+  path_parser& operator++() noexcept
+  {
+    this->increment();
+    return *this;
+  }
+
+  path_parser& operator--() noexcept
+  {
+    this->decrement();
+    return *this;
+  }
+
+  cm::string_view operator*() const noexcept
+  {
+    switch (this->State) {
+      case state::before_begin:
+      case state::at_end:
+        return cm::string_view();
+      case state::trailing_separator:
+        return "";
+      case state::in_root_dir:
+      case state::in_root_name:
+      case state::in_filename:
+        return this->Entry;
+      default:
+        // unreachable
+        std::abort();
+    }
+  }
+
+  void seek(seek_position position)
+  {
+    state s = static_cast<state>(static_cast<int>(position));
+
+    while (this->State <= s) {
+      this->increment();
+    }
+  }
+
+  cm::string_view peek(peek_fragment fragment)
+  {
+    if (fragment == peek_fragment::remainder) {
+      // peek-up remain part of the initial path
+      return { this->Entry.data(),
+               std::size_t(&this->Path.back() - this->Entry.data() + 1) };
+    }
+    if (fragment == peek_fragment::path) {
+      // peek-up full path until current position
+      return { this->Path.data(),
+               std::size_t(&this->Entry.back() - this->Path.data() + 1) };
+    }
+    return {};
+  }
+
+  bool in_root_name() const { return this->State == state::in_root_name; }
+  bool in_root_directory() const { return this->State == state::in_root_dir; }
+  bool at_end() const { return this->State == state::at_end; }
+
+  bool at_start() const { return this->Entry.data() == this->Path.data(); }
+
+private:
+  void set_state(state newState) noexcept
+  {
+    this->State = newState;
+    if (newState == state::before_begin || newState == state::at_end) {
+      this->Entry = {};
+    }
+  }
+
+  pointer before_start() const noexcept { return this->Path.data() - 1; }
+  pointer after_end() const noexcept
+  {
+    return this->Path.data() + this->Path.size();
+  }
+
+  pointer current_token() const noexcept
+  {
+    switch (this->State) {
+      case state::before_begin:
+      case state::in_root_name:
+        return &this->Path.front();
+      case state::in_root_dir:
+      case state::in_filename:
+      case state::trailing_separator:
+        return &this->Entry.front();
+      case state::at_end:
+        return &this->Path.back() + 1;
+      default:
+        // unreachable
+        std::abort();
+    }
+  }
+  pointer next_token() const noexcept
+  {
+    switch (this->State) {
+      case state::before_begin:
+        return this->Path.data();
+      case state::in_root_name:
+      case state::in_root_dir:
+      case state::in_filename:
+        return &this->Entry.back() + 1;
+      case state::trailing_separator:
+      case state::at_end:
+        return after_end();
+      default:
+        // unreachable
+        std::abort();
+    }
+  }
+
+  pointer consume_separator(pointer ptr, pointer end) noexcept
+  {
+    if (ptr == end ||
+        (*ptr != '/'
+#  if defined(_WIN32)
+         && *ptr != '\\'
+#  endif
+         )) {
+      return nullptr;
+    }
+    const auto step = ptr < end ? 1 : -1;
+    ptr += step;
+    while (ptr != end &&
+           (*ptr == '/'
+#  if defined(_WIN32)
+            || *ptr == '\\'
+#  endif
+            )) {
+      ptr += step;
+    }
+    if (step == 1) {
+      this->Entry = cm::string_view(ptr - 1, 1);
+    } else {
+      this->Entry = cm::string_view(ptr + 1, 1);
+    }
+
+    return ptr;
+  }
+
+  pointer consume_filename(pointer ptr, pointer end) noexcept
+  {
+    auto start = ptr;
+
+    if (ptr == end || *ptr == '/'
+#  if defined(_WIN32)
+        || *ptr == '\\'
+#  endif
+    ) {
+      return nullptr;
+    }
+    const auto step = ptr < end ? 1 : -1;
+    ptr += step;
+    while (ptr != end && *ptr != '/'
+#  if defined(_WIN32)
+           && *ptr != '\\'
+#  endif
+    ) {
+      ptr += step;
+    }
+
+#  if defined(_WIN32)
+    if (step == -1 && (start - ptr) >= 2 && ptr == end) {
+      // rollback drive name consumption, if any
+      if (this->is_drive_name(ptr + 1)) {
+        ptr += 2;
+      }
+      if (ptr == start) {
+        return nullptr;
+      }
+    }
+#  endif
+
+    if (step == 1) {
+      this->Entry = cm::string_view(start, ptr - start);
+    } else {
+      this->Entry = cm::string_view(ptr + 1, start - ptr);
+    }
+
+    return ptr;
+  }
+
+#  if defined(_WIN32)
+  bool is_drive_name(pointer ptr)
+  {
+    return std::toupper(ptr[0]) >= 'A' && std::toupper(ptr[0]) <= 'Z' &&
+      ptr[1] == ':';
+  }
+#  endif
+
+  pointer consume_root_name(pointer ptr, pointer end,
+                            bool check_only = false) noexcept
+  {
+#  if defined(_WIN32) && !defined(__CYGWIN__)
+    if (ptr < end) {
+      if ((end - ptr) >= 2 && this->is_drive_name(ptr)) {
+        // Drive letter (X:) is a root name
+        if (!check_only) {
+          this->Entry = cm::string_view(ptr, 2);
+        }
+        return ptr + 2;
+      }
+      if ((end - ptr) > 2 && (ptr[0] == '/' || ptr[0] == '\\') &&
+          (ptr[1] == '/' || ptr[1] == '\\') &&
+          (ptr[2] != '/' && ptr[2] != '\\')) {
+        // server name (//server) is a root name
+        auto pos = std::find_if(ptr + 2, end,
+                                [](char c) { return c == '/' || c == '\\'; });
+        if (!check_only) {
+          this->Entry = cm::string_view(ptr, pos - ptr);
+        }
+        return pos;
+      }
+    } else {
+      if ((ptr - end) >= 2 && this->is_drive_name(ptr - 1)) {
+        // Drive letter (X:) is a root name
+        if (!check_only) {
+          this->Entry = cm::string_view(ptr - 1, 2);
+        }
+        return ptr - 2;
+      }
+      if ((ptr - end) > 2 && (ptr[0] != '/' && ptr[0] != '\\')) {
+        std::reverse_iterator<pointer> start(ptr);
+        std::reverse_iterator<pointer> stop(end);
+        auto res = std::find_if(start, stop,
+                                [](char c) { return c == '/' || c == '\\'; });
+        pointer pos = res.base() - 1;
+        if ((pos - 1) > end && (pos[-1] == '/' || pos[-1] == '\\')) {
+          // server name (//server) is a root name
+          if (!check_only) {
+            this->Entry = cm::string_view(pos - 1, ptr - pos + 2);
+          }
+          return pos - 2;
+        }
+      }
+    }
+#  elif defined(__CYGWIN__)
+    if (ptr < end) {
+      if ((end - ptr) > 2 && ptr[0] == '/' && ptr[1] == '/' && ptr[2] != '/') {
+        // server name (//server) is a root name
+        auto pos = std::find(ptr + 2, end, '/');
+        if (!check_only) {
+          this->Entry = cm::string_view(ptr, pos - ptr);
+        }
+        return pos;
+      }
+    } else {
+      if ((ptr - end) > 2 && ptr[0] != '/') {
+        std::reverse_iterator<pointer> start(ptr);
+        std::reverse_iterator<pointer> stop(end);
+        auto res = std::find(start, stop, '/');
+        pointer pos = res.base() - 1;
+        if ((pos - 1) > end && pos[-1] == '/') {
+          // server name (//server) is a root name
+          if (!check_only) {
+            this->Entry = cm::string_view(pos - 1, ptr - pos + 2);
+          }
+          return pos - 2;
+        }
+      }
+    }
+#  else
+    (void)ptr;
+    (void)end;
+    (void)check_only;
+#  endif
+    return nullptr;
+  }
+
+  state State;
+  const cm::string_view Path;
+  cm::string_view Entry;
+};
+
+// class unicode_helper
+void unicode_helper::append(std::string& str, std::uint32_t codepoint)
+{
+  if (codepoint <= 0x7f) {
+    str.push_back(static_cast<char>(codepoint));
+  } else if (codepoint >= 0x80 && codepoint <= 0x7ff) {
+    str.push_back(static_cast<char>((codepoint >> 6) + 192));
+    str.push_back(static_cast<char>((codepoint & 0x3f) + 128));
+  } else if ((codepoint >= 0x800 && codepoint <= 0xd7ff) ||
+             (codepoint >= 0xe000 && codepoint <= 0xffff)) {
+    str.push_back(static_cast<char>((codepoint >> 12) + 224));
+    str.push_back(static_cast<char>(((codepoint & 0xfff) >> 6) + 128));
+    str.push_back(static_cast<char>((codepoint & 0x3f) + 128));
+  } else if (codepoint >= 0x10000 && codepoint <= 0x10ffff) {
+    str.push_back(static_cast<char>((codepoint >> 18) + 240));
+    str.push_back(static_cast<char>(((codepoint & 0x3ffff) >> 12) + 128));
+    str.push_back(static_cast<char>(((codepoint & 0xfff) >> 6) + 128));
+    str.push_back(static_cast<char>((codepoint & 0x3f) + 128));
+  } else {
+    append(str, 0xfffd);
+  }
+}
+
+unicode_helper::utf8_state unicode_helper::decode(const utf8_state state,
+                                                  const std::uint8_t fragment,
+                                                  std::uint32_t& codepoint)
+{
+  const std::uint32_t utf8_state_info[] = {
+    // encoded states
+    0x11111111u, 0x11111111u, 0x77777777u, 0x77777777u, 0x88888888u,
+    0x88888888u, 0x88888888u, 0x88888888u, 0x22222299u, 0x22222222u,
+    0x22222222u, 0x22222222u, 0x3333333au, 0x33433333u, 0x9995666bu,
+    0x99999999u, 0x88888880u, 0x22818108u, 0x88888881u, 0x88888882u,
+    0x88888884u, 0x88888887u, 0x88888886u, 0x82218108u, 0x82281108u,
+    0x88888888u, 0x88888883u, 0x88888885u, 0u,          0u,
+    0u,          0u,
+  };
+  std::uint8_t category = fragment < 128
+    ? 0
+    : (utf8_state_info[(fragment >> 3) & 0xf] >> ((fragment & 7) << 2)) & 0xf;
+  codepoint = (state ? (codepoint << 6) | (fragment & 0x3fu)
+                     : (0xffu >> category) & fragment);
+  return state == s_reject
+    ? s_reject
+    : static_cast<utf8_state>(
+        (utf8_state_info[category + 16] >> (state << 2)) & 0xf);
+}
+
+} // internals
+
+// Class path
+path& path::operator/=(const path& p)
+{
+  if (p.is_absolute() ||
+      (p.has_root_name() && p.get_root_name() != this->get_root_name())) {
+    this->path_ = p.path_;
+    return *this;
+  }
+  if (p.has_root_directory()) {
+    this->path_ = static_cast<std::string>(this->get_root_name());
+    this->path_ += static_cast<std::string>(p.get_root_directory());
+  } else if (this->has_filename()) {
+    this->path_ += this->preferred_separator;
+#  if defined(_WIN32) || defined(__CYGWIN__)
+    // special case: "//host" / "b" => "//host/b"
+  } else if (this->has_root_name() && !this->has_root_directory()) {
+    if (this->path_.length() >= 3 &&
+        (this->path_[0] == '/'
+#    if defined(_WIN32) && !defined(__CYGWIN__)
+         || this->path_[0] == '\\'
+#    endif
+         ) &&
+        (this->path_[1] == '/'
+#    if defined(_WIN32) && !defined(__CYGWIN__)
+         || this->path_[1] == '\\'
+#    endif
+         ) &&
+        (this->path_[2] != '/'
+#    if defined(_WIN32) && !defined(__CYGWIN__)
+         && this->path_[2] != '\\'
+#    endif
+         )) {
+      this->path_ += this->preferred_separator;
+    }
+#  endif
+  }
+
+  this->path_ += p.get_relative_path();
+  return *this;
+}
+
+path path::lexically_normal() const
+{
+  if (this->path_.empty()) {
+    return *this;
+  }
+
+  const cm::string_view dot = "."_s;
+  const cm::string_view dotdot = ".."_s;
+
+  std::vector<cm::string_view> root_parts;
+  std::vector<cm::string_view> parts;
+  bool root_directory_defined = false;
+  bool need_final_separator = false;
+  std::size_t path_size = 0;
+
+  internals::path_parser parser(this->path_);
+  ++parser;
+  while (!parser.at_end()) {
+    auto part = *parser;
+
+    if (parser.in_root_name() || parser.in_root_directory()) {
+      if (parser.in_root_directory()) {
+        root_directory_defined = true;
+      }
+      root_parts.push_back(part);
+      path_size += part.size();
+    } else if (part == dotdot) {
+      if (!parts.empty() && parts.back() != dotdot) {
+        need_final_separator = true;
+        path_size -= parts.back().size();
+        parts.pop_back();
+      } else if ((parts.empty() || parts.back() == dotdot) &&
+                 !root_directory_defined) {
+        parts.push_back(dotdot);
+        path_size += 2;
+      }
+
+    } else if (part == dot || part.empty()) {
+      need_final_separator = true;
+      if (part.empty()) {
+        parts.push_back(part);
+      }
+    } else {
+      // filename
+      need_final_separator = false;
+      parts.push_back(part);
+      path_size += part.size();
+    }
+    ++parser;
+  }
+
+  // no final separator if last element of path is ".."
+  need_final_separator =
+    need_final_separator && !parts.empty() && parts.back() != dotdot;
+
+  // build final path
+  //// compute final size of path
+  path_size += parts.size() + (need_final_separator ? 1 : 0);
+
+  std::string np;
+  np.reserve(path_size);
+  for (const auto& p : root_parts) {
+    np += p;
+  }
+  // convert any slash to the preferred_separator
+  if (static_cast<std::string::value_type>(this->preferred_separator) != '/') {
+    std::replace(
+      np.begin(), np.end(), '/',
+      static_cast<std::string::value_type>(this->preferred_separator));
+  }
+  for (const auto& p : parts) {
+    if (!p.empty()) {
+      np += p;
+      np += static_cast<std::string::value_type>(this->preferred_separator);
+    }
+  }
+  if (!parts.empty() && !need_final_separator) {
+    // remove extra separator
+    np.pop_back();
+  }
+  if (np.empty()) {
+    np.assign(1, '.');
+  }
+
+  return path(std::move(np));
+}
+
+path path::lexically_relative(const path& base) const
+{
+  internals::path_parser parser(this->path_);
+  ++parser;
+  internals::path_parser parserbase(base.path_);
+  ++parserbase;
+  cm::string_view this_root_name, base_root_name;
+  cm::string_view this_root_dir, base_root_dir;
+
+  if (parser.in_root_name()) {
+    this_root_name = *parser;
+    ++parser;
+  }
+  if (parser.in_root_directory()) {
+    this_root_dir = *parser;
+    ++parser;
+  }
+  if (parserbase.in_root_name()) {
+    base_root_name = *parserbase;
+    ++parserbase;
+  }
+  if (parserbase.in_root_directory()) {
+    base_root_dir = *parserbase;
+    ++parserbase;
+  }
+
+  auto is_path_absolute = [](cm::string_view rn, cm::string_view rd) -> bool {
+#  if defined(_WIN32) && !defined(__CYGWIN__)
+    return !rn.empty() && !rd.empty();
+#  else
+    (void)rn;
+    return !rd.empty();
+#  endif
+  };
+
+  if (this_root_name != base_root_name ||
+      is_path_absolute(this_root_name, this_root_dir) !=
+        is_path_absolute(base_root_name, base_root_dir) ||
+      (this_root_dir.empty() && !base_root_dir.empty())) {
+    return path();
+  }
+
+#  if defined(_WIN32) && !defined(__CYGWIN__)
+  // LWG3070 handle special case: filename can also be a root-name
+  auto is_drive_name = [](cm::string_view item) -> bool {
+    return item.length() == 2 && item[1] == ':';
+  };
+  parser.reset();
+  parser.seek(internals::path_parser::seek_position::root_directory);
+  while (!parser.at_end()) {
+    if (is_drive_name(*parser)) {
+      return path();
+    }
+    ++parser;
+  }
+  parserbase.reset();
+  parserbase.seek(internals::path_parser::seek_position::root_directory);
+  while (!parserbase.at_end()) {
+    if (is_drive_name(*parserbase)) {
+      return path();
+    }
+    ++parserbase;
+  }
+#  endif
+
+  const cm::string_view dot = "."_s;
+  const cm::string_view dotdot = ".."_s;
+
+  auto a = this->begin(), aend = this->end();
+  auto b = base.begin(), bend = base.end();
+  while (a != aend && b != bend && a->string() == b->string()) {
+    ++a;
+    ++b;
+  }
+
+  int count = 0;
+  for (; b != bend; ++b) {
+    auto part = *b;
+    if (part == dotdot) {
+      --count;
+    } else if (part.string() != dot && !part.empty()) {
+      ++count;
+    }
+  }
+
+  if (count == 0 && (a == this->end() || a->empty())) {
+    return path(dot);
+  }
+  if (count >= 0) {
+    path result;
+    path p_dotdot(dotdot);
+    for (int i = 0; i < count; ++i) {
+      result /= p_dotdot;
+    }
+    for (; a != aend; ++a) {
+      result /= *a;
+    }
+    return result;
+  }
+  // count < 0
+  return path();
+}
+
+path::path_type path::get_generic() const
+{
+  auto gen_path = this->path_;
+  auto start = gen_path.begin();
+#  if defined(_WIN32) && !defined(__CYGWIN__)
+  std::replace(gen_path.begin(), gen_path.end(), '\\', '/');
+  // preserve special syntax for root_name ('//server' or '//?')
+  if (gen_path.length() > 2 && gen_path[2] != '/') {
+    start += 2;
+  }
+#  endif
+  // remove duplicate separators
+  auto new_end = std::unique(start, gen_path.end(), [](char lhs, char rhs) {
+    return lhs == rhs && lhs == '/';
+  });
+  gen_path.erase(new_end, gen_path.end());
+  return gen_path;
+}
+
+cm::string_view path::get_root_name() const
+{
+  internals::path_parser parser(this->path_);
+  ++parser;
+  if (parser.in_root_name()) {
+    return *parser;
+  }
+  return {};
+}
+
+cm::string_view path::get_root_directory() const
+{
+  internals::path_parser parser(this->path_);
+  ++parser;
+  if (parser.in_root_name()) {
+    ++parser;
+  }
+  if (parser.in_root_directory()) {
+    return *parser;
+  }
+  return {};
+}
+
+cm::string_view path::get_relative_path() const
+{
+  internals::path_parser parser(this->path_);
+  parser.seek(internals::path_parser::seek_position::root_directory);
+  if (parser.at_end()) {
+    return {};
+  }
+  return parser.peek(internals::path_parser::peek_fragment::remainder);
+}
+
+cm::string_view path::get_parent_path() const
+{
+  if (!this->has_relative_path()) {
+    return this->path_;
+  }
+
+  // peek-up full path minus last element
+  internals::path_parser parser(this->path_, true);
+  --parser;
+  if (parser.at_start()) {
+    return {};
+  }
+  --parser;
+  return parser.peek(internals::path_parser::peek_fragment::path);
+}
+
+cm::string_view path::get_filename() const
+{
+  {
+    internals::path_parser parser(this->path_);
+    parser.seek(internals::path_parser::seek_position::root_directory);
+    if (parser.at_end()) {
+      return {};
+    }
+  }
+  {
+    internals::path_parser parser(this->path_, true);
+    return *(--parser);
+  }
+}
+
+cm::string_view path::get_filename_fragment(filename_fragment fragment) const
+{
+  auto file = this->get_filename();
+
+  if (file == "." || file == ".." || file.empty()) {
+    return fragment == filename_fragment::stem ? file : cm::string_view{};
+  }
+
+  auto pos = file.find_last_of('.');
+  if (pos == cm::string_view::npos || pos == 0) {
+    return fragment == filename_fragment::stem ? file : cm::string_view{};
+  }
+  return fragment == filename_fragment::stem ? file.substr(0, pos)
+                                             : file.substr(pos);
+}
+
+int path::compare_path(cm::string_view str) const
+{
+  internals::path_parser this_pp(this->path_);
+  ++this_pp;
+  internals::path_parser other_pp(str);
+  ++other_pp;
+
+  // compare root_name part
+  {
+    bool compare_root_names = false;
+    cm::string_view this_root_name, other_root_name;
+    int res;
+
+    if (this_pp.in_root_name()) {
+      compare_root_names = true;
+      this_root_name = *this_pp;
+      ++this_pp;
+    }
+    if (other_pp.in_root_name()) {
+      compare_root_names = true;
+      other_root_name = *other_pp;
+      ++other_pp;
+    }
+    if (compare_root_names &&
+        (res = this_root_name.compare(other_root_name) != 0)) {
+      return res;
+    }
+  }
+
+  // compare root_directory part
+  {
+    if (!this_pp.in_root_directory() && other_pp.in_root_directory()) {
+      return -1;
+    } else if (this_pp.in_root_directory() && !other_pp.in_root_directory()) {
+      return 1;
+    }
+    if (this_pp.in_root_directory()) {
+      ++this_pp;
+    }
+    if (other_pp.in_root_directory()) {
+      ++other_pp;
+    }
+  }
+
+  // compare various parts of the paths
+  while (!this_pp.at_end() && !other_pp.at_end()) {
+    int res;
+    if ((res = (*this_pp).compare(*other_pp)) != 0) {
+      return res;
+    }
+    ++this_pp;
+    ++other_pp;
+  }
+
+  // final step
+  if (this_pp.at_end() && !other_pp.at_end()) {
+    return -1;
+  } else if (!this_pp.at_end() && other_pp.at_end()) {
+    return 1;
+  }
+
+  return 0;
+}
+
+// Class path::iterator
+path::iterator::iterator()
+  : path_(nullptr)
+{
+}
+path::iterator::iterator(const iterator& other)
+{
+  this->path_ = other.path_;
+  if (other.parser_) {
+    this->parser_ = cm::make_unique<internals::path_parser>(*other.parser_);
+    this->path_element_ = path(**this->parser_);
+  }
+}
+path::iterator::iterator(const path* p, bool at_end)
+  : path_(p)
+  , parser_(cm::make_unique<internals::path_parser>(p->path_, at_end))
+{
+  if (!at_end) {
+    ++(*this->parser_);
+    this->path_element_ = path(**this->parser_);
+  }
+}
+
+path::iterator::~iterator() = default;
+
+path::iterator& path::iterator::operator=(const iterator& other)
+{
+  this->path_ = other.path_;
+  if (other.parser_) {
+    this->parser_ = cm::make_unique<internals::path_parser>(*other.parser_);
+    this->path_element_ = path(**this->parser_);
+  }
+
+  return *this;
+}
+
+path::iterator& path::iterator::operator++()
+{
+  assert(this->parser_);
+
+  if (this->parser_) {
+    assert(!this->parser_->at_end());
+
+    if (!this->parser_->at_end()) {
+      ++(*this->parser_);
+      if (this->parser_->at_end()) {
+        this->path_element_ = path();
+      } else {
+        this->path_element_ = path(**this->parser_);
+      }
+    }
+  }
+
+  return *this;
+}
+
+path::iterator& path::iterator::operator--()
+{
+  assert(this->parser_);
+
+  if (this->parser_) {
+    assert(!this->parser_->at_start());
+
+    if (!this->parser_->at_start()) {
+      --(*this->parser_);
+      this->path_element_ = path(**this->parser_);
+    }
+  }
+
+  return *this;
+}
+
+bool operator==(const path::iterator& lhs, const path::iterator& rhs)
+{
+  return lhs.path_ == rhs.path_ && lhs.parser_ != nullptr &&
+    ((lhs.parser_->at_end() && rhs.parser_->at_end()) ||
+     (lhs.parser_->at_start() && rhs.parser_->at_start()) ||
+     ((**lhs.parser_).data() == (**rhs.parser_).data()));
+}
+
+std::size_t hash_value(const path& p) noexcept
+{
+  internals::path_parser parser(p.path_);
+  std::hash<cm::string_view> hasher;
+  std::size_t value = 0;
+
+  while (!parser.at_end()) {
+    value = hasher(*parser) + 0x9e3779b9 + (value << 6) + (value >> 2);
+    ++parser;
+  }
+
+  return value;
+}
+} // filesystem
+} // cm
+
+#else
+
+// Avoid empty translation unit.
+void cm_filesystem_path_cxx()
+{
+}
+
+#endif
diff --git a/Utilities/std/cm/filesystem b/Utilities/std/cm/filesystem
new file mode 100644
index 0000000..6021712
--- /dev/null
+++ b/Utilities/std/cm/filesystem
@@ -0,0 +1,1175 @@
+// -*-c++-*-
+// vim: set ft=cpp:
+
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file Copyright.txt or https://cmake.org/licensing for details.  */
+#ifndef cm_filesystem
+#define cm_filesystem
+
+#include "cmSTL.hxx" // IWYU pragma: keep
+
+#if defined(CMake_HAVE_CXX_FILESYSTEM)
+
+#  include <filesystem> // IWYU pragma: export
+
+#else
+
+#  include <cstddef>
+#  include <cstdint>
+#  include <iostream>
+#  include <iterator>
+#  include <memory>
+#  include <string>
+#  include <utility>
+
+#  include <cm/iomanip>
+#  include <cm/string_view>
+#  include <cm/type_traits>
+#  include <cmext/iterator>
+
+#  if defined(_WIN32) && !defined(__CYGWIN__)
+#    include <algorithm>
+#  endif
+
+#endif
+
+namespace cm {
+namespace filesystem {
+
+#if defined(CMake_HAVE_CXX_FILESYSTEM)
+
+using std::filesystem::path;
+using std::filesystem::swap;
+using std::filesystem::hash_value;
+
+#else
+
+#  if !defined(CM_FILESYSTEM_SOURCE_TRAITS_ITERATOR)
+// Oracle DeveloperStudio C++ compiler on Solaris/Sparc fails to compile
+// the source_traits for iterator check.  So disable it for now.
+#    define CM_FILESYSTEM_SOURCE_TRAITS_ITERATOR 0
+#  endif
+
+namespace internals {
+
+class path_parser;
+
+class unicode_helper
+{
+protected:
+  using utf8_state = unsigned char;
+  static const utf8_state s_start = 0;
+  static const utf8_state s_reject = 8;
+
+  static inline bool in_range(std::uint32_t c, std::uint32_t lo,
+                              std::uint32_t hi)
+  {
+    return (static_cast<std::uint32_t>(c - lo) < (hi - lo + 1));
+  }
+
+  static inline bool is_surrogate(std::uint32_t c)
+  {
+    return in_range(c, 0xd800, 0xdfff);
+  }
+
+  static inline bool is_high_surrogate(std::uint32_t c)
+  {
+    return (c & 0xfffffc00) == 0xd800;
+  }
+
+  static inline bool is_low_surrogate(std::uint32_t c)
+  {
+    return (c & 0xfffffc00) == 0xdc00;
+  }
+
+  static void append(std::string& str, std::uint32_t codepoint);
+
+  static utf8_state decode(const utf8_state state, const std::uint8_t fragment,
+                           std::uint32_t& codepoint);
+};
+
+template <typename Char, typename = void>
+class unicode
+{
+};
+
+template <typename Char>
+class unicode<Char, typename std::enable_if<(sizeof(Char) == 4)>::type>
+  : public unicode_helper
+{
+public:
+  // UTF32 -> UTF8
+  static std::string to_utf8(const std::wstring& str)
+  {
+    std::string result;
+    for (auto c : str) {
+      append(result, c);
+    }
+    return result;
+  }
+  static std::string to_utf8(Char c)
+  {
+    std::string result;
+    append(result, c);
+    return result;
+  }
+
+  // UTF8 -> UTF32
+  static std::wstring from_utf8(const std::string& str)
+  {
+    std::wstring result;
+    result.reserve(str.length());
+    auto iter = str.begin();
+    utf8_state state = s_start;
+    std::uint32_t codepoint = 0;
+    while (iter < str.end()) {
+      if ((state = decode(state, static_cast<std::uint8_t>(*iter++),
+                          codepoint)) == s_start) {
+        result += static_cast<std::wstring::value_type>(codepoint);
+        codepoint = 0;
+      } else if (state == s_reject) {
+        result += static_cast<std::wstring::value_type>(0xfffd);
+        state = s_start;
+        codepoint = 0;
+      }
+    }
+    if (state) {
+      result += static_cast<std::wstring::value_type>(0xfffd);
+    }
+    return result;
+  }
+  static std::wstring from_utf8(char c)
+  {
+    std::wstring result;
+    utf8_state state = s_start;
+    std::uint32_t codepoint = 0;
+    if ((state = decode(state, static_cast<std::uint8_t>(c), codepoint)) ==
+        s_start) {
+      result += static_cast<std::wstring::value_type>(codepoint);
+    } else {
+      result += static_cast<std::wstring::value_type>(0xfffd);
+    }
+
+    return result;
+  }
+};
+
+template <typename Char>
+class unicode<Char, typename std::enable_if<(sizeof(Char) == 2)>::type>
+  : public unicode_helper
+{
+public:
+  // UTF16 -> UTF8
+  static std::string to_utf8(const std::wstring& str)
+  {
+    std::string result;
+    for (auto iter = str.begin(); iter != str.end(); ++iter) {
+      std::uint32_t c = *iter;
+      if (is_surrogate(c)) {
+        ++iter;
+        if (iter != str.end() && is_high_surrogate(c) &&
+            is_low_surrogate(*iter)) {
+          append(result, (std::uint32_t(c) << 10) + *iter - 0x35fdc00);
+        } else {
+          append(result, 0xfffd);
+          if (iter == str.end()) {
+            break;
+          }
+        }
+      } else {
+        append(result, c);
+      }
+    }
+    return result;
+  }
+  static std::string to_utf8(Char c)
+  {
+    std::string result;
+    if (is_surrogate(c)) {
+      append(result, 0xfffd);
+    } else {
+      append(result, c);
+    }
+    return result;
+  }
+
+  // UTF8 -> UTF16
+  static std::wstring from_utf8(const std::string& str)
+  {
+    std::wstring result;
+    result.reserve(str.length());
+    auto iter = str.begin();
+    utf8_state state = s_start;
+    std::uint32_t codepoint = 0;
+    while (iter < str.end()) {
+      if ((state = decode(state, static_cast<std::uint8_t>(*iter++),
+                          codepoint)) == s_start) {
+        if (codepoint <= 0xffff) {
+          result += static_cast<std::wstring::value_type>(codepoint);
+        } else {
+          codepoint -= 0x10000;
+          result +=
+            static_cast<std::wstring::value_type>((codepoint >> 10) + 0xd800);
+          result += static_cast<std::wstring::value_type>((codepoint & 0x3ff) +
+                                                          0xdc00);
+        }
+        codepoint = 0;
+      } else if (state == s_reject) {
+        result += static_cast<std::wstring::value_type>(0xfffd);
+        state = s_start;
+        codepoint = 0;
+      }
+    }
+    if (state) {
+      result += static_cast<std::wstring::value_type>(0xfffd);
+    }
+    return result;
+  }
+  static std::wstring from_utf8(char c)
+  {
+    std::wstring result;
+    utf8_state state = s_start;
+    std::uint32_t codepoint = 0;
+    if ((state = decode(state, static_cast<std::uint8_t>(c), codepoint)) ==
+        s_start) {
+      if (codepoint <= 0xffff) {
+        result += static_cast<std::wstring::value_type>(codepoint);
+      } else {
+        codepoint -= 0x10000;
+        result +=
+          static_cast<std::wstring::value_type>((codepoint >> 10) + 0xd800);
+        result +=
+          static_cast<std::wstring::value_type>((codepoint & 0x3ff) + 0xdc00);
+      }
+    } else {
+      result += static_cast<std::wstring::value_type>(0xfffd);
+    }
+    return result;
+  }
+};
+
+template <typename In, typename Out>
+class unicode_converter;
+
+template <>
+class unicode_converter<char, wchar_t>
+{
+public:
+  std::wstring operator()(const std::string& in)
+  {
+    return unicode<wchar_t>::from_utf8(in);
+  }
+  std::wstring operator()(const char* in)
+  {
+    return unicode<wchar_t>::from_utf8(in);
+  }
+  std::wstring operator()(char in) { return unicode<wchar_t>::from_utf8(in); }
+};
+template <>
+class unicode_converter<wchar_t, char>
+{
+public:
+  std::string operator()(const std::wstring& in)
+  {
+    return unicode<wchar_t>::to_utf8(in);
+  }
+  std::string operator()(const wchar_t* in)
+  {
+    return unicode<wchar_t>::to_utf8(in);
+  }
+  std::string operator()(wchar_t in) { return unicode<wchar_t>::to_utf8(in); }
+};
+template <>
+class unicode_converter<char, char>
+{
+public:
+  std::string operator()(const std::string& in) { return in; }
+  std::string operator()(const char* in) { return std::string(in); }
+  std::string operator()(char in) { return std::string(1, in); }
+};
+template <>
+class unicode_converter<wchar_t, wchar_t>
+{
+public:
+  std::wstring operator()(const std::wstring& in) { return in; }
+  std::wstring operator()(const wchar_t* in) { return std::wstring(in); }
+  std::wstring operator()(wchar_t in) { return std::wstring(1, in); }
+};
+
+template <typename In>
+struct string_converter
+{
+};
+
+template <>
+struct string_converter<char>
+{
+  // some compilers, like gcc 4.8 does not implement the following C++11
+  // signature:
+  // std::string::string(const string&, const Allocator&)
+  // As workaround, use char* pointer.
+  template <typename Char, typename Traits, typename Alloc>
+  static std::basic_string<Char, Traits, Alloc> to(const std::string& in,
+                                                   const Alloc& a)
+  {
+    return std::basic_string<Char, Traits, Alloc>(
+      unicode_converter<char, Char>()(in).c_str(), a);
+  }
+  template <typename Char, typename Traits, typename Alloc>
+  static std::basic_string<Char, Traits, Alloc> to(const char* in,
+                                                   const Alloc& a)
+  {
+    return std::basic_string<Char, Traits, Alloc>(
+      unicode_converter<char, Char>()(in).c_str(), a);
+  }
+  template <typename Char, typename Traits, typename Alloc>
+  static std::basic_string<Char, Traits, Alloc> to(char in, const Alloc& a)
+  {
+    return std::basic_string<Char, Traits, Alloc>(
+      unicode_converter<char, Char>()(in).c_str(), a);
+  }
+
+  template <typename Char>
+  static std::basic_string<Char> to(const std::string& in)
+  {
+    return std::basic_string<Char>(unicode_converter<char, Char>()(in));
+  }
+  template <typename Char>
+  static std::basic_string<Char> to(const char* in)
+  {
+    return std::basic_string<Char>(unicode_converter<char, Char>()(in));
+  }
+  template <typename Char>
+  static std::basic_string<Char> to(char in)
+  {
+    return std::basic_string<Char>(unicode_converter<char, Char>()(in));
+  }
+};
+template <>
+struct string_converter<wchar_t>
+{
+  // some compilers, like gcc 4.8 does not implement the following C++11
+  // signature:
+  // std::string::string(const string&, const Allocator&)
+  // As workaround, use char* pointer.
+  template <typename Char, typename Traits, typename Alloc>
+  static std::basic_string<Char, Traits, Alloc> to(const std::wstring& in,
+                                                   const Alloc& a)
+  {
+    return std::basic_string<Char, Traits, Alloc>(
+      unicode_converter<wchar_t, Char>()(in).c_str(), a);
+  }
+  template <typename Char, typename Traits, typename Alloc>
+  static std::basic_string<Char, Traits, Alloc> to(const wchar_t* in,
+                                                   const Alloc& a)
+  {
+    return std::basic_string<Char, Traits, Alloc>(
+      unicode_converter<wchar_t, Char>()(in).c_str(), a);
+  }
+  template <typename Char, typename Traits, typename Alloc>
+  static std::basic_string<Char, Traits, Alloc> to(wchar_t in, const Alloc& a)
+  {
+    return std::basic_string<Char, Traits, Alloc>(
+      unicode_converter<wchar_t, Char>()(in).c_str(), a);
+  }
+
+  template <typename Char>
+  static std::basic_string<Char> to(const std::wstring& in)
+  {
+    return std::basic_string<Char>(unicode_converter<wchar_t, Char>()(in));
+  }
+  template <typename Char>
+  static std::basic_string<Char> to(const wchar_t* in)
+  {
+    return std::basic_string<Char>(unicode_converter<wchar_t, Char>()(in));
+  }
+  template <typename Char>
+  static std::basic_string<Char> to(wchar_t in)
+  {
+    return std::basic_string<Char>(unicode_converter<wchar_t, Char>()(in));
+  }
+};
+
+template <typename T, typename = void>
+struct source_traits
+{
+};
+
+template <typename T, std::size_t N>
+struct source_traits<T[N]>
+{
+  using value_type = T;
+};
+
+template <typename Char, typename Traits, typename Alloc>
+struct source_traits<std::basic_string<Char, Traits, Alloc>>
+{
+  using value_type =
+    typename std::basic_string<Char, Traits, Alloc>::value_type;
+};
+
+template <>
+struct source_traits<cm::string_view>
+{
+  using value_type = cm::string_view::value_type;
+};
+
+#  if CM_FILESYSTEM_SOURCE_TRAITS_ITERATOR
+template <typename T>
+struct source_traits<T, cm::enable_if_t<cm::is_iterator<T>::value, void>>
+{
+  using value_type =
+    typename std::iterator_traits<typename std::decay<T>::type>::value_type;
+};
+#  endif
+
+template <typename In, typename Out>
+struct source_converter
+{
+};
+
+template <>
+struct source_converter<char, char>
+{
+  template <typename Iterator>
+  static void append_range(std::string& p, Iterator b, Iterator e)
+  {
+    if (b == e) {
+      return;
+    }
+    p.append(b, e);
+  }
+  template <typename Iterator>
+  static void append_range(std::string& p, Iterator b)
+  {
+    char e = '\0';
+
+    if (*b == e) {
+      return;
+    }
+    for (; *b != e; ++b) {
+      p.push_back(*b);
+    }
+  }
+
+  static void append_source(std::string& p, const cm::string_view s)
+  {
+    append_range(p, s.begin(), s.end());
+  }
+  template <typename Traits, typename Alloc>
+  static void append_source(std::string& p,
+                            const std::basic_string<char, Traits, Alloc>& s)
+  {
+    append_range(p, s.begin(), s.end());
+  }
+  template <typename Source>
+  static void append_source(std::string& p, const Source& s)
+  {
+    append_range(p, s);
+  }
+
+  static void set_source(std::string& p, std::string&& s) { p = std::move(s); }
+};
+
+template <>
+struct source_converter<wchar_t, char>
+{
+  template <typename Iterator>
+  static void append_range(std::string& p, Iterator b, Iterator e)
+  {
+    if (b == e) {
+      return;
+    }
+
+    std::wstring tmp(b, e);
+    std::string dest = string_converter<wchar_t>::to<char>(tmp);
+    p.append(dest.begin(), dest.end());
+  }
+  template <typename Iterator>
+  static void append_range(std::string& p, Iterator b)
+  {
+    wchar_t e = '\0';
+
+    if (*b == e) {
+      return;
+    }
+    std::wstring tmp;
+    for (; *b != e; ++b) {
+      tmp.push_back(*b);
+    }
+
+    std::string dest = string_converter<wchar_t>::to<char>(tmp);
+    p.append(dest.begin(), dest.end());
+  }
+
+  template <typename Traits, typename Alloc>
+  static void append_source(std::string& p,
+                            const std::basic_string<wchar_t, Traits, Alloc>& s)
+  {
+    append_range(p, s.begin(), s.end());
+  }
+  template <typename Source>
+  static void append_source(std::string& p, const Source& s)
+  {
+    append_range(p, s);
+  }
+
+  static void set_source(std::string& p, std::wstring&& s)
+  {
+    p = string_converter<wchar_t>::to<char>(s);
+  }
+};
+
+template <typename T>
+struct is_pathable_string : std::false_type
+{
+};
+template <typename Traits, typename Alloc>
+struct is_pathable_string<std::basic_string<char, Traits, Alloc>>
+  : std::true_type
+{
+};
+template <typename Traits, typename Alloc>
+struct is_pathable_string<std::basic_string<wchar_t, Traits, Alloc>>
+  : std::true_type
+{
+};
+template <>
+struct is_pathable_string<cm::string_view> : std::true_type
+{
+};
+
+template <typename T, typename = void>
+struct is_pathable_char_array : std::false_type
+{
+};
+template <typename T>
+struct is_pathable_char_array<
+  T,
+  cm::enable_if_t<
+    std::is_same<char*, typename std::decay<T>::type>::value ||
+      std::is_same<wchar_t*, typename std::decay<T>::type>::value,
+    void>>
+  : bool_constant<std::is_same<char*, typename std::decay<T>::type>::value ||
+                  std::is_same<wchar_t*, typename std::decay<T>::type>::value>
+{
+};
+
+template <typename T, typename = void>
+struct is_pathable_iterator : std::false_type
+{
+};
+template <typename T>
+struct is_pathable_iterator<
+  T,
+  cm::enable_if_t<
+    is_input_iterator<T>::value &&
+      (std::is_same<char,
+                    typename std::iterator_traits<
+                      typename std::decay<T>::type>::value_type>::value ||
+       std::is_same<wchar_t,
+                    typename std::iterator_traits<
+                      typename std::decay<T>::type>::value_type>::value),
+    void>>
+  : bool_constant<
+      std::is_same<char,
+                   typename std::iterator_traits<
+                     typename std::decay<T>::type>::value_type>::value ||
+      std::is_same<wchar_t,
+                   typename std::iterator_traits<
+                     typename std::decay<T>::type>::value_type>::value>
+{
+};
+
+#  if defined(__SUNPRO_CC) && defined(__sparc)
+// Oracle DeveloperStudio C++ compiler on Solaris/Sparc fails to compile
+// the full 'is_pathable' check.  We use it only to improve error messages
+// via 'enable_if' when calling methods with incorrect types.  Just
+// pretend all types are allowed so we can at least compile valid code.
+template <typename T>
+struct is_pathable : std::true_type
+{
+};
+#  else
+template <typename T>
+struct is_pathable
+  : bool_constant<is_pathable_string<T>::value ||
+                  is_pathable_char_array<T>::value ||
+                  is_pathable_iterator<T>::value>
+{
+};
+#  endif
+}
+
+class path
+{
+  using path_type = std::string;
+
+  template <typename Source>
+  using enable_if_pathable =
+    enable_if_t<internals::is_pathable<Source>::value, path&>;
+
+  enum class filename_fragment : unsigned char
+  {
+    stem,
+    extension
+  };
+
+public:
+#  if defined(_WIN32) && !defined(__CYGWIN__)
+  using value_type = wchar_t;
+#  else
+  using value_type = char;
+#  endif
+  using string_type = std::basic_string<value_type>;
+
+  class iterator;
+  using const_iterator = iterator;
+
+  enum format : unsigned char
+  {
+    auto_format,
+    native_format,
+    generic_format
+  };
+
+#  if defined(_WIN32) && !defined(__CYGWIN__)
+  static constexpr value_type preferred_separator = L'\\';
+#  else
+  static constexpr value_type preferred_separator = '/';
+#  endif
+
+  // Constructors
+  // ============
+  path() noexcept {}
+  path(const path& p)
+    : path_(p.path_)
+  {
+  }
+  path(path&& p) noexcept
+    : path_(std::move(p.path_))
+  {
+  }
+  path(string_type&& source, format fmt = auto_format)
+  {
+    (void)fmt;
+    internals::source_converter<value_type, path_type::value_type>::set_source(
+      this->path_, std::move(source));
+  }
+  template <typename Source, typename = enable_if_pathable<Source>>
+  path(const Source& source, format fmt = auto_format)
+  {
+    (void)fmt;
+    internals::source_converter<
+      typename internals::source_traits<Source>::value_type,
+      path_type::value_type>::append_source(this->path_, source);
+  }
+  template <typename Iterator, typename = enable_if_pathable<Iterator>>
+  path(const Iterator first, Iterator last, format fmt = auto_format)
+  {
+    (void)fmt;
+    internals::source_converter<
+      typename std::iterator_traits<Iterator>::value_type,
+      path_type::value_type>::append_range(this->path_, first, last);
+  }
+
+  ~path() = default;
+
+  // Assignments
+  // ===========
+  path& operator=(const path& p)
+  {
+    if (this != &p) {
+      this->path_ = p.path_;
+    }
+    return *this;
+  }
+  path& operator=(path&& p) noexcept
+  {
+    if (this != &p) {
+      this->path_ = std::move(p.path_);
+    }
+    return *this;
+  }
+  path& operator=(string_type&& source) { return this->assign(source); }
+  template <typename Source, typename = enable_if_pathable<Source>>
+  path& operator=(const Source& source)
+  {
+    return this->assign(source);
+  }
+
+  path& assign(string_type&& source)
+  {
+    internals::source_converter<value_type, path_type::value_type>::set_source(
+      this->path_, std::move(source));
+    return *this;
+  }
+  template <typename Source, typename = enable_if_pathable<Source>>
+  path& assign(const Source& source)
+  {
+    this->path_.clear();
+    internals::source_converter<
+      typename internals::source_traits<Source>::value_type,
+      path_type::value_type>::append_source(this->path_, source);
+    return *this;
+  }
+  template <typename Iterator, typename = enable_if_pathable<Iterator>>
+  path& assign(Iterator first, Iterator last)
+  {
+    this->path_.clear();
+    internals::source_converter<
+      typename std::iterator_traits<Iterator>::value_type,
+      path_type::value_type>::append_range(this->path_, first, last);
+    return *this;
+  }
+
+  // Concatenation
+  // =============
+  path& operator/=(const path& p);
+
+  template <typename Source, typename = enable_if_pathable<Source>>
+  path& append(const Source& source)
+  {
+    return this->operator/=(path(source));
+  }
+  template <typename Source>
+  path& operator/=(const Source& source)
+  {
+    return this->append(source);
+  }
+
+  template <typename Iterator, typename = enable_if_pathable<Iterator>>
+  path& append(Iterator first, Iterator last)
+  {
+    return this->operator/=(path(first, last));
+  }
+
+  path& operator+=(const path& p)
+  {
+    this->path_ += p.path_;
+    return *this;
+  }
+  path& operator+=(const string_type& str)
+  {
+    this->path_ +=
+      internals::string_converter<value_type>::to<path_type::value_type>(str);
+    return *this;
+  }
+  path& operator+=(cm::string_view str)
+  {
+    this->path_.append(str.begin(), str.end());
+    return *this;
+  }
+  path& operator+=(const value_type* str)
+  {
+    this->path_ +=
+      internals::string_converter<value_type>::to<path_type::value_type>(str);
+    return *this;
+  }
+  path& operator+=(const value_type c)
+  {
+    this->path_ +=
+      internals::string_converter<value_type>::to<path_type::value_type>(c);
+    return *this;
+  }
+  template <typename Source, typename = enable_if_pathable<Source>>
+  path& concat(const Source& source)
+  {
+    internals::source_converter<
+      typename internals::source_traits<Source>::value_type,
+      path_type::value_type>::append_source(this->path_, source);
+    return *this;
+  }
+  template <typename Source>
+  path& operator+=(const Source& source)
+  {
+    return this->concat(source);
+  }
+  template <typename Iterator, typename = enable_if_pathable<Iterator>>
+  path& concat(Iterator first, Iterator last)
+  {
+    internals::source_converter<
+      typename std::iterator_traits<Iterator>::value_type,
+      path_type::value_type>::append_range(this->path_, first, last);
+    return *this;
+  }
+
+  // Modifiers
+  // =========
+  void clear() noexcept { this->path_.clear(); }
+
+  path& make_preferred()
+  {
+#  if defined(_WIN32) && !defined(__CYGWIN__)
+    std::replace(
+      this->path_.begin(), this->path_.end(), '/',
+      static_cast<path_type::value_type>(this->preferred_separator));
+#  endif
+    return *this;
+  }
+
+  path& remove_filename()
+  {
+    auto fname = this->get_filename();
+    if (!fname.empty()) {
+      this->path_.erase(fname.data() - this->path_.data());
+    }
+    return *this;
+  }
+
+  path& replace_filename(const path& replacement)
+  {
+    this->remove_filename();
+    this->operator/=(replacement);
+    return *this;
+  }
+
+  path& replace_extension(const path& replacement = path())
+  {
+    auto ext = this->get_filename_fragment(filename_fragment::extension);
+    if (!ext.empty()) {
+      this->path_.erase(ext.data() - this->path_.data());
+    }
+    if (!replacement.path_.empty()) {
+      if (replacement.path_[0] != '.') {
+        this->path_ += '.';
+      }
+      this->path_.append(replacement.path_);
+    }
+    return *this;
+  }
+
+  void swap(path& other) noexcept { this->path_.swap(other.path_); }
+
+  // Format observers
+  // ================
+  const string_type& native() const noexcept
+  {
+#  if defined(_WIN32) && !defined(__CYGWIN__)
+    this->native_path_ = internals::string_converter<
+      path_type::value_type>::to<string_type::value_type>(this->path_);
+    return this->native_path_;
+#  else
+    return this->path_;
+#  endif
+  }
+  const value_type* c_str() const noexcept { return this->native().c_str(); }
+  operator string_type() const { return this->native(); }
+
+  template <
+    typename Char, typename Traits = std::char_traits<Char>,
+    typename Alloc = std::allocator<Char>,
+    cm::enable_if_t<(std::is_same<Char, char>::value &&
+                     std::is_same<Traits, std::char_traits<char>>::value) ||
+                      (std::is_same<Char, wchar_t>::value &&
+                       std::is_same<Traits, std::char_traits<wchar_t>>::value),
+                    int> = 1>
+  std::basic_string<Char, Traits, Alloc> string(const Alloc& a = Alloc()) const
+  {
+    return internals::string_converter<path_type::value_type>::to<Char, Traits,
+                                                                  Alloc>(
+      this->path_, a);
+  }
+  const std::string string() const { return this->path_; }
+  std::wstring wstring() const
+  {
+    std::string out = this->string();
+    return internals::string_converter<path_type::value_type>::to<
+      std::wstring::value_type>(out);
+  }
+
+  template <
+    typename Char, typename Traits = std::char_traits<Char>,
+    typename Alloc = std::allocator<Char>,
+    cm::enable_if_t<(std::is_same<Char, char>::value &&
+                     std::is_same<Traits, std::char_traits<char>>::value) ||
+                      (std::is_same<Char, wchar_t>::value &&
+                       std::is_same<Traits, std::char_traits<wchar_t>>::value),
+                    int> = 1>
+  std::basic_string<Char, Traits, Alloc> generic_string(
+    const Alloc& a = Alloc()) const
+  {
+    return internals::string_converter<path_type::value_type>::to<Char, Traits,
+                                                                  Alloc>(
+      this->get_generic(), a);
+  }
+  std::string generic_string() const { return this->get_generic(); }
+  std::wstring generic_wstring() const
+  {
+    auto dest = this->generic_string();
+    return internals::string_converter<path_type::value_type>::to<
+      std::wstring::value_type>(dest);
+  }
+
+  // Compare
+  // =======
+  int compare(const path& p) const noexcept
+  {
+    return this->compare_path(p.path_);
+  }
+  int compare(const string_type& str) const
+  {
+    return this->compare_path(
+      internals::string_converter<value_type>::to<path_type::value_type>(str));
+  }
+  int compare(const value_type* str) const
+  {
+    return this->compare_path(
+      internals::string_converter<value_type>::to<path_type::value_type>(str));
+  }
+  int compare(cm::string_view str) const { return this->compare_path(str); }
+
+  // Generation
+  // ==========
+  path lexically_normal() const;
+
+  path lexically_relative(const path& base) const;
+
+  path lexically_proximate(const path& base) const
+  {
+    path result = this->lexically_relative(base);
+    return result.empty() ? *this : result;
+  }
+
+  // Decomposition
+  // =============
+  path root_name() const { return get_root_name(); }
+
+  path root_directory() const { return this->get_root_directory(); }
+
+  path root_path() const
+  {
+    return this->root_name().append(this->get_root_directory());
+  }
+
+  path relative_path() const { return this->get_relative_path(); }
+
+  path parent_path() const { return this->get_parent_path(); }
+
+  path filename() const { return this->get_filename(); }
+
+  path stem() const
+  {
+    return this->get_filename_fragment(filename_fragment::stem);
+  }
+  path extension() const
+  {
+    return this->get_filename_fragment(filename_fragment::extension);
+  }
+
+  // Queries
+  // =======
+  bool empty() const noexcept { return this->path_.empty(); }
+
+  bool has_root_name() const { return !this->get_root_name().empty(); }
+
+  bool has_root_directory() const
+  {
+    return !this->get_root_directory().empty();
+  }
+
+  bool has_root_path() const
+  {
+    return this->has_root_name() || this->has_root_directory();
+  }
+
+  bool has_relative_path() const { return !this->get_relative_path().empty(); }
+
+  bool has_parent_path() const { return !this->get_parent_path().empty(); }
+
+  bool has_filename() const { return !this->get_filename().empty(); }
+
+  bool has_stem() const
+  {
+    return !this->get_filename_fragment(filename_fragment::stem).empty();
+  }
+  bool has_extension() const
+  {
+    return !this->get_filename_fragment(filename_fragment::extension).empty();
+  }
+
+  bool is_absolute() const
+  {
+#  if defined(_WIN32) && !defined(__CYGWIN__)
+    return this->has_root_name() && this->has_root_directory();
+#  else
+    // For CYGWIN, root_name (i.e. //host or /cygdrive/x) is not considered.
+    // Same as current GNU g++ implementation (9.3).
+    return this->has_root_directory();
+#  endif
+  }
+
+  bool is_relative() const { return !this->is_absolute(); }
+
+  // Iterators
+  // =========
+  inline iterator begin() const;
+  inline iterator end() const;
+
+  // Non-members
+  // ===========
+  friend inline bool operator==(const path& lhs, const path& rhs) noexcept
+  {
+    return lhs.compare(rhs) == 0;
+  }
+  friend inline bool operator!=(const path& lhs, const path& rhs) noexcept
+  {
+    return lhs.compare(rhs) != 0;
+  }
+  friend inline bool operator<(const path& lhs, const path& rhs) noexcept
+  {
+    return lhs.compare(rhs) < 0;
+  }
+  friend inline bool operator<=(const path& lhs, const path& rhs) noexcept
+  {
+    return lhs.compare(rhs) <= 0;
+  }
+  friend inline bool operator>(const path& lhs, const path& rhs) noexcept
+  {
+    return lhs.compare(rhs) > 0;
+  }
+  friend inline bool operator>=(const path& lhs, const path& rhs) noexcept
+  {
+    return lhs.compare(rhs) >= 0;
+  }
+
+  friend inline path operator/(const path& lhs, const path& rhs)
+  {
+    path result(lhs);
+    result /= rhs;
+
+    return result;
+  }
+
+  template <typename Char, typename Traits>
+  friend inline cm::enable_if_t<
+    (std::is_same<Char, path::value_type>::value &&
+     std::is_same<Traits, std::char_traits<path::value_type>>::value) ||
+      (std::is_same<Char, path::path_type::value_type>::value &&
+       std::is_same<Traits,
+                    std::char_traits<path::path_type::value_type>>::value),
+    std::basic_ostream<Char, Traits>&>
+  operator<<(std::basic_ostream<Char, Traits>& os, const path& p)
+  {
+    os << cm::quoted(p.string<Char, Traits>());
+    return os;
+  }
+
+  template <typename Char, typename Traits>
+  friend inline cm::enable_if_t<
+    (std::is_same<Char, path::value_type>::value &&
+     std::is_same<Traits, std::char_traits<path::value_type>>::value) ||
+      (std::is_same<Char, path::path_type::value_type>::value &&
+       std::is_same<Traits,
+                    std::char_traits<path::path_type::value_type>>::value),
+    std::basic_istream<Char, Traits>&>
+  operator>>(std::basic_istream<Char, Traits>& is, path& p)
+  {
+    std::basic_string<Char, Traits> tmp;
+    is >> cm::quoted(tmp);
+    p = tmp;
+    return is;
+  }
+
+private:
+  friend class iterator;
+  friend std::size_t hash_value(const path& p) noexcept;
+
+  path_type get_generic() const;
+
+  cm::string_view get_root_name() const;
+  cm::string_view get_root_directory() const;
+  cm::string_view get_relative_path() const;
+  cm::string_view get_parent_path() const;
+  cm::string_view get_filename() const;
+  cm::string_view get_filename_fragment(filename_fragment fragment) const;
+
+  int compare_path(cm::string_view str) const;
+
+  path_type path_;
+#  if defined(_WIN32) && !defined(__CYGWIN__)
+  mutable string_type native_path_;
+#  endif
+};
+
+class path::iterator
+{
+public:
+  using iterator_category = std::bidirectional_iterator_tag;
+
+  using value_type = path;
+  using difference_type = std::ptrdiff_t;
+  using pointer = const path*;
+  using reference = const path&;
+
+  iterator();
+  iterator(const iterator& other);
+
+  ~iterator();
+
+  iterator& operator=(const iterator& other);
+
+  reference operator*() const { return this->path_element_; }
+
+  pointer operator->() const { return &this->path_element_; }
+
+  iterator& operator++();
+
+  iterator operator++(int)
+  {
+    iterator it(*this);
+    this->operator++();
+    return it;
+  }
+
+  iterator& operator--();
+
+  iterator operator--(int)
+  {
+    iterator it(*this);
+    this->operator--();
+    return it;
+  }
+
+private:
+  friend class path;
+  friend bool operator==(const iterator&, const iterator&);
+
+  iterator(const path* p, bool at_end = false);
+
+  const path* path_;
+  std::unique_ptr<internals::path_parser> parser_;
+  path path_element_;
+};
+
+inline path::iterator path::begin() const
+{
+  return iterator(this);
+}
+inline path::iterator path::end() const
+{
+  return iterator(this, true);
+}
+
+bool operator==(const path::iterator& lhs, const path::iterator& rhs);
+
+inline bool operator!=(const path::iterator& lhs, const path::iterator& rhs)
+{
+  return !(lhs == rhs);
+}
+
+// Non-member functions
+// ====================
+inline void swap(path& lhs, path& rhs) noexcept
+{
+  lhs.swap(rhs);
+}
+
+std::size_t hash_value(const path& p) noexcept;
+
+#endif
+
+} // namespace filesystem
+} // namespace cm
+
+#endif
diff --git a/Utilities/std/cm/iomanip b/Utilities/std/cm/iomanip
new file mode 100644
index 0000000..6f68530
--- /dev/null
+++ b/Utilities/std/cm/iomanip
@@ -0,0 +1,183 @@
+// -*-c++-*-
+// vim: set ft=cpp:
+
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file Copyright.txt or https://cmake.org/licensing for details.  */
+#ifndef cm_iomanip
+#define cm_iomanip
+
+#include <iomanip> // IWYU pragma: export
+#if __cplusplus < 201402L || defined(_MSVC_LANG) && _MSVC_LANG < 201402L
+#  include <ios>
+#  include <iostream>
+#  include <sstream>
+#  include <string>
+#  include <type_traits>
+#endif
+#if __cplusplus < 201703L || defined(_MSVC_LANG) && _MSVC_LANG < 201703L
+#  include <cm/string_view>
+#endif
+
+namespace cm {
+
+#if __cplusplus >= 201402L || defined(_MSVC_LANG) && _MSVC_LANG >= 201402L
+
+using std::quoted;
+
+#  if __cplusplus < 201703L || defined(_MSVC_LANG) && _MSVC_LANG < 201703L
+
+inline auto quoted(cm::string_view str, char delim = '"', char escape = '\\')
+{
+  return std::quoted(static_cast<std::string>(str), delim, escape);
+}
+
+#  endif
+
+#else
+
+namespace internals {
+
+// Struct for delimited strings.
+template <typename String, typename Char>
+struct quoted_string
+{
+  static_assert(std::is_reference<String>::value ||
+                  std::is_pointer<String>::value,
+                "String type must be pointer or reference");
+
+  quoted_string(String str, Char del, Char esc)
+    : string_(str)
+    , delim_{ del }
+    , escape_{ esc }
+  {
+  }
+
+  quoted_string& operator=(quoted_string&) = delete;
+
+  String string_;
+  Char delim_;
+  Char escape_;
+};
+
+template <>
+struct quoted_string<cm::string_view, char>
+{
+  quoted_string(cm::string_view str, char del, char esc)
+    : string_(str)
+    , delim_{ del }
+    , escape_{ esc }
+  {
+  }
+
+  quoted_string& operator=(quoted_string&) = delete;
+
+  cm::string_view string_;
+  char delim_;
+  char escape_;
+};
+
+template <typename Char, typename Traits>
+std::basic_ostream<Char, Traits>& operator<<(
+  std::basic_ostream<Char, Traits>& os,
+  const quoted_string<const Char*, Char>& str)
+{
+  std::basic_ostringstream<Char, Traits> ostr;
+  ostr << str.delim_;
+  for (const Char* c = str.string_; *c; ++c) {
+    if (*c == str.delim_ || *c == str.escape_)
+      ostr << str.escape_;
+    ostr << *c;
+  }
+  ostr << str.delim_;
+
+  return os << ostr.str();
+}
+
+template <typename Char, typename Traits, typename String>
+std::basic_ostream<Char, Traits>& operator<<(
+  std::basic_ostream<Char, Traits>& os, const quoted_string<String, Char>& str)
+{
+  std::basic_ostringstream<Char, Traits> ostr;
+  ostr << str.delim_;
+  for (auto c : str.string_) {
+    if (c == str.delim_ || c == str.escape_)
+      ostr << str.escape_;
+    ostr << c;
+  }
+  ostr << str.delim_;
+
+  return os << ostr.str();
+}
+
+template <typename Char, typename Traits, typename Alloc>
+std::basic_istream<Char, Traits>& operator>>(
+  std::basic_istream<Char, Traits>& is,
+  const quoted_string<std::basic_string<Char, Traits, Alloc>&, Char>& str)
+{
+  Char c;
+  is >> c;
+  if (!is.good())
+    return is;
+  if (c != str.delim_) {
+    is.unget();
+    is >> str.string_;
+    return is;
+  }
+  str.string_.clear();
+  std::ios_base::fmtflags flags =
+    is.flags(is.flags() & ~std::ios_base::skipws);
+  do {
+    is >> c;
+    if (!is.good())
+      break;
+    if (c == str.escape_) {
+      is >> c;
+      if (!is.good())
+        break;
+    } else if (c == str.delim_)
+      break;
+    str.string_ += c;
+  } while (true);
+  is.setf(flags);
+
+  return is;
+}
+}
+
+template <typename Char>
+inline internals::quoted_string<const Char*, Char> quoted(
+  const Char* str, Char delim = Char('"'), Char escape = Char('\\'))
+{
+  return internals::quoted_string<const Char*, Char>(str, delim, escape);
+}
+
+template <typename Char, typename Traits, typename Alloc>
+inline internals::quoted_string<const std::basic_string<Char, Traits, Alloc>&,
+                                Char>
+quoted(const std::basic_string<Char, Traits, Alloc>& str,
+       Char delim = Char('"'), Char escape = Char('\\'))
+{
+  return internals::quoted_string<
+    const std::basic_string<Char, Traits, Alloc>&, Char>(str, delim, escape);
+}
+
+template <typename Char, typename Traits, typename Alloc>
+inline internals::quoted_string<std::basic_string<Char, Traits, Alloc>&, Char>
+quoted(std::basic_string<Char, Traits, Alloc>& str, Char delim = Char('"'),
+       Char escape = Char('\\'))
+{
+  return internals::quoted_string<std::basic_string<Char, Traits, Alloc>&,
+                                  Char>(str, delim, escape);
+}
+
+inline internals::quoted_string<cm::string_view, char> quoted(
+  cm::string_view str, char delim = '"', char escape = '\\')
+{
+  return internals::quoted_string<cm::string_view, char>(str, delim, escape);
+}
+
+#endif
+
+} // namespace cm
+
+#endif
diff --git a/Utilities/std/cm/memory b/Utilities/std/cm/memory
index dd0f822..5611f6b 100644
--- a/Utilities/std/cm/memory
+++ b/Utilities/std/cm/memory
@@ -6,7 +6,10 @@
 #ifndef cm_memory
 #define cm_memory
 
+#include "cmSTL.hxx" // IWYU pragma: keep
+
 #include <memory> // IWYU pragma: export
+
 #if !defined(CMake_HAVE_CXX_MAKE_UNIQUE)
 #  include <cstddef>
 #  include <type_traits>
diff --git a/Utilities/std/cmSTL.hxx.in b/Utilities/std/cmSTL.hxx.in
new file mode 100644
index 0000000..9c8605c
--- /dev/null
+++ b/Utilities/std/cmSTL.hxx.in
@@ -0,0 +1,10 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file Copyright.txt or https://cmake.org/licensing for details.  */
+#ifndef cmSTL_hxx
+#define cmSTL_hxx
+
+/* Whether CMake is using its own STL implementation.  */
+#cmakedefine CMake_HAVE_CXX_MAKE_UNIQUE
+#cmakedefine CMake_HAVE_CXX_FILESYSTEM
+
+#endif
diff --git a/bootstrap b/bootstrap
index 04067dc..2ef0fbb 100755
--- a/bootstrap
+++ b/bootstrap
@@ -432,6 +432,7 @@
   cmSiteNameCommand \
   cmSourceFile \
   cmSourceFileLocation \
+  cmStandardLevelResolver \
   cmState \
   cmStateDirectory \
   cmStateSnapshot \
@@ -478,6 +479,7 @@
 fi
 
 CMAKE_STD_CXX_HEADERS="\
+  filesystem \
   memory \
   optional \
   shared_mutex \
@@ -485,6 +487,7 @@
   utility \
 "
 CMAKE_STD_CXX_SOURCES="\
+  fs_path \
   string_view \
 "
 
@@ -633,6 +636,8 @@
   --system-libuv          use system-installed libuv library
   --no-system-libuv       use cmake-provided libuv library (default)
 
+  --bootstrap-system-libuv use system-installed libuv library for bootstrap
+
   --qt-gui                build the Qt-based GUI (requires Qt >= 4.2)
   --no-qt-gui             do not build the Qt-based GUI (default)
   --qt-qmake=<qmake>      use <qmake> as the qmake executable to find Qt
@@ -855,6 +860,7 @@
 cmake_parallel_make=
 cmake_ccache_enabled=
 cmake_prefix_dir="${cmake_default_prefix}"
+bootstrap_system_libuv=
 while test $# != 0; do
   case "$1" in
   --prefix=*) dir=`cmake_arg "$1"`
@@ -874,6 +880,7 @@
   --no-system-bzip2|--no-system-curl|--no-system-expat|--no-system-jsoncpp|--no-system-libarchive|--no-system-librhash|--no-system-zlib|--no-system-liblzma|--no-system-nghttp2|--no-system-zstd|--no-system-libuv)
     lib=`cmake_arg "$1" "--no-system-"`
     cmake_bootstrap_system_libs="${cmake_bootstrap_system_libs} -DCMAKE_USE_SYSTEM_LIBRARY_`cmake_toupper $lib`=0" ;;
+  --bootstrap-system-libuv) bootstrap_system_libuv="1" ;;
   --qt-gui) cmake_bootstrap_qt_gui="1" ;;
   --no-qt-gui) cmake_bootstrap_qt_gui="0" ;;
   --qt-qmake=*) cmake_bootstrap_qt_qmake=`cmake_arg "$1"` ;;
@@ -1249,7 +1256,7 @@
 #-----------------------------------------------------------------------------
 # Test CXX features
 
-cmake_cxx_features="make_unique"
+cmake_cxx_features="make_unique filesystem"
 
 for feature in ${cmake_cxx_features}; do
   eval "cmake_have_cxx_${feature}=0"
@@ -1269,6 +1276,9 @@
   fi
 done
 
+cmake_generate_file "${cmake_bootstrap_dir}/cmSTL.hxx" ""
+
+
 #-----------------------------------------------------------------------------
 # Test Make
 
@@ -1489,9 +1499,11 @@
 for a in ${CMAKE_CXX_SOURCES} ${CMAKE_C_SOURCES} ${CMAKE_STD_CXX_SOURCES} ${LexerParser_CXX_SOURCES} ${LexerParser_C_SOURCES} ${KWSYS_CXX_SOURCES} ${KWSYS_C_SOURCES}; do
   objs="${objs} ${a}.o"
 done
-for a in ${LIBUV_C_SOURCES}; do
-  objs="${objs} uv-`cmake_obj ${a}`"
-done
+if test "x${bootstrap_system_libuv}" = "x"; then
+  for a in ${LIBUV_C_SOURCES}; do
+    objs="${objs} uv-`cmake_obj ${a}`"
+  done
+fi
 
 libs=""
 
@@ -1529,14 +1541,20 @@
       ;;
   esac
 fi
-uv_c_flags="${uv_c_flags} `cmake_escape "-I${cmake_source_dir}/Utilities/cmlibuv/include"`"
-if ${cmake_system_mingw}; then
-  uv_c_flags="${uv_c_flags} `cmake_escape "-I${cmake_source_dir}/Utilities/cmlibuv/src/win"`"
+if test "x${bootstrap_system_libuv}" = "x"; then
+  uv_c_flags="${uv_c_flags} `cmake_escape "-I${cmake_source_dir}/Utilities/cmlibuv/include"`"
+  if ${cmake_system_mingw}; then
+    uv_c_flags="${uv_c_flags} `cmake_escape "-I${cmake_source_dir}/Utilities/cmlibuv/src/win"`"
+  else
+    uv_c_flags="${uv_c_flags} `cmake_escape "-I${cmake_source_dir}/Utilities/cmlibuv/src/unix"`"
+  fi
+  uv_c_flags="${uv_c_flags} `cmake_escape "-I${cmake_source_dir}/Utilities/cmlibuv/src"`"
 else
-  uv_c_flags="${uv_c_flags} `cmake_escape "-I${cmake_source_dir}/Utilities/cmlibuv/src/unix"`"
+  if test `which pkg-config`; then
+    uv_c_flags="${uv_c_flags} `pkg-config --cflags libuv`"
+  fi
+  libs="${libs} -luv"
 fi
-uv_c_flags="${uv_c_flags} `cmake_escape "-I${cmake_source_dir}/Utilities/cmlibuv/src"`"
-
 if test "x${cmake_ansi_cxx_flags}" != "x"; then
   cmake_cxx_flags="${cmake_ansi_cxx_flags} ${cmake_cxx_flags}"
 fi
@@ -1618,11 +1636,13 @@
   echo "${a}.o : ${src} ${dep}" >> "${cmake_bootstrap_dir}/Makefile"
   echo "	${cmake_cxx_compiler} ${cmake_cxx_flags} -DKWSYS_NAMESPACE=cmsys ${src_flags} -c ${src} -o ${a}.o" >> "${cmake_bootstrap_dir}/Makefile"
 done
-for a in ${LIBUV_C_SOURCES}; do
-  src=`cmake_escape "${cmake_source_dir}/Utilities/cmlibuv/${a}"`
-  echo "uv-`cmake_obj ${a}` : ${src} ${dep}" >> "${cmake_bootstrap_dir}/Makefile"
-  echo "	${cmake_c_compiler} ${cmake_c_flags} ${uv_c_flags} -c ${src} -o uv-`cmake_obj ${a}`" >> "${cmake_bootstrap_dir}/Makefile"
-done
+if test "x${bootstrap_system_libuv}" = "x"; then
+  for a in ${LIBUV_C_SOURCES}; do
+    src=`cmake_escape "${cmake_source_dir}/Utilities/cmlibuv/${a}"`
+    echo "uv-`cmake_obj ${a}` : ${src} ${dep}" >> "${cmake_bootstrap_dir}/Makefile"
+    echo "	${cmake_c_compiler} ${cmake_c_flags} ${uv_c_flags} -c ${src} -o uv-`cmake_obj ${a}`" >> "${cmake_bootstrap_dir}/Makefile"
+  done
+fi
 echo '
 rebuild_cache:
 	cd "${cmake_binary_dir}" && "${cmake_source_dir}/bootstrap"