Merge topic 'preset-comments'

7d2cc6ece6 presets: Allow comments in presets files

Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !9608
diff --git a/.gitlab/ci/cmake.ps1 b/.gitlab/ci/cmake.ps1
index f7d0007..644cf56 100644
--- a/.gitlab/ci/cmake.ps1
+++ b/.gitlab/ci/cmake.ps1
@@ -1,12 +1,12 @@
 $erroractionpreference = "stop"
 
-$version = "3.30.0-rc3"
+$version = "3.30.0-rc4"
 
 if ("$env:PROCESSOR_ARCHITECTURE" -eq "AMD64") {
-    $sha256sum = "ECAE920994E96649A22C0DF093718537354AF08054C998C8F4B862040AEBEE87"
+    $sha256sum = "9086FA9C83E5A3DA2599220D4E426D1DFEEFAC417F2ABF19862A91620C38FAEE"
     $platform = "windows-x86_64"
 } elseif ("$env:PROCESSOR_ARCHITECTURE" -eq "ARM64") {
-    $sha256sum = "9768BE435BB5619C7539FE66F180F0056A59F29BDC28CAA3E5A0FD1EFE963A93"
+    $sha256sum = "90A45E3E2B89F7670D674685223CCDC93C1F51BB5B65A84FE7EB1130F06ACEEA"
     $platform = "windows-arm64"
 } else {
     throw ('unknown PROCESSOR_ARCHITECTURE: ' + "$env:PROCESSOR_ARCHITECTURE")
diff --git a/.gitlab/ci/cmake.sh b/.gitlab/ci/cmake.sh
index ec690a2..4427c09 100755
--- a/.gitlab/ci/cmake.sh
+++ b/.gitlab/ci/cmake.sh
@@ -2,22 +2,22 @@
 
 set -e
 
-readonly version="3.30.0-rc3"
+readonly version="3.30.0-rc4"
 
 case "$(uname -s)-$(uname -m)" in
     Linux-x86_64)
         shatool="sha256sum"
-        sha256sum="e5626890d969b26a60db6abfcbbfdc5fa06cc161d72e4f148fde631278e4c5e1"
+        sha256sum="0fe59e3a5b2915943ac7535fa8c1e3026fc0abefe3efd47c5ff3f3b448dac457"
         platform="linux-x86_64"
         ;;
     Linux-aarch64)
         shatool="sha256sum"
-        sha256sum="bfefefda491d91eeb61d9f199b75f0b0e227a1880919cb585cda78af0210909b"
+        sha256sum="5989bd61c819ff0ea30f8d16f1a0b53b9d96daf610bad76272fa59c6024fbea3"
         platform="linux-aarch64"
         ;;
     Darwin-*)
         shatool="shasum -a 256"
-        sha256sum="a39c3e21ad921a32c4b4d9b8dbd546c388b72e7b5ea624d908846dc6de3dc323"
+        sha256sum="1b15a6e216452bebfadb9f6166661b720eb073a07e94c4c602652e82e799ba14"
         platform="macos-universal"
         ;;
     *)
diff --git a/Auxiliary/cmake-mode.el b/Auxiliary/cmake-mode.el
index cfa0173..893c0d4 100644
--- a/Auxiliary/cmake-mode.el
+++ b/Auxiliary/cmake-mode.el
@@ -279,7 +279,7 @@
 
 ;------------------------------------------------------------------------------
 
-(defun cmake--syntax-propertize-until-bracket-close (syntax)
+(defun cmake--syntax-propertize-until-bracket-close (syntax end)
   ;; This function assumes that a previous search has matched the
   ;; beginning of a bracket_comment or bracket_argument and that the
   ;; second capture group has matched the equal signs between the two
@@ -307,10 +307,10 @@
   (syntax-propertize-rules
    ("\\(#\\)\\[\\(=*\\)\\["
     (1
-     (prog1 "!" (cmake--syntax-propertize-until-bracket-close "!"))))
+     (prog1 "!" (cmake--syntax-propertize-until-bracket-close "!" end))))
    ("\\(\\[\\)\\(=*\\)\\["
     (1
-     (prog1 "|" (cmake--syntax-propertize-until-bracket-close "|"))))))
+     (prog1 "|" (cmake--syntax-propertize-until-bracket-close "|" end))))))
 
 ;; Syntax table for this mode.
 (defvar cmake-mode-syntax-table nil
diff --git a/Help/command/file.rst b/Help/command/file.rst
index 5b9dfac..ede95a1 100644
--- a/Help/command/file.rst
+++ b/Help/command/file.rst
@@ -398,10 +398,19 @@
   ============== ======================================================
 
 .. signature::
-  file(MAKE_DIRECTORY <directories>...)
+  file(MAKE_DIRECTORY <directories>... [RESULT <result>])
 
   Create the given directories and their parents as needed.
 
+  The options are:
+
+    ``RESULT <result>``
+      .. versionadded:: 3.31
+
+      Set ``<result>`` variable to ``0`` on success or an error message
+      otherwise. If ``RESULT`` is not specified and the operation fails,
+      an error is emitted.
+
   .. versionchanged:: 3.30
     ``<directories>`` can be an empty list. CMake 3.29 and earlier required
     at least one directory to be given.
diff --git a/Help/cpack_gen/deb.rst b/Help/cpack_gen/deb.rst
index 23436de..a4063d9 100644
--- a/Help/cpack_gen/deb.rst
+++ b/Help/cpack_gen/deb.rst
@@ -654,6 +654,31 @@
    This value is not interpreted. It is possible to pass an optional
    revision number of the referenced source package as well.
 
+.. variable:: CPACK_DEBIAN_PACKAGE_MULTIARCH
+              CPACK_DEBIAN_<COMPONENT>_PACKAGE_MULTIARCH
+
+ Sets the `Multi-Arch` field of the Debian package.
+ Packages can declare in their control file how they should handle
+ situations, where packages for different architectures are being installed
+ on the same machine.
+
+ :Mandatory: No
+ :Default:
+
+   - An empty string for non-component based installations
+   - :variable:`CPACK_DEBIAN_PACKAGE_MULTIARCH` for component-based
+     installations.
+
+ .. versionadded:: 3.31
+  Per-component :variable:`!CPACK_DEBIAN_<COMPONENT>_PACKAGE_MULTIARCH` variables.
+
+ See https://wiki.debian.org/MultiArch/Hints
+
+ .. note::
+
+   This value is validated. It must be one of the following values:
+   ``same``, ``foreign``, ``allowed``.
+
 Packaging of debug information
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
diff --git a/Help/dev/make_directory-optional-result.rst b/Help/dev/make_directory-optional-result.rst
new file mode 100644
index 0000000..be842fe
--- /dev/null
+++ b/Help/dev/make_directory-optional-result.rst
@@ -0,0 +1,5 @@
+make_directory-optional-result
+------------------------------
+
+* The :command:`file(MAKE_DIRECTORY)` learned to
+optionally capture failure in a result variable.
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index 6400a93..1abdd62 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -467,7 +467,7 @@
    /variable/CMAKE_LANG_INCLUDE_WHAT_YOU_USE
    /variable/CMAKE_LANG_LINK_GROUP_USING_FEATURE
    /variable/CMAKE_LANG_LINK_GROUP_USING_FEATURE_SUPPORTED
-   /variable/CMAKE_LANG_LINK_LIBRARY_FEATURE_PROPERTIES
+   /variable/CMAKE_LANG_LINK_LIBRARY_FEATURE_ATTRIBUTES
    /variable/CMAKE_LANG_LINK_LIBRARY_FILE_FLAG
    /variable/CMAKE_LANG_LINK_LIBRARY_FLAG
    /variable/CMAKE_LANG_LINK_LIBRARY_USING_FEATURE
@@ -486,7 +486,7 @@
    /variable/CMAKE_LINK_GROUP_USING_FEATURE
    /variable/CMAKE_LINK_GROUP_USING_FEATURE_SUPPORTED
    /variable/CMAKE_LINK_INTERFACE_LIBRARIES
-   /variable/CMAKE_LINK_LIBRARY_FEATURE_PROPERTIES
+   /variable/CMAKE_LINK_LIBRARY_FEATURE_ATTRIBUTES
    /variable/CMAKE_LINK_LIBRARY_FILE_FLAG
    /variable/CMAKE_LINK_LIBRARY_FLAG
    /variable/CMAKE_LINK_LIBRARY_USING_FEATURE
diff --git a/Help/prop_tgt/MACOSX_FRAMEWORK_INFO_PLIST.rst b/Help/prop_tgt/MACOSX_FRAMEWORK_INFO_PLIST.rst
index 82fdcc0..a1f7c66 100644
--- a/Help/prop_tgt/MACOSX_FRAMEWORK_INFO_PLIST.rst
+++ b/Help/prop_tgt/MACOSX_FRAMEWORK_INFO_PLIST.rst
@@ -12,12 +12,20 @@
 The following target properties may be set to specify content to be
 configured into the file:
 
+``MACOSX_FRAMEWORK_BUNDLE_NAME``
+  .. versionadded:: 3.31
+
+  Sets ``CFBundleName``.
+
 ``MACOSX_FRAMEWORK_BUNDLE_VERSION``
   Sets ``CFBundleVersion``.
+
 ``MACOSX_FRAMEWORK_ICON_FILE``
   Sets ``CFBundleIconFile``.
+
 ``MACOSX_FRAMEWORK_IDENTIFIER``
   Sets ``CFBundleIdentifier``.
+
 ``MACOSX_FRAMEWORK_SHORT_VERSION_STRING``
   Sets ``CFBundleShortVersionString``.
 
diff --git a/Help/release/3.30.rst b/Help/release/3.30.rst
index db66b0d..6d515fd 100644
--- a/Help/release/3.30.rst
+++ b/Help/release/3.30.rst
@@ -148,9 +148,9 @@
   associated :variable:`CMAKE_<LANG>_COMPILER_FRONTEND_VARIANT` variables.
 
 * Link features, as used with the :genex:`LINK_LIBRARY` generator expression,
-  gained the ability to have properties that describe their behavior by
-  specifying the :variable:`CMAKE_LINK_LIBRARY_<FEATURE>_PROPERTIES` or
-  :variable:`CMAKE_<LANG>_LINK_LIBRARY_<FEATURE>_PROPERTIES` variables.
+  gained the ability to have attributes that describe their behavior by
+  specifying the :variable:`CMAKE_LINK_LIBRARY_<FEATURE>_ATTRIBUTES` or
+  :variable:`CMAKE_<LANG>_LINK_LIBRARY_<FEATURE>_ATTRIBUTES` variables.
 
 * The :genex:`QUOTE` generator expression was added to evaluate to ``"``.
 
diff --git a/Help/release/dev/apple-framework-bundle-name.rst b/Help/release/dev/apple-framework-bundle-name.rst
new file mode 100644
index 0000000..541845b
--- /dev/null
+++ b/Help/release/dev/apple-framework-bundle-name.rst
@@ -0,0 +1,6 @@
+apple-framework-bundle-name
+---------------------------
+
+* The :prop_tgt:`MACOSX_FRAMEWORK_BUNDLE_NAME <MACOSX_FRAMEWORK_INFO_PLIST>`
+  target property was added to set the ``CFBundleName`` key in an Apple
+  :prop_tgt:`FRAMEWORK`'s ``Info.plist`` file.
diff --git a/Help/release/dev/cpack-debian-multiarch.rst b/Help/release/dev/cpack-debian-multiarch.rst
new file mode 100644
index 0000000..f593103
--- /dev/null
+++ b/Help/release/dev/cpack-debian-multiarch.rst
@@ -0,0 +1,6 @@
+cpack-debian-multiarch
+----------------------
+
+* The :cpack_gen:`CPack DEB Generator` gained a
+  :variable:`CPACK_DEBIAN_PACKAGE_MULTIARCH` option
+  to support multi-arch packages.
diff --git a/Help/variable/CMAKE_LANG_LINK_LIBRARY_FEATURE_PROPERTIES.rst b/Help/variable/CMAKE_LANG_LINK_LIBRARY_FEATURE_ATTRIBUTES.rst
similarity index 64%
rename from Help/variable/CMAKE_LANG_LINK_LIBRARY_FEATURE_PROPERTIES.rst
rename to Help/variable/CMAKE_LANG_LINK_LIBRARY_FEATURE_ATTRIBUTES.rst
index 10f4fda..8769d60 100644
--- a/Help/variable/CMAKE_LANG_LINK_LIBRARY_FEATURE_PROPERTIES.rst
+++ b/Help/variable/CMAKE_LANG_LINK_LIBRARY_FEATURE_ATTRIBUTES.rst
@@ -1,10 +1,10 @@
-CMAKE_<LANG>_LINK_LIBRARY_<FEATURE>_PROPERTIES
+CMAKE_<LANG>_LINK_LIBRARY_<FEATURE>_ATTRIBUTES
 ----------------------------------------------
 
 .. versionadded:: 3.30
 
 This variable defines the semantics of the specified link library ``<FEATURE>``
 when linking with the link language ``<LANG>``. It takes precedence over
-:variable:`CMAKE_LINK_LIBRARY_<FEATURE>_PROPERTIES` if that variable is also
+:variable:`CMAKE_LINK_LIBRARY_<FEATURE>_ATTRIBUTES` if that variable is also
 defined for the same ``<FEATURE>``, but otherwise has similar effects.
-See :variable:`CMAKE_LINK_LIBRARY_<FEATURE>_PROPERTIES` for further details.
+See :variable:`CMAKE_LINK_LIBRARY_<FEATURE>_ATTRIBUTES` for further details.
diff --git a/Help/variable/CMAKE_LINK_LIBRARY_FEATURE_PROPERTIES.rst b/Help/variable/CMAKE_LINK_LIBRARY_FEATURE_ATTRIBUTES.rst
similarity index 78%
rename from Help/variable/CMAKE_LINK_LIBRARY_FEATURE_PROPERTIES.rst
rename to Help/variable/CMAKE_LINK_LIBRARY_FEATURE_ATTRIBUTES.rst
index e30c30a..c9966ff 100644
--- a/Help/variable/CMAKE_LINK_LIBRARY_FEATURE_PROPERTIES.rst
+++ b/Help/variable/CMAKE_LINK_LIBRARY_FEATURE_ATTRIBUTES.rst
@@ -1,4 +1,4 @@
-CMAKE_LINK_LIBRARY_<FEATURE>_PROPERTIES
+CMAKE_LINK_LIBRARY_<FEATURE>_ATTRIBUTES
 ---------------------------------------
 
 .. versionadded:: 3.30
@@ -17,28 +17,29 @@
 control whether the ``<FEATURE>`` is available at all.
 
 When linking for a particular language ``<LANG>``,
-``CMAKE_LINK_LIBRARY_<FEATURE>_PROPERTIES`` is ignored if the
-:variable:`CMAKE_<LANG>_LINK_LIBRARY_<FEATURE>_PROPERTIES` variable is also
+``CMAKE_LINK_LIBRARY_<FEATURE>_ATTRIBUTES`` is ignored if the
+:variable:`CMAKE_<LANG>_LINK_LIBRARY_<FEATURE>_ATTRIBUTES` variable is also
 defined for the same ``<FEATURE>``.
 
-The value of ``CMAKE_LINK_LIBRARY_<FEATURE>_PROPERTIES`` and
-:variable:`CMAKE_<LANG>_LINK_LIBRARY_<FEATURE>_PROPERTIES` at the end of the
+The value of ``CMAKE_LINK_LIBRARY_<FEATURE>_ATTRIBUTES`` and
+:variable:`CMAKE_<LANG>_LINK_LIBRARY_<FEATURE>_ATTRIBUTES` at the end of the
 directory scope in which a target is defined is what matters.
 
-Feature Properties Definition
+Feature Attributes Definition
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-A feature properties definition is a
-:ref:`semicolon-separated list <CMake Language Lists>` of ``property=value(s)``
-items. If a property has multiple values, those values must be comma-separated.
+A feature attributes definition is a
+:ref:`semicolon-separated list <CMake Language Lists>` of
+``attribute=value(s)`` items. If an attribute has multiple values, those values
+must be comma-separated.
 
-The following properties are supported:
+The following attributes are supported:
 
 ``LIBRARY_TYPE=<library-type-list>``
   Specify the library types supported by the feature. Supported values are:
   ``STATIC``, ``SHARED``, ``MODULE``, and ``EXECUTABLE``.
 
-  If this property is not specified, the default is
+  If this attribute is not specified, the default is
   ``LIBRARY_TYPE=STATIC,SHARED,MODULE,EXECUTABLE``.
 
   If the feature is used with an unsupported library type, CMake will emit a
@@ -51,9 +52,9 @@
   :prop_tgt:`LINK_LIBRARY_OVERRIDE_<LIBRARY>` target property definitions,
   if defined.
 
-  If this property is not specified, the default is an empty list.
+  If this attribute is not specified, the default is an empty list.
 
-``UNICITY=YES|NO|DEFAULT``
+``DEDUPLICATION=YES|NO|DEFAULT``
   Specify the de-duplication strategy for a library using this feature.
 
   ``YES``
@@ -67,7 +68,7 @@
   ``DEFAULT``
     Let CMake determine a de-duplication strategy automatically.
 
-  If this property is not specified, ``DEFAULT`` will be used.
+  If this attribute is not specified, ``DEFAULT`` will be used.
 
 Example
 ^^^^^^^
@@ -75,14 +76,14 @@
 A common need is the loading of a full archive as part of the creation of a
 shared library. The built-in ``WHOLE_ARCHIVE`` feature can be used for that
 purpose. The implementation of that built-in feature sets the following
-link library feature properties:
+link library feature attributes:
 
 .. code-block:: cmake
 
-  set(CMAKE_LINK_LIBRARY_WHOLE_ARCHIVE_PROPERTIES
+  set(CMAKE_LINK_LIBRARY_WHOLE_ARCHIVE_ATTRIBUTES
     LIBRARY_TYPE=STATIC
     OVERRIDE=DEFAULT
-    UNICITY=YES
+    DEDUPLICATION=YES
   )
 
 ``LIBRARY_TYPE=STATIC``
@@ -92,7 +93,7 @@
   because they are compatible and enhance the user's experience: standard
   library specification and ``$<LINK_LIBRARY:WHOLE_ARCHIVE>`` can be used
   freely.
-``UNICITY=YES``
+``DEDUPLICATION=YES``
   When this feature is used, the linker loads all symbols from the static
   library, so there is no need to repeat the library on the linker
   command line.
diff --git a/Help/variable/CMAKE_LINK_LIBRARY_USING_FEATURE.txt b/Help/variable/CMAKE_LINK_LIBRARY_USING_FEATURE.txt
index 59a0d02..f5c19e0 100644
--- a/Help/variable/CMAKE_LINK_LIBRARY_USING_FEATURE.txt
+++ b/Help/variable/CMAKE_LINK_LIBRARY_USING_FEATURE.txt
@@ -3,8 +3,8 @@
 CMake's own built-in features (see `Predefined Features`_ further below).
 
 Some aspects of feature behavior can be defined by the
-:variable:`CMAKE_<LANG>_LINK_LIBRARY_<FEATURE>_PROPERTIES` and
-:variable:`CMAKE_LINK_LIBRARY_<FEATURE>_PROPERTIES` variables.
+:variable:`CMAKE_<LANG>_LINK_LIBRARY_<FEATURE>_ATTRIBUTES` and
+:variable:`CMAKE_LINK_LIBRARY_<FEATURE>_ATTRIBUTES` variables.
 
 Feature Definitions
 ^^^^^^^^^^^^^^^^^^^
diff --git a/Modules/Internal/CPack/CPackDeb.cmake b/Modules/Internal/CPack/CPackDeb.cmake
index d4a47e4..2b58ab1 100644
--- a/Modules/Internal/CPack/CPackDeb.cmake
+++ b/Modules/Internal/CPack/CPackDeb.cmake
@@ -567,7 +567,7 @@
   # if per-component variable, overrides the global CPACK_DEBIAN_PACKAGE_${variable_type_}
   # automatic dependency discovery will be performed afterwards.
   if(CPACK_DEB_PACKAGE_COMPONENT)
-    foreach(value_type_ IN ITEMS DEPENDS RECOMMENDS SUGGESTS PREDEPENDS ENHANCES BREAKS CONFLICTS PROVIDES REPLACES SOURCE SECTION PRIORITY NAME)
+    foreach(value_type_ IN ITEMS DEPENDS RECOMMENDS SUGGESTS PREDEPENDS ENHANCES BREAKS CONFLICTS PROVIDES REPLACES MULTIARCH SOURCE SECTION PRIORITY NAME)
       set(_component_var "CPACK_DEBIAN_${_local_component_name}_PACKAGE_${value_type_}")
 
       # if set, overrides the global variable
@@ -862,6 +862,7 @@
   set(GEN_CPACK_DEBIAN_PACKAGE_CONFLICTS "${CPACK_DEBIAN_PACKAGE_CONFLICTS}" PARENT_SCOPE)
   set(GEN_CPACK_DEBIAN_PACKAGE_PROVIDES "${CPACK_DEBIAN_PACKAGE_PROVIDES}" PARENT_SCOPE)
   set(GEN_CPACK_DEBIAN_PACKAGE_REPLACES "${CPACK_DEBIAN_PACKAGE_REPLACES}" PARENT_SCOPE)
+  set(GEN_CPACK_DEBIAN_PACKAGE_MULTIARCH "${CPACK_DEBIAN_PACKAGE_MULTIARCH}" PARENT_SCOPE)
   set(GEN_CPACK_DEBIAN_PACKAGE_SHLIBS "${CPACK_DEBIAN_PACKAGE_SHLIBS_LIST}" PARENT_SCOPE)
   set(GEN_CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA}" PARENT_SCOPE)
   set(GEN_CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION
diff --git a/Modules/MacOSXFrameworkInfo.plist.in b/Modules/MacOSXFrameworkInfo.plist.in
index 18eaef2..f053fda 100644
--- a/Modules/MacOSXFrameworkInfo.plist.in
+++ b/Modules/MacOSXFrameworkInfo.plist.in
@@ -12,6 +12,8 @@
 	<string>${MACOSX_FRAMEWORK_IDENTIFIER}</string>
 	<key>CFBundleInfoDictionaryVersion</key>
 	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>${MACOSX_FRAMEWORK_BUNDLE_NAME}</string>
 	<key>CFBundlePackageType</key>
 	<string>FMWK</string>
 	<key>CFBundleSignature</key>
diff --git a/Modules/Platform/AIX-GNU.cmake b/Modules/Platform/AIX-GNU.cmake
index 55a6680..f6616fb 100644
--- a/Modules/Platform/AIX-GNU.cmake
+++ b/Modules/Platform/AIX-GNU.cmake
@@ -17,7 +17,7 @@
   set(CMAKE_${lang}_VERBOSE_LINK_FLAG "-Wl,-v")
 
   set(CMAKE_${lang}_LINK_FLAGS "-Wl,-bnoipath")
-  set(CMAKE_${lang}_LINK_LIBRARIES_PROCESSING ORDER=REVERSE UNICITY=ALL)
+  set(CMAKE_${lang}_LINK_LIBRARIES_PROCESSING ORDER=REVERSE DEDUPLICATION=ALL)
 
   if(CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 7 OR CMAKE_SYSTEM_VERSION VERSION_LESS 7.1)
     unset(CMAKE_${lang}_COMPILE_OPTIONS_VISIBILITY)
diff --git a/Modules/Platform/AIX-XL.cmake b/Modules/Platform/AIX-XL.cmake
index c225de9..cd202cb 100644
--- a/Modules/Platform/AIX-XL.cmake
+++ b/Modules/Platform/AIX-XL.cmake
@@ -17,7 +17,7 @@
   set(CMAKE_SHARED_MODULE_${lang}_FLAGS  " ")
 
   set(CMAKE_${lang}_LINK_FLAGS "-Wl,-bnoipath")
-  set(CMAKE_${lang}_LINK_LIBRARIES_PROCESSING ORDER=REVERSE UNICITY=ALL)
+  set(CMAKE_${lang}_LINK_LIBRARIES_PROCESSING ORDER=REVERSE DEDUPLICATION=ALL)
 
   set(_OBJECTS " <OBJECTS>")
   if(DEFINED CMAKE_XL_CreateExportList AND CMAKE_XL_CreateExportList STREQUAL "")
diff --git a/Modules/Platform/Apple-Clang.cmake b/Modules/Platform/Apple-Clang.cmake
index 31f4293..40fed44 100644
--- a/Modules/Platform/Apple-Clang.cmake
+++ b/Modules/Platform/Apple-Clang.cmake
@@ -15,11 +15,11 @@
     set(CMAKE_${lang}_SYSTEM_FRAMEWORK_SEARCH_FLAG "-iframework ")
   endif()
 
-  set(CMAKE_${lang}_LINK_LIBRARIES_PROCESSING ORDER=REVERSE UNICITY=ALL)
+  set(CMAKE_${lang}_LINK_LIBRARIES_PROCESSING ORDER=REVERSE DEDUPLICATION=ALL)
 
   set(CMAKE_${lang}_LINK_LIBRARY_USING_FRAMEWORK "-framework <LIBRARY>")
   set(CMAKE_${lang}_LINK_LIBRARY_USING_FRAMEWORK_SUPPORTED TRUE)
-  set(CMAKE_${lang}_LINK_LIBRARY_FRAMEWORK_PROPERTIES LIBRARY_TYPE=STATIC,SHARED UNICITY=DEFAULT OVERRIDE=DEFAULT)
+  set(CMAKE_${lang}_LINK_LIBRARY_FRAMEWORK_ATTRIBUTES LIBRARY_TYPE=STATIC,SHARED DEDUPLICATION=DEFAULT OVERRIDE=DEFAULT)
 
   # linker selection
   set(CMAKE_${lang}_USING_LINKER_SYSTEM "-fuse-ld=ld")
diff --git a/Modules/Platform/Apple-GNU.cmake b/Modules/Platform/Apple-GNU.cmake
index 20b18ad..bc4147e 100644
--- a/Modules/Platform/Apple-GNU.cmake
+++ b/Modules/Platform/Apple-GNU.cmake
@@ -17,7 +17,7 @@
 
   set(CMAKE_${lang}_LINK_LIBRARY_USING_FRAMEWORK "-framework <LIBRARY>")
   set(CMAKE_${lang}_LINK_LIBRARY_USING_FRAMEWORK_SUPPORTED TRUE)
-  set(CMAKE_LINK_LIBRARY_FRAMEWORK_PROPERTIES LIBRARY_TYPE=STATIC,SHARED UNICITY=DEFAULT OVERRIDE=DEFAULT)
+  set(CMAKE_LINK_LIBRARY_FRAMEWORK_ATTRIBUTES LIBRARY_TYPE=STATIC,SHARED DEDUPLICATION=DEFAULT OVERRIDE=DEFAULT)
 
   set(CMAKE_${lang}_USING_LINKER_SYSTEM "")
   set(CMAKE_${lang}_USING_LINKER_APPLE_CLASSIC "LINKER:-ld_classic")
diff --git a/Modules/Platform/CYGWIN-GNU.cmake b/Modules/Platform/CYGWIN-GNU.cmake
index 5e2ba41..01b5f91 100644
--- a/Modules/Platform/CYGWIN-GNU.cmake
+++ b/Modules/Platform/CYGWIN-GNU.cmake
@@ -40,7 +40,7 @@
                                              "LINKER:--no-whole-archive")
 endif()
 set(CMAKE_LINK_LIBRARY_USING_WHOLE_ARCHIVE_SUPPORTED TRUE)
-set(CMAKE_LINK_LIBRARY_WHOLE_ARCHIVE_PROPERTIES LIBRARY_TYPE=STATIC UNICITY=YES OVERRIDE=DEFAULT)
+set(CMAKE_LINK_LIBRARY_WHOLE_ARCHIVE_ATTRIBUTES LIBRARY_TYPE=STATIC DEDUPLICATION=YES OVERRIDE=DEFAULT)
 
 
 macro(__cygwin_compiler_gnu lang)
diff --git a/Modules/Platform/Darwin.cmake b/Modules/Platform/Darwin.cmake
index 1272baf..b26912d 100644
--- a/Modules/Platform/Darwin.cmake
+++ b/Modules/Platform/Darwin.cmake
@@ -114,37 +114,37 @@
 # Defines LINK_LIBRARY features for frameworks
 set(CMAKE_LINK_LIBRARY_USING_FRAMEWORK "LINKER:-framework,<LIBRARY>")
 set(CMAKE_LINK_LIBRARY_USING_FRAMEWORK_SUPPORTED TRUE)
-set(CMAKE_LINK_LIBRARY_FRAMEWORK_PROPERTIES LIBRARY_TYPE=STATIC,SHARED UNICITY=DEFAULT OVERRIDE=DEFAULT)
+set(CMAKE_LINK_LIBRARY_FRAMEWORK_ATTRIBUTES LIBRARY_TYPE=STATIC,SHARED DEDUPLICATION=DEFAULT OVERRIDE=DEFAULT)
 
 set(CMAKE_LINK_LIBRARY_USING_NEEDED_FRAMEWORK "LINKER:-needed_framework,<LIBRARY>")
 set(CMAKE_LINK_LIBRARY_USING_NEEDED_FRAMEWORK_SUPPORTED TRUE)
-set(CMAKE_LINK_LIBRARY_NEEDED_FRAMEWORK_PROPERTIES LIBRARY_TYPE=STATIC,SHARED UNICITY=DEFAULT OVERRIDE=DEFAULT)
+set(CMAKE_LINK_LIBRARY_NEEDED_FRAMEWORK_ATTRIBUTES LIBRARY_TYPE=STATIC,SHARED DEDUPLICATION=DEFAULT OVERRIDE=DEFAULT)
 
 set(CMAKE_LINK_LIBRARY_USING_REEXPORT_FRAMEWORK "LINKER:-reexport_framework,<LIBRARY>")
 set(CMAKE_LINK_LIBRARY_USING_REEXPORT_FRAMEWORK_SUPPORTED TRUE)
-set(CMAKE_LINK_LIBRARY_REEXPORT_FRAMEWORK_PROPERTIES LIBRARY_TYPE=STATIC,SHARED UNICITY=DEFAULT OVERRIDE=DEFAULT)
+set(CMAKE_LINK_LIBRARY_REEXPORT_FRAMEWORK_ATTRIBUTES LIBRARY_TYPE=STATIC,SHARED DEDUPLICATION=DEFAULT OVERRIDE=DEFAULT)
 
 set(CMAKE_LINK_LIBRARY_USING_WEAK_FRAMEWORK "LINKER:-weak_framework,<LIBRARY>")
 set(CMAKE_LINK_LIBRARY_USING_WEAK_FRAMEWORK_SUPPORTED TRUE)
-set(CMAKE_LINK_LIBRARY_WEAK_FRAMEWORK_PROPERTIES LIBRARY_TYPE=STATIC,SHARED UNICITY=DEFAULT OVERRIDE=DEFAULT)
+set(CMAKE_LINK_LIBRARY_WEAK_FRAMEWORK_ATTRIBUTES LIBRARY_TYPE=STATIC,SHARED DEDUPLICATION=DEFAULT OVERRIDE=DEFAULT)
 
 # Defines LINK_LIBRARY features for libraries
 set(CMAKE_LINK_LIBRARY_USING_NEEDED_LIBRARY "PATH{LINKER:-needed_library,<LIBRARY>}NAME{LINKER:-needed-l<LIBRARY>}")
 set(CMAKE_LINK_LIBRARY_USING_NEEDED_LIBRARY_SUPPORTED TRUE)
-set(CMAKE_LINK_LIBRARY_NEEDED_LIBRARY_PROPERTIES LIBRARY_TYPE=SHARED UNICITY=DEFAULT OVERRIDE=DEFAULT)
+set(CMAKE_LINK_LIBRARY_NEEDED_LIBRARY_ATTRIBUTES LIBRARY_TYPE=SHARED DEDUPLICATION=DEFAULT OVERRIDE=DEFAULT)
 
 set(CMAKE_LINK_LIBRARY_USING_REEXPORT_LIBRARY "PATH{LINKER:-reexport_library,<LIBRARY>}NAME{LINKER:-reexport-l<LIBRARY>}")
 set(CMAKE_LINK_LIBRARY_USING_REEXPORT_LIBRARY_SUPPORTED TRUE)
-set(CMAKE_LINK_LIBRARY_REEXPORT_LIBRARY_PROPERTIES LIBRARY_TYPE=STATIC,SHARED UNICITY=DEFAULT OVERRIDE=DEFAULT)
+set(CMAKE_LINK_LIBRARY_REEXPORT_LIBRARY_ATTRIBUTES LIBRARY_TYPE=STATIC,SHARED DEDUPLICATION=DEFAULT OVERRIDE=DEFAULT)
 
 set(CMAKE_LINK_LIBRARY_USING_WEAK_LIBRARY "PATH{LINKER:-weak_library,<LIBRARY>}NAME{LINKER:-weak-l<LIBRARY>}")
 set(CMAKE_LINK_LIBRARY_USING_WEAK_LIBRARY_SUPPORTED TRUE)
-set(CMAKE_LINK_LIBRARY_WEAK_LIBRARY_PROPERTIES LIBRARY_TYPE=STATIC,SHARED UNICITY=DEFAULT OVERRIDE=DEFAULT)
+set(CMAKE_LINK_LIBRARY_WEAK_LIBRARY_ATTRIBUTES LIBRARY_TYPE=STATIC,SHARED DEDUPLICATION=DEFAULT OVERRIDE=DEFAULT)
 
 # Defines LINK_LIBRARY feature to Force loading of all members of an archive
 set(CMAKE_LINK_LIBRARY_USING_WHOLE_ARCHIVE "LINKER:-force_load,<LIB_ITEM>")
 set(CMAKE_LINK_LIBRARY_USING_WHOLE_ARCHIVE_SUPPORTED TRUE)
-set(CMAKE_LINK_LIBRARY_WHOLE_ARCHIVE_PROPERTIES LIBRARY_TYPE=STATIC UNICITY=YES OVERRIDE=DEFAULT)
+set(CMAKE_LINK_LIBRARY_WHOLE_ARCHIVE_ATTRIBUTES LIBRARY_TYPE=STATIC DEDUPLICATION=YES OVERRIDE=DEFAULT)
 
 # default to searching for frameworks first
 if(NOT DEFINED CMAKE_FIND_FRAMEWORK)
diff --git a/Modules/Platform/FreeBSD.cmake b/Modules/Platform/FreeBSD.cmake
index 7d5f951..891422e 100644
--- a/Modules/Platform/FreeBSD.cmake
+++ b/Modules/Platform/FreeBSD.cmake
@@ -51,7 +51,7 @@
                                              "LINKER:--no-whole-archive")
 endif()
 set(CMAKE_LINK_LIBRARY_USING_WHOLE_ARCHIVE_SUPPORTED TRUE)
-set(CMAKE_LINK_LIBRARY_WHOLE_ARCHIVE_PROPERTIES LIBRARY_TYPE=STATIC UNICITY=YES OVERRIDE=DEFAULT)
+set(CMAKE_LINK_LIBRARY_WHOLE_ARCHIVE_ATTRIBUTES LIBRARY_TYPE=STATIC DEDUPLICATION=YES OVERRIDE=DEFAULT)
 
 
 # Features for LINK_GROUP generator expression
diff --git a/Modules/Platform/Linux.cmake b/Modules/Platform/Linux.cmake
index fba6ab8..a73bbf7 100644
--- a/Modules/Platform/Linux.cmake
+++ b/Modules/Platform/Linux.cmake
@@ -44,7 +44,7 @@
                                              "LINKER:--no-whole-archive")
 endif()
 set(CMAKE_LINK_LIBRARY_USING_WHOLE_ARCHIVE_SUPPORTED TRUE)
-set(CMAKE_LINK_LIBRARY_WHOLE_ARCHIVE_PROPERTIES LIBRARY_TYPE=STATIC UNICITY=YES OVERRIDE=DEFAULT)
+set(CMAKE_LINK_LIBRARY_WHOLE_ARCHIVE_ATTRIBUTES LIBRARY_TYPE=STATIC DEDUPLICATION=YES OVERRIDE=DEFAULT)
 
 # Features for LINK_GROUP generator expression
 ## RESCAN: request the linker to rescan static libraries until there is
@@ -84,7 +84,7 @@
 
 # Debian has lib32 and lib64 paths only for compatibility so they should not be
 # searched.
-if(NOT CMAKE_CROSSCOMPILING)
+if(NOT CMAKE_CROSSCOMPILING AND NOT CMAKE_COMPILER_SYSROOT)
   if (EXISTS "/etc/debian_version")
     set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_LIB32_PATHS FALSE)
     set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS FALSE)
diff --git a/Modules/Platform/NetBSD.cmake b/Modules/Platform/NetBSD.cmake
index af368cd..892d55b 100644
--- a/Modules/Platform/NetBSD.cmake
+++ b/Modules/Platform/NetBSD.cmake
@@ -37,7 +37,7 @@
                                              "LINKER:--no-whole-archive")
 endif()
 set(CMAKE_LINK_LIBRARY_USING_WHOLE_ARCHIVE_SUPPORTED TRUE)
-set(CMAKE_LINK_LIBRARY_WHOLE_ARCHIVE_PROPERTIES LIBRARY_TYPE=STATIC UNICITY=YES OVERRIDE=DEFAULT)
+set(CMAKE_LINK_LIBRARY_WHOLE_ARCHIVE_ATTRIBUTES LIBRARY_TYPE=STATIC DEDUPLICATION=YES OVERRIDE=DEFAULT)
 
 
 # Features for LINK_GROUP generator expression
diff --git a/Modules/Platform/SunOS.cmake b/Modules/Platform/SunOS.cmake
index 73205c1..25e95e6 100644
--- a/Modules/Platform/SunOS.cmake
+++ b/Modules/Platform/SunOS.cmake
@@ -20,7 +20,7 @@
                                              "LINKER:-z,defaultextract")
 endif()
 set(CMAKE_LINK_LIBRARY_USING_WHOLE_ARCHIVE_SUPPORTED TRUE)
-set(CMAKE_LINK_LIBRARY_WHOLE_ARCHIVE_PROPERTIES LIBRARY_TYPE=STATIC UNICITY=YES OVERRIDE=DEFAULT)
+set(CMAKE_LINK_LIBRARY_WHOLE_ARCHIVE_ATTRIBUTES LIBRARY_TYPE=STATIC DEDUPLICATION=YES OVERRIDE=DEFAULT)
 
 
 # Features for LINK_GROUP generator expression
diff --git a/Modules/Platform/Windows-Clang.cmake b/Modules/Platform/Windows-Clang.cmake
index 35055bc..e3725cb 100644
--- a/Modules/Platform/Windows-Clang.cmake
+++ b/Modules/Platform/Windows-Clang.cmake
@@ -55,7 +55,7 @@
   set(CMAKE_SHARED_LIBRARY_${lang}_FLAGS "")
   set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "-shared")
 
-  set(CMAKE_${lang}_LINK_LIBRARIES_PROCESSING ORDER=FORWARD UNICITY=ALL)
+  set(CMAKE_${lang}_LINK_LIBRARIES_PROCESSING ORDER=FORWARD DEDUPLICATION=ALL)
 
   # linker selection
   set(CMAKE_${lang}_USING_LINKER_DEFAULT "-fuse-ld=lld-link")
@@ -140,7 +140,7 @@
     ## WHOLE_ARCHIVE: Force loading all members of an archive
     set(CMAKE_${lang}_LINK_LIBRARY_USING_WHOLE_ARCHIVE "LINKER:/WHOLEARCHIVE:<LIBRARY>")
     set(CMAKE_${lang}_LINK_LIBRARY_USING_WHOLE_ARCHIVE_SUPPORTED TRUE)
-    set(CMAKE_${lang}_LINK_LIBRARY_WHOLE_ARCHIVE_PROPERTIES LIBRARY_TYPE=STATIC UNICITY=YES OVERRIDE=DEFAULT)
+    set(CMAKE_${lang}_LINK_LIBRARY_WHOLE_ARCHIVE_ATTRIBUTES LIBRARY_TYPE=STATIC DEDUPLICATION=YES OVERRIDE=DEFAULT)
   endif()
 
   enable_language(RC)
diff --git a/Modules/Platform/Windows-GNU.cmake b/Modules/Platform/Windows-GNU.cmake
index d2b25c6..1a4159b 100644
--- a/Modules/Platform/Windows-GNU.cmake
+++ b/Modules/Platform/Windows-GNU.cmake
@@ -88,7 +88,7 @@
                                              "LINKER:--no-whole-archive")
 endif()
 set(CMAKE_LINK_LIBRARY_USING_WHOLE_ARCHIVE_SUPPORTED TRUE)
-set(CMAKE_LINK_LIBRARY_WHOLE_ARCHIVE_PROPERTIES LIBRARY_TYPE=STATIC UNICITY=YES OVERRIDE=DEFAULT)
+set(CMAKE_LINK_LIBRARY_WHOLE_ARCHIVE_ATTRIBUTES LIBRARY_TYPE=STATIC DEDUPLICATION=YES OVERRIDE=DEFAULT)
 
 # Features for LINK_GROUP generator expression
 ## RESCAN: request the linker to rescan static libraries until there is
diff --git a/Modules/Platform/Windows-IntelLLVM.cmake b/Modules/Platform/Windows-IntelLLVM.cmake
index 691c7ce..517d959 100644
--- a/Modules/Platform/Windows-IntelLLVM.cmake
+++ b/Modules/Platform/Windows-IntelLLVM.cmake
@@ -37,7 +37,7 @@
     ## WHOLE_ARCHIVE: Force loading all members of an archive
     set(CMAKE_LINK_LIBRARY_USING_WHOLE_ARCHIVE "LINKER:/WHOLEARCHIVE:<LIBRARY>")
     set(CMAKE_LINK_LIBRARY_USING_WHOLE_ARCHIVE_SUPPORTED TRUE)
-    set(CMAKE_LINK_LIBRARY_WHOLE_ARCHIVE_PROPERTIES LIBRARY_TYPE=STATIC UNICITY=YES OVERRIDE=DEFAULT)
+    set(CMAKE_LINK_LIBRARY_WHOLE_ARCHIVE_ATTRIBUTES LIBRARY_TYPE=STATIC DEDUPLICATION=YES OVERRIDE=DEFAULT)
   endif()
 
   set(CMAKE_${lang}_LINK_EXECUTABLE
diff --git a/Modules/Platform/Windows-MSVC.cmake b/Modules/Platform/Windows-MSVC.cmake
index c737b88..5809379 100644
--- a/Modules/Platform/Windows-MSVC.cmake
+++ b/Modules/Platform/Windows-MSVC.cmake
@@ -358,7 +358,7 @@
   ## WHOLE_ARCHIVE: Force loading all members of an archive
   set(CMAKE_LINK_LIBRARY_USING_WHOLE_ARCHIVE "/WHOLEARCHIVE:<LIBRARY>")
   set(CMAKE_LINK_LIBRARY_USING_WHOLE_ARCHIVE_SUPPORTED TRUE)
-  set(CMAKE_LINK_LIBRARY_WHOLE_ARCHIVE_PROPERTIES LIBRARY_TYPE=STATIC UNICITY=YES OVERRIDE=DEFAULT)
+  set(CMAKE_LINK_LIBRARY_WHOLE_ARCHIVE_ATTRIBUTES LIBRARY_TYPE=STATIC DEDUPLICATION=YES OVERRIDE=DEFAULT)
 endif()
 
 
@@ -514,7 +514,7 @@
     set(CMAKE_${lang}_DEPFILE_FORMAT msvc)
   endif()
 
-  set(CMAKE_${lang}_LINK_LIBRARIES_PROCESSING ORDER=FORWARD UNICITY=ALL)
+  set(CMAKE_${lang}_LINK_LIBRARIES_PROCESSING ORDER=FORWARD DEDUPLICATION=ALL)
 
   # linker selection
   set(CMAKE_${lang}_USING_LINKER_SYSTEM "${CMAKE_LINKER_LINK}")
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 034564c..f3000c7 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 30)
-set(CMake_VERSION_PATCH 20240622)
+set(CMake_VERSION_PATCH 20240626)
 #set(CMake_VERSION_RC 0)
 set(CMake_VERSION_IS_DIRTY 0)
 
diff --git a/Source/CPack/cmCPackDebGenerator.cxx b/Source/CPack/cmCPackDebGenerator.cxx
index 31191a9..d721cf1 100644
--- a/Source/CPack/cmCPackDebGenerator.cxx
+++ b/Source/CPack/cmCPackDebGenerator.cxx
@@ -789,6 +789,21 @@
   if (cmNonempty(debian_pkg_replaces)) {
     controlValues["Replaces"] = *debian_pkg_replaces;
   }
+  cmValue debian_pkg_multiarch =
+    this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_MULTIARCH");
+  if (cmNonempty(debian_pkg_multiarch)) {
+    // check for valid values: same, foreign, allowed
+    if (*debian_pkg_multiarch != "same" &&
+        *debian_pkg_multiarch != "foreign" &&
+        *debian_pkg_multiarch != "allowed") {
+      cmCPackLogger(cmCPackLog::LOG_ERROR,
+                    "Error: invalid value for Multi-Arch: "
+                      << *debian_pkg_multiarch
+                      << ". Valid values are: same, foreign, allowed\n");
+      return false;
+    }
+    controlValues["Multi-Arch"] = *debian_pkg_multiarch;
+  }
 
   const std::string strGenWDIR(this->GetOption("GEN_WDIR"));
   const std::string shlibsfilename = strGenWDIR + "/shlibs";
diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx
index cc323f4..1937674 100644
--- a/Source/cmComputeLinkDepends.cxx
+++ b/Source/cmComputeLinkDepends.cxx
@@ -202,8 +202,8 @@
   return makefile->GetDefinition(featureSupported).IsOn();
 }
 
-// LINK_LIBRARY feature properties management
-struct LinkLibraryFeaturePropertySet
+// LINK_LIBRARY feature attributes management
+struct LinkLibraryFeatureAttributeSet
 {
   std::set<cmStateEnums::TargetType> LibraryTypes = {
     cmStateEnums::EXECUTABLE, cmStateEnums::STATIC_LIBRARY,
@@ -212,84 +212,88 @@
   };
   std::set<std::string> Override;
 
-  enum UnicityKind
+  enum DeduplicationKind
   {
     Default,
     Yes,
     No
   };
-  UnicityKind Unicity = Default;
+  DeduplicationKind Deduplication = Default;
 };
-std::map<std::string, LinkLibraryFeaturePropertySet>
-  LinkLibraryFeatureProperties;
-const LinkLibraryFeaturePropertySet& GetLinkLibraryFeatureProperties(
+std::map<std::string, LinkLibraryFeatureAttributeSet>
+  LinkLibraryFeatureAttributes;
+const LinkLibraryFeatureAttributeSet& GetLinkLibraryFeatureAttributes(
   cmMakefile* makefile, std::string const& linkLanguage,
   const std::string& feature)
 {
-  auto it = LinkLibraryFeatureProperties.find(feature);
-  if (it != LinkLibraryFeatureProperties.end()) {
+  auto it = LinkLibraryFeatureAttributes.find(feature);
+  if (it != LinkLibraryFeatureAttributes.end()) {
     return it->second;
   }
 
-  auto featurePropertiesVariable =
-    cmStrCat("CMAKE_", linkLanguage, "_LINK_LIBRARY_", feature, "_PROPERTIES");
-  auto featurePropertiesValues =
-    makefile->GetDefinition(featurePropertiesVariable);
-  if (featurePropertiesValues.IsEmpty()) {
+  auto featureAttributesVariable =
+    cmStrCat("CMAKE_", linkLanguage, "_LINK_LIBRARY_", feature, "_ATTRIBUTES");
+  auto featureAttributesValues =
+    makefile->GetDefinition(featureAttributesVariable);
+  if (featureAttributesValues.IsEmpty()) {
     // try language agnostic definition
-    featurePropertiesVariable =
-      cmStrCat("CMAKE_LINK_LIBRARY_", feature, "_PROPERTIES");
-    featurePropertiesValues =
-      makefile->GetDefinition(featurePropertiesVariable);
+    featureAttributesVariable =
+      cmStrCat("CMAKE_LINK_LIBRARY_", feature, "_ATTRIBUTES");
+    featureAttributesValues =
+      makefile->GetDefinition(featureAttributesVariable);
   }
-  if (!featurePropertiesValues.IsEmpty()) {
-    LinkLibraryFeaturePropertySet featureProperties;
+  if (!featureAttributesValues.IsEmpty()) {
+    LinkLibraryFeatureAttributeSet featureAttributes;
     cmsys::RegularExpression processingOption{
-      "^(LIBRARY_TYPE|UNICITY|OVERRIDE)=((STATIC|SHARED|MODULE|EXECUTABLE)(,("
+      "^(LIBRARY_TYPE|DEDUPLICATION|OVERRIDE)=((STATIC|SHARED|MODULE|"
+      "EXECUTABLE)(,("
       "STATIC|"
       "SHARED|MODULE|EXECUTABLE)"
       ")*|YES|NO|DEFAULT|[A-Za-z0-9_]+(,[A-Za-z0-9_]+)*)$"
     };
     std::string errorMessage;
-    for (auto const& option : cmList{ featurePropertiesValues }) {
+    for (auto const& option : cmList{ featureAttributesValues }) {
       if (processingOption.find(option)) {
         if (processingOption.match(1) == "LIBRARY_TYPE") {
-          featureProperties.LibraryTypes.clear();
+          featureAttributes.LibraryTypes.clear();
           for (auto const& value :
                cmTokenize(processingOption.match(2), ","_s)) {
             if (value == "STATIC") {
-              featureProperties.LibraryTypes.emplace(
+              featureAttributes.LibraryTypes.emplace(
                 cmStateEnums::STATIC_LIBRARY);
             } else if (value == "SHARED") {
-              featureProperties.LibraryTypes.emplace(
+              featureAttributes.LibraryTypes.emplace(
                 cmStateEnums::SHARED_LIBRARY);
             } else if (value == "MODULE") {
-              featureProperties.LibraryTypes.emplace(
+              featureAttributes.LibraryTypes.emplace(
                 cmStateEnums::MODULE_LIBRARY);
             } else if (value == "EXECUTABLE") {
-              featureProperties.LibraryTypes.emplace(cmStateEnums::EXECUTABLE);
+              featureAttributes.LibraryTypes.emplace(cmStateEnums::EXECUTABLE);
             } else {
               errorMessage += cmStrCat("  ", option, '\n');
               break;
             }
           }
           // Always add UNKNOWN type
-          featureProperties.LibraryTypes.emplace(
+          featureAttributes.LibraryTypes.emplace(
             cmStateEnums::UNKNOWN_LIBRARY);
-        } else if (processingOption.match(1) == "UNICITY") {
+        } else if (processingOption.match(1) == "DEDUPLICATION") {
           if (processingOption.match(2) == "YES") {
-            featureProperties.Unicity = LinkLibraryFeaturePropertySet::Yes;
+            featureAttributes.Deduplication =
+              LinkLibraryFeatureAttributeSet::Yes;
           } else if (processingOption.match(2) == "NO") {
-            featureProperties.Unicity = LinkLibraryFeaturePropertySet::No;
+            featureAttributes.Deduplication =
+              LinkLibraryFeatureAttributeSet::No;
           } else if (processingOption.match(2) == "DEFAULT") {
-            featureProperties.Unicity = LinkLibraryFeaturePropertySet::Default;
+            featureAttributes.Deduplication =
+              LinkLibraryFeatureAttributeSet::Default;
           } else {
             errorMessage += cmStrCat("  ", option, '\n');
           }
         } else if (processingOption.match(1) == "OVERRIDE") {
-          featureProperties.Override.clear();
+          featureAttributes.Override.clear();
           auto values = cmTokenize(processingOption.match(2), ","_s);
-          featureProperties.Override.insert(values.begin(), values.end());
+          featureAttributes.Override.insert(values.begin(), values.end());
         }
       } else {
         errorMessage += cmStrCat("  ", option, '\n');
@@ -298,14 +302,14 @@
     if (!errorMessage.empty()) {
       makefile->GetCMakeInstance()->IssueMessage(
         MessageType::FATAL_ERROR,
-        cmStrCat("Erroneous option(s) for '", featurePropertiesVariable,
+        cmStrCat("Erroneous option(s) for '", featureAttributesVariable,
                  "':\n", errorMessage));
     }
-    return LinkLibraryFeatureProperties.emplace(feature, featureProperties)
+    return LinkLibraryFeatureAttributes.emplace(feature, featureAttributes)
       .first->second;
   }
-  return LinkLibraryFeatureProperties
-    .emplace(feature, LinkLibraryFeaturePropertySet{})
+  return LinkLibraryFeatureAttributes
+    .emplace(feature, LinkLibraryFeatureAttributeSet{})
     .first->second;
 }
 
@@ -376,8 +380,10 @@
       case cmPolicies::NEW: {
         if (auto libProcessing = makefile->GetDefinition(cmStrCat(
               "CMAKE_", linkLanguage, "_LINK_LIBRARIES_PROCESSING"))) {
+          // UNICITY keyword is just for compatibility with previous
+          // implementation
           cmsys::RegularExpression processingOption{
-            "^(ORDER|UNICITY)=(FORWARD|REVERSE|ALL|NONE|SHARED)$"
+            "^(ORDER|UNICITY|DEDUPLICATION)=(FORWARD|REVERSE|ALL|NONE|SHARED)$"
           };
           std::string errorMessage;
           for (auto const& option : cmList{ libProcessing }) {
@@ -390,13 +396,14 @@
                 } else {
                   errorMessage += cmStrCat("  ", option, '\n');
                 }
-              } else if (processingOption.match(1) == "UNICITY") {
+              } else if (processingOption.match(1) == "UNICITY" ||
+                         processingOption.match(1) == "DEDUPLICATION") {
                 if (processingOption.match(2) == "ALL") {
-                  this->Unicity = All;
+                  this->Deduplication = All;
                 } else if (processingOption.match(2) == "NONE") {
-                  this->Unicity = None;
+                  this->Deduplication = None;
                 } else if (processingOption.match(2) == "SHARED") {
-                  this->Unicity = Shared;
+                  this->Deduplication = Shared;
                 } else {
                   errorMessage += cmStrCat("  ", option, '\n');
                 }
@@ -499,7 +506,7 @@
     Reverse
   };
 
-  enum UnicityKind
+  enum DeduplicationKind
   {
     None,
     Shared,
@@ -509,22 +516,23 @@
   bool IncludeEntry(LinkEntry const& entry) const
   {
     if (entry.Feature != cmComputeLinkDepends::LinkEntry::DEFAULT) {
-      auto const& featureProperties = GetLinkLibraryFeatureProperties(
+      auto const& featureAttributes = GetLinkLibraryFeatureAttributes(
         this->Target->Makefile, this->LinkLanguage, entry.Feature);
       if ((entry.Target == nullptr ||
-           featureProperties.LibraryTypes.find(entry.Target->GetType()) !=
-             featureProperties.LibraryTypes.end()) &&
-          featureProperties.Unicity !=
-            LinkLibraryFeaturePropertySet::Default) {
-        return featureProperties.Unicity == LinkLibraryFeaturePropertySet::No;
+           featureAttributes.LibraryTypes.find(entry.Target->GetType()) !=
+             featureAttributes.LibraryTypes.end()) &&
+          featureAttributes.Deduplication !=
+            LinkLibraryFeatureAttributeSet::Default) {
+        return featureAttributes.Deduplication ==
+          LinkLibraryFeatureAttributeSet::No;
       }
     }
 
-    return this->Unicity == None ||
-      (this->Unicity == Shared &&
+    return this->Deduplication == None ||
+      (this->Deduplication == Shared &&
        (entry.Target == nullptr ||
         entry.Target->GetType() != cmStateEnums::SHARED_LIBRARY)) ||
-      (this->Unicity == All && entry.Kind != LinkEntry::Library);
+      (this->Deduplication == All && entry.Kind != LinkEntry::Library);
   }
 
   template <typename Range>
@@ -539,7 +547,7 @@
   }
 
   OrderKind Order = Reverse;
-  UnicityKind Unicity = Shared;
+  DeduplicationKind Deduplication = Shared;
   const cmGeneratorTarget* Target;
   const std::string& LinkLanguage;
   EntryVector& Entries;
@@ -1121,27 +1129,29 @@
           " library '", entry.Item.Value, "'."),
         this->Target->GetBacktrace());
     }
+    // check if feature is applicable to this item
+    if (itemFeature != LinkEntry::DEFAULT && entry.Target != nullptr) {
+      auto const& featureAttributes = GetLinkLibraryFeatureAttributes(
+        this->Makefile, this->LinkLanguage, itemFeature);
+      if (featureAttributes.LibraryTypes.find(entry.Target->GetType()) ==
+          featureAttributes.LibraryTypes.end()) {
+        supportedItem = false;
+        this->CMakeInstance->IssueMessage(
+          MessageType::AUTHOR_WARNING,
+          cmStrCat("The feature '", itemFeature,
+                   "', specified as part of a generator-expression "
+                   "'$<LINK_LIBRARY:",
+                   itemFeature, ">', will not be applied to the ",
+                   cmState::GetTargetTypeName(entry.Target->GetType()), " '",
+                   entry.Item.Value, "'."),
+          this->Target->GetBacktrace());
+      }
+    }
     if (ale.second) {
       // current item not yet defined
       entry.Feature = itemFeature;
-
-      if (itemFeature != LinkEntry::DEFAULT && entry.Target != nullptr) {
-        auto const& featureProperties = GetLinkLibraryFeatureProperties(
-          this->Makefile, this->LinkLanguage, itemFeature);
-        if (featureProperties.LibraryTypes.find(entry.Target->GetType()) ==
-            featureProperties.LibraryTypes.end()) {
-          supportedItem = false;
-          entry.Feature = LinkEntry::DEFAULT;
-          this->CMakeInstance->IssueMessage(
-            MessageType::AUTHOR_WARNING,
-            cmStrCat("The feature '", itemFeature,
-                     "', specified as part of a generator-expression "
-                     "'$<LINK_LIBRARY:",
-                     itemFeature, ">', will not be applied to the ",
-                     cmState::GetTargetTypeName(entry.Target->GetType()), " '",
-                     entry.Item.Value, "'."),
-            this->Target->GetBacktrace());
-        }
+      if (!supportedItem) {
+        entry.Feature = LinkEntry::DEFAULT;
       }
     }
 
@@ -1170,38 +1180,50 @@
       if (entry.Feature != itemFeature) {
         bool incompatibleFeatures = true;
         // check if an override is possible
-        auto const& entryFeatureProperties = GetLinkLibraryFeatureProperties(
+        auto const& entryFeatureAttributes = GetLinkLibraryFeatureAttributes(
           this->Makefile, this->LinkLanguage, entry.Feature);
-        auto const& itemFeatureProperties = GetLinkLibraryFeatureProperties(
+        auto const& itemFeatureAttributes = GetLinkLibraryFeatureAttributes(
           this->Makefile, this->LinkLanguage, itemFeature);
-        if (entryFeatureProperties.Override.empty() &&
-            !itemFeatureProperties.Override.empty() &&
-            itemFeatureProperties.Override.find(entry.Feature) !=
-              itemFeatureProperties.Override.end()) {
-          entry.Feature = itemFeature;
-          incompatibleFeatures = false;
-        } else if (!entryFeatureProperties.Override.empty() &&
-                   itemFeatureProperties.Override.empty() &&
-                   entryFeatureProperties.Override.find(itemFeature) !=
-                     entryFeatureProperties.Override.end()) {
-          incompatibleFeatures = false;
-        }
-        if (incompatibleFeatures) {
-          // incompatibles features occurred
+        if (itemFeatureAttributes.Override.find(entry.Feature) !=
+              itemFeatureAttributes.Override.end() &&
+            entryFeatureAttributes.Override.find(itemFeature) !=
+              entryFeatureAttributes.Override.end()) {
+          // features override each other
           this->CMakeInstance->IssueMessage(
             MessageType::FATAL_ERROR,
             cmStrCat("Impossible to link target '", this->Target->GetName(),
                      "' because the link item '", entry.Item.Value,
-                     "', specified ",
-                     (itemFeature == LinkEntry::DEFAULT
-                        ? "without any feature or 'DEFAULT' feature"
-                        : cmStrCat("with the feature '", itemFeature, '\'')),
-                     ", has already occurred ",
-                     (entry.Feature == LinkEntry::DEFAULT
-                        ? "without any feature or 'DEFAULT' feature"
-                        : cmStrCat("with the feature '", entry.Feature, '\'')),
-                     ", which is not allowed."),
+                     "' is specified with the features '", itemFeature,
+                     "' and '", entry.Feature, "'",
+                     ", and both have an 'OVERRIDE' attribute that overrides "
+                     "the other. Such cycles are not allowed."),
             this->Target->GetBacktrace());
+        } else {
+          if (itemFeatureAttributes.Override.find(entry.Feature) !=
+              itemFeatureAttributes.Override.end()) {
+            entry.Feature = itemFeature;
+            incompatibleFeatures = false;
+          } else if (entryFeatureAttributes.Override.find(itemFeature) !=
+                     entryFeatureAttributes.Override.end()) {
+            incompatibleFeatures = false;
+          }
+          if (incompatibleFeatures) {
+            // incompatibles features occurred
+            this->CMakeInstance->IssueMessage(
+              MessageType::FATAL_ERROR,
+              cmStrCat(
+                "Impossible to link target '", this->Target->GetName(),
+                "' because the link item '", entry.Item.Value, "', specified ",
+                (itemFeature == LinkEntry::DEFAULT
+                   ? "without any feature or 'DEFAULT' feature"
+                   : cmStrCat("with the feature '", itemFeature, '\'')),
+                ", has already occurred ",
+                (entry.Feature == LinkEntry::DEFAULT
+                   ? "without any feature or 'DEFAULT' feature"
+                   : cmStrCat("with the feature '", entry.Feature, '\'')),
+                ", which is not allowed."),
+              this->Target->GetBacktrace());
+          }
         }
       }
     }
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index ce8cc2a..88555b6 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -8,6 +8,7 @@
 #include <cmath>
 #include <cstdio>
 #include <cstdlib>
+#include <iterator>
 #include <map>
 #include <set>
 #include <sstream>
@@ -881,6 +882,42 @@
   // Projects might pass a dynamically generated list of directories, and it
   // could be an empty list. We should not assume there is at least one.
 
+  cmRange<std::vector<std::string>::const_iterator> argsRange =
+    cmMakeRange(args).advance(1); // Get rid of subcommand
+
+  struct Arguments : public ArgumentParser::ParseResult
+  {
+    std::string Result;
+  };
+  Arguments arguments;
+
+  auto resultPosItr =
+    std::find(cm::begin(argsRange), cm::end(argsRange), "RESULT");
+  if (resultPosItr != cm::end(argsRange)) {
+    static auto const parser =
+      cmArgumentParser<Arguments>{}.Bind("RESULT"_s, &Arguments::Result);
+    std::vector<std::string> unparsedArguments;
+    auto resultDistanceFromBegin =
+      std::distance(cm::begin(argsRange), resultPosItr);
+    arguments =
+      parser.Parse(cmMakeRange(argsRange).advance(resultDistanceFromBegin),
+                   &unparsedArguments);
+
+    if (!unparsedArguments.empty()) {
+      std::string unexpectedArgsStr = cmJoin(
+        cmMakeRange(cm::begin(unparsedArguments), cm::end(unparsedArguments)),
+        "\n");
+      status.SetError("MAKE_DIRECTORY called with unexpected\n"
+                      "arguments:\n" +
+                      unexpectedArgsStr);
+      return false;
+    }
+
+    auto resultDistanceFromEnd =
+      std::distance(cm::end(argsRange), resultPosItr);
+    argsRange = argsRange.retreat(-resultDistanceFromEnd);
+  }
+
   std::string expr;
   for (std::string const& arg :
        cmMakeRange(args).advance(1)) // Get rid of subcommand
@@ -892,20 +929,34 @@
       cdir = &expr;
     }
     if (!status.GetMakefile().CanIWriteThisFile(*cdir)) {
-      std::string e = "attempted to create a directory: " + *cdir +
-        " into a source directory.";
-      status.SetError(e);
-      cmSystemTools::SetFatalErrorOccurred();
-      return false;
+      std::string e = cmStrCat("attempted to create a directory: ", *cdir,
+                               " into a source directory.");
+      if (arguments.Result.empty()) {
+        status.SetError(e);
+        cmSystemTools::SetFatalErrorOccurred();
+        return false;
+      }
+      status.GetMakefile().AddDefinition(arguments.Result, e);
+      return true;
     }
     cmsys::Status mkdirStatus = cmSystemTools::MakeDirectory(*cdir);
     if (!mkdirStatus) {
-      std::string error = cmStrCat("failed to create directory:\n  ", *cdir,
-                                   "\nbecause: ", mkdirStatus.GetString());
-      status.SetError(error);
-      return false;
+      if (arguments.Result.empty()) {
+        std::string errorOutput =
+          cmStrCat("failed to create directory:\n  ", *cdir,
+                   "\nbecause: ", mkdirStatus.GetString());
+        status.SetError(errorOutput);
+        return false;
+      }
+      std::string errorResult = cmStrCat("Failed to create directory: ", *cdir,
+                                         " Error: ", mkdirStatus.GetString());
+      status.GetMakefile().AddDefinition(arguments.Result, errorResult);
+      return true;
     }
   }
+  if (!arguments.Result.empty()) {
+    status.GetMakefile().AddDefinition(arguments.Result, "0");
+  }
   return true;
 }
 
diff --git a/Source/cmGlobalCommonGenerator.cxx b/Source/cmGlobalCommonGenerator.cxx
index 513e3bf..b1b96d0 100644
--- a/Source/cmGlobalCommonGenerator.cxx
+++ b/Source/cmGlobalCommonGenerator.cxx
@@ -12,8 +12,8 @@
 
 #include "cmGeneratorExpression.h"
 #include "cmGeneratorTarget.h"
+#include "cmLocalCommonGenerator.h"
 #include "cmLocalGenerator.h"
-#include "cmMakefile.h"
 #include "cmStateDirectory.h"
 #include "cmStateSnapshot.h"
 #include "cmStateTypes.h"
@@ -38,8 +38,8 @@
       lg->GetStateSnapshot().GetDirectory().GetCurrentBinary();
     DirectoryTarget& dirTarget = dirTargets[currentBinaryDir];
     dirTarget.LG = lg.get();
-    const std::vector<std::string>& configs =
-      lg->GetMakefile()->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
+    std::vector<std::string> const& configs =
+      static_cast<cmLocalCommonGenerator const*>(lg.get())->GetConfigNames();
 
     // The directory-level rule should depend on the target-level rules
     // for all targets in the directory.
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index 4e6f164..96c8f25 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -603,6 +603,13 @@
            "Generates build.ninja files." };
 }
 
+std::vector<std::string> const& cmGlobalNinjaGenerator::GetConfigNames() const
+{
+  return static_cast<cmLocalNinjaGenerator const*>(
+           this->LocalGenerators.front().get())
+    ->GetConfigNames();
+}
+
 // Implemented in all cmGlobaleGenerator sub-classes.
 // Used in:
 //   Source/cmLocalGenerator.cxx
@@ -655,8 +662,7 @@
 
   if (cmSystemTools::GetErrorOccurredFlag()) {
     this->RulesFileStream->setstate(std::ios::failbit);
-    for (auto const& config : this->Makefiles[0]->GetGeneratorConfigs(
-           cmMakefile::IncludeEmptyConfig)) {
+    for (std::string const& config : this->GetConfigNames()) {
       this->GetImplFileStream(config)->setstate(std::ios::failbit);
       this->GetConfigFileStream(config)->setstate(std::ios::failbit);
     }
@@ -1491,9 +1497,7 @@
   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(
-           cmMakefile::IncludeEmptyConfig)) {
+    for (std::string const& config2 : this->GetConfigNames()) {
       this->Configs[config2].TargetAliases[output].GeneratorTarget = nullptr;
     }
   }
@@ -1567,8 +1571,7 @@
   }
 
   if (this->IsMultiConfig()) {
-    for (auto const& config : this->Makefiles.front()->GetGeneratorConfigs(
-           cmMakefile::IncludeEmptyConfig)) {
+    for (std::string const& config : this->GetConfigNames()) {
       for (auto const& ta : this->Configs[config].TargetAliases) {
         // Don't write ambiguous aliases.
         if (!ta.second.GeneratorTarget) {
@@ -1630,8 +1633,7 @@
     std::string const& currentBinaryDir = it.first;
     DirectoryTarget const& dt = it.second;
     std::vector<std::string> configs =
-      dt.LG->GetMakefile()->GetGeneratorConfigs(
-        cmMakefile::IncludeEmptyConfig);
+      static_cast<cmLocalNinjaGenerator const*>(dt.LG)->GetConfigNames();
 
     // Setup target
     cmNinjaDeps configDeps;
@@ -1827,8 +1829,7 @@
   this->WriteTargetClean(os);
   this->WriteTargetHelp(os);
 
-  for (auto const& config : this->Makefiles[0]->GetGeneratorConfigs(
-         cmMakefile::IncludeEmptyConfig)) {
+  for (std::string const& config : this->GetConfigNames()) {
     this->WriteTargetDefault(*this->GetConfigFileStream(config));
   }
 
@@ -2025,8 +2026,7 @@
   std::string cleanScriptRel = "CMakeFiles/clean_additional.cmake";
   std::string cleanScriptAbs =
     cmStrCat(lgr->GetBinaryDirectory(), '/', cleanScriptRel);
-  std::vector<std::string> configs =
-    this->Makefiles[0]->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
+  std::vector<std::string> const& configs = this->GetConfigNames();
 
   // Check if there are additional files to clean
   bool empty = true;
@@ -2121,16 +2121,13 @@
     WriteRule(*this->RulesFileStream, rule);
   }
 
-  auto const configs = this->Makefiles.front()->GetGeneratorConfigs(
-    cmMakefile::IncludeEmptyConfig);
-
   // Write build
   {
     cmNinjaBuild build("CLEAN");
     build.Comment = "Clean all the built files.";
     build.Outputs.emplace_back();
 
-    for (auto const& config : configs) {
+    for (std::string const& config : this->GetConfigNames()) {
       build.Outputs.front() = this->BuildAlias(
         this->NinjaOutputPath(this->GetCleanTargetName()), config);
       if (this->IsMultiConfig()) {
@@ -2145,7 +2142,7 @@
           this->NinjaOutputPath(this->GetAdditionalCleanTargetName()),
           config));
       }
-      for (auto const& fileConfig : configs) {
+      for (std::string const& fileConfig : this->GetConfigNames()) {
         if (fileConfig != config && !this->EnableCrossConfigBuild()) {
           continue;
         }
@@ -2181,7 +2178,7 @@
       byproducts.emplace_back(GetByproductsForCleanTargetName());
       build.Variables["TARGETS"] = cmJoin(byproducts, " ");
 
-      for (auto const& fileConfig : configs) {
+      for (std::string const& fileConfig : this->GetConfigNames()) {
         build.Variables["FILE_ARG"] = cmStrCat(
           "-f ",
           this->NinjaOutputPath(
@@ -2197,7 +2194,7 @@
       this->NinjaOutputPath(this->GetCleanTargetName()));
     build.ExplicitDeps.emplace_back();
 
-    for (auto const& config : configs) {
+    for (std::string const& config : this->GetConfigNames()) {
       build.ExplicitDeps.front() = this->BuildAlias(
         this->NinjaOutputPath(this->GetCleanTargetName()), config);
       this->WriteBuild(*this->GetConfigFileStream(config), build);
@@ -2222,7 +2219,7 @@
     build.ExplicitDeps = this->ByproductsForCleanTarget;
     this->WriteBuild(os, build);
 
-    for (auto const& config : configs) {
+    for (std::string const& config : this->GetConfigNames()) {
       build.Outputs.front() = this->BuildAlias(
         this->ConvertToNinjaPath(GetByproductsForCleanTargetName()), config);
       build.ExplicitDeps = this->Configs[config].ByproductsForCleanTarget;
@@ -3119,8 +3116,7 @@
     << "# This file contains build statements common to all "
        "configurations.\n\n";
 
-  auto const& configs =
-    this->Makefiles[0]->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
+  std::vector<std::string> const& configs = this->GetConfigNames();
   return std::all_of(
     configs.begin(), configs.end(), [this](std::string const& config) -> bool {
       // Open impl file.
@@ -3163,8 +3159,7 @@
     this->DefaultFileStream.reset();
   } // No error if it wasn't open
 
-  for (auto const& config : this->Makefiles[0]->GetGeneratorConfigs(
-         cmMakefile::IncludeEmptyConfig)) {
+  for (std::string const& config : this->GetConfigNames()) {
     if (this->ImplFileStreams[config]) {
       this->ImplFileStreams[config].reset();
     } else {
@@ -3206,8 +3201,7 @@
 void cmGlobalNinjaMultiGenerator::AddRebuildManifestOutputs(
   cmNinjaDeps& outputs) const
 {
-  for (auto const& config : this->Makefiles.front()->GetGeneratorConfigs(
-         cmMakefile::IncludeEmptyConfig)) {
+  for (std::string const& config : this->GetConfigNames()) {
     outputs.push_back(this->NinjaOutputPath(GetNinjaImplFilename(config)));
     outputs.push_back(this->NinjaOutputPath(GetNinjaConfigFilename(config)));
   }
@@ -3219,18 +3213,15 @@
 void cmGlobalNinjaMultiGenerator::GetQtAutoGenConfigs(
   std::vector<std::string>& configs) const
 {
-  auto allConfigs =
-    this->Makefiles[0]->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
+  std::vector<std::string> const& allConfigs = this->GetConfigNames();
   configs.insert(configs.end(), cm::cbegin(allConfigs), cm::cend(allConfigs));
 }
 
 bool cmGlobalNinjaMultiGenerator::InspectConfigTypeVariables()
 {
-  cmList configsList{ this->Makefiles.front()->GetDefinition(
-    "CMAKE_CONFIGURATION_TYPES") };
-  if (configsList.empty()) {
-    configsList.emplace_back();
-  }
+  std::vector<std::string> configsList =
+    this->Makefiles.front()->GetGeneratorConfigs(
+      cmMakefile::IncludeEmptyConfig);
   std::set<std::string> configs(configsList.cbegin(), configsList.cend());
 
   this->DefaultFileConfig =
diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h
index 9758627..6ad38fb 100644
--- a/Source/cmGlobalNinjaGenerator.h
+++ b/Source/cmGlobalNinjaGenerator.h
@@ -485,6 +485,8 @@
   bool CheckCxxModuleSupport(CxxModuleSupportQuery query) override;
 
 protected:
+  std::vector<std::string> const& GetConfigNames() const;
+
   void Generate() override;
 
   bool CheckALLOW_DUPLICATE_CUSTOM_TARGETS() const override { return true; }
diff --git a/Source/cmGlobalVisualStudio10Generator.cxx b/Source/cmGlobalVisualStudio10Generator.cxx
index 7abe75a..51d6d8a 100644
--- a/Source/cmGlobalVisualStudio10Generator.cxx
+++ b/Source/cmGlobalVisualStudio10Generator.cxx
@@ -225,10 +225,8 @@
                                   versionToolsetRegex.match(2));
         // Hard-code special cases for toolset versions whose first
         // three digits do not match their toolset name.
-        if (platformToolset == "v143"_s && versionToolset == "v144"_s &&
-            // VS 17.10 toolset v143 version 14.40.
-            (this->GeneratorToolsetVersion == "14.40"_s ||
-             cmHasLiteralPrefix(this->GeneratorToolsetVersion, "14.40."))) {
+        // The v143 toolset reserves versions 14.30 through 14.49.
+        if (platformToolset == "v143"_s && versionToolset == "v144"_s) {
           versionToolset = "v143";
         }
       } else {
diff --git a/Source/cmLocalCommonGenerator.cxx b/Source/cmLocalCommonGenerator.cxx
index aa953f4..14b3040 100644
--- a/Source/cmLocalCommonGenerator.cxx
+++ b/Source/cmLocalCommonGenerator.cxx
@@ -2,10 +2,12 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmLocalCommonGenerator.h"
 
+#include <memory>
 #include <utility>
 #include <vector>
 
 #include "cmGeneratorTarget.h"
+#include "cmGlobalGenerator.h"
 #include "cmMakefile.h"
 #include "cmOutputConverter.h"
 #include "cmStateDirectory.h"
@@ -13,14 +15,18 @@
 #include "cmStringAlgorithms.h"
 #include "cmValue.h"
 
-class cmGlobalGenerator;
-
 cmLocalCommonGenerator::cmLocalCommonGenerator(cmGlobalGenerator* gg,
                                                cmMakefile* mf)
   : cmLocalGenerator(gg, mf)
 {
-  this->ConfigNames =
-    this->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
+  // Multi-config generators define one set of configurations at the top.
+  // Single-config generators nominally define one configuration at the top,
+  // but the implementation has never been strict about that, so look up the
+  // per-directory config to preserve behavior.
+  this->ConfigNames = (gg->IsMultiConfig() && !gg->GetMakefiles().empty()
+                         ? gg->GetMakefiles().front().get()
+                         : this->Makefile)
+                        ->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
 }
 
 cmLocalCommonGenerator::~cmLocalCommonGenerator() = default;
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 94e62ff..aa3f28e 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -4369,6 +4369,7 @@
   cmLGInfoProp(mf, target, "MACOSX_FRAMEWORK_ICON_FILE");
   cmLGInfoProp(mf, target, "MACOSX_FRAMEWORK_IDENTIFIER");
   cmLGInfoProp(mf, target, "MACOSX_FRAMEWORK_SHORT_VERSION_STRING");
+  cmLGInfoProp(mf, target, "MACOSX_FRAMEWORK_BUNDLE_NAME");
   cmLGInfoProp(mf, target, "MACOSX_FRAMEWORK_BUNDLE_VERSION");
   mf->ConfigureFile(inFile, fname, false, false, false);
 }
diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx
index bc3da6e..46a95af 100644
--- a/Source/cmLocalNinjaGenerator.cxx
+++ b/Source/cmLocalNinjaGenerator.cxx
@@ -743,8 +743,6 @@
 bool cmLocalNinjaGenerator::HasUniqueByproducts(
   std::vector<std::string> const& byproducts, cmListFileBacktrace const& bt)
 {
-  std::vector<std::string> configs =
-    this->GetMakefile()->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
   cmGeneratorExpression ge(*this->GetCMakeInstance(), bt);
   for (std::string const& p : byproducts) {
     if (cmGeneratorExpression::Find(p) == std::string::npos) {
@@ -752,7 +750,7 @@
     }
     std::set<std::string> seen;
     std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(p);
-    for (std::string const& config : configs) {
+    for (std::string const& config : this->GetConfigNames()) {
       for (std::string const& b :
            this->ExpandCustomCommandOutputPaths(*cge, config)) {
         if (!seen.insert(b).second) {
@@ -800,8 +798,7 @@
   std::string const base = cmStrCat(this->GetCurrentBinaryDirectory(),
                                     "/CMakeFiles/", targetName, '-');
   // The output is not actually created so mark it symbolic.
-  for (std::string const& config :
-       this->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig)) {
+  for (std::string const& config : this->GetConfigNames()) {
     std::string const force = cmStrCat(base, config);
     if (cmSourceFile* sf = this->Makefile->GetOrCreateGeneratedSource(force)) {
       sf->SetProperty("SYMBOLIC", "1");
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index 160689c..a10635a 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -87,8 +87,7 @@
   , LocalGenerator(
       static_cast<cmLocalNinjaGenerator*>(target->GetLocalGenerator()))
 {
-  for (auto const& fileConfig :
-       target->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig)) {
+  for (auto const& fileConfig : this->LocalGenerator->GetConfigNames()) {
     this->Configs[fileConfig].MacOSXContentGenerator =
       cm::make_unique<MacOSXContentGeneratorType>(this, fileConfig);
   }
diff --git a/Tests/RunCMake/Autogen/RunCMakeTest.cmake b/Tests/RunCMake/Autogen/RunCMakeTest.cmake
deleted file mode 100644
index 0036551..0000000
--- a/Tests/RunCMake/Autogen/RunCMakeTest.cmake
+++ /dev/null
@@ -1,487 +0,0 @@
-include(RunCMake)
-
-run_cmake(NoQt)
-if (DEFINED with_qt_version)
-  set(RunCMake_TEST_OPTIONS
-    -Dwith_qt_version=${with_qt_version}
-    "-DQt${with_qt_version}_DIR:PATH=${Qt${with_qt_version}_DIR}"
-    "-DCMAKE_PREFIX_PATH:STRING=${CMAKE_PREFIX_PATH}"
-  )
-
-  run_cmake(QtInFunction)
-  run_cmake(QtInFunctionNested)
-  run_cmake(QtInFunctionProperty)
-
-  run_cmake(CMP0111-imported-target-full)
-  run_cmake(CMP0111-imported-target-libname)
-  run_cmake(CMP0111-imported-target-implib-only)
-
-  block()
-    set(RunCMake_TEST_BINARY_DIR  ${RunCMake_BINARY_DIR}/MocPredefs-build)
-    run_cmake(MocPredefs)
-    set(RunCMake_TEST_NO_CLEAN 1)
-    run_cmake_command(MocPredefs-build ${CMAKE_COMMAND} --build . --config Debug)
-  endblock()
-
-  # Detect information from the toolchain:
-  # - CMAKE_INCLUDE_FLAG_CXX
-  # - CMAKE_INCLUDE_SYSTEM_FLAG_CXX
-  run_cmake(Inspect)
-  include("${RunCMake_BINARY_DIR}/Inspect-build/info.cmake")
-
-  if(CMAKE_INCLUDE_SYSTEM_FLAG_CXX)
-    if(RunCMake_GENERATOR MATCHES "Visual Studio")
-      string(REGEX REPLACE "^-" "/" test_expect_stdout "${CMAKE_INCLUDE_SYSTEM_FLAG_CXX}")
-    else()
-      set(test_expect_stdout "-*${CMAKE_INCLUDE_SYSTEM_FLAG_CXX}")
-    endif()
-    string(APPEND test_expect_stdout " *(\"[^\"]*|([^ ]|\\ )*)[\\/]dummy_autogen[\\/]include")
-    if(RunCMake_GENERATOR_IS_MULTI_CONFIG)
-      string(APPEND test_expect_stdout "_Debug")
-    endif()
-
-    block()
-      set(RunCMake_TEST_BINARY_DIR  ${RunCMake_BINARY_DIR}/CMP0151-new-build)
-      run_cmake_with_options(CMP0151-new ${RunCMake_TEST_OPTIONS} -DCMAKE_POLICY_DEFAULT_CMP0151=NEW)
-      set(RunCMake_TEST_NO_CLEAN 1)
-      set(RunCMake_TEST_EXPECT_stdout "${test_expect_stdout}")
-      message(STATUS "RunCMake_TEST_EXPECT_stdout: ${RunCMake_TEST_EXPECT_stdout}")
-      run_cmake_command(CMP0151-new-build ${CMAKE_COMMAND} --build . --config Debug --verbose)
-    endblock()
-
-    block()
-      set(RunCMake_TEST_BINARY_DIR  ${RunCMake_BINARY_DIR}/AutogenUseSystemIncludeOn-build)
-      run_cmake_with_options(AutogenUseSystemIncludeOn ${RunCMake_TEST_OPTIONS} -DCMAKE_POLICY_DEFAULT_CMP0151=NEW)
-      set(RunCMake_TEST_NO_CLEAN 1)
-      set(RunCMake_TEST_EXPECT_stdout "${test_expect_stdout}")
-      message(STATUS "RunCMake_TEST_EXPECT_stdout: ${RunCMake_TEST_EXPECT_stdout}")
-      run_cmake_command(AutogenUseSystemIncludeOn ${CMAKE_COMMAND} --build . --config Debug --verbose)
-    endblock()
-  endif()
-
-  if(CMAKE_INCLUDE_FLAG_CXX)
-    if(RunCMake_GENERATOR MATCHES "Visual Studio")
-      string(REGEX REPLACE "^-" "/" test_expect_stdout "${CMAKE_INCLUDE_FLAG_CXX}")
-    else()
-      set(test_expect_stdout "-*${CMAKE_INCLUDE_FLAG_CXX}")
-    endif()
-    string(APPEND test_expect_stdout " *(\"[^\"]*|([^ ]|\\ )*)[\\/]dummy_autogen[\\/]include")
-    if(RunCMake_GENERATOR_IS_MULTI_CONFIG)
-      string(APPEND test_expect_stdout "_Debug")
-    endif()
-
-    block()
-      set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/CMP0151-old-build)
-      run_cmake_with_options(CMP0151-old ${RunCMake_TEST_OPTIONS} -DCMAKE_POLICY_DEFAULT_CMP0151=OLD)
-      set(RunCMake_TEST_NO_CLEAN 1)
-      set(RunCMake_TEST_EXPECT_stdout "${test_expect_stdout}")
-      message(STATUS "RunCMake_TEST_EXPECT_stdout: ${RunCMake_TEST_EXPECT_stdout}")
-      run_cmake_command(CMP0151-old-build ${CMAKE_COMMAND} --build . --config Debug --verbose)
-    endblock()
-
-    block()
-      set(RunCMake_TEST_BINARY_DIR  ${RunCMake_BINARY_DIR}/AutogenUseSystemIncludeOff-build)
-      run_cmake_with_options(AutogenUseSystemIncludeOff ${RunCMake_TEST_OPTIONS} -DCMAKE_POLICY_DEFAULT_CMP0151=NEW)
-      set(RunCMake_TEST_NO_CLEAN 1)
-      set(RunCMake_TEST_EXPECT_stdout "${test_expect_stdout}")
-      message(STATUS "RunCMake_TEST_EXPECT_stdout: ${RunCMake_TEST_EXPECT_stdout}")
-      run_cmake_command(AutogenUseSystemIncludeOff ${CMAKE_COMMAND} --build . --config Debug --verbose)
-    endblock()
-
-    if(RunCMake_GENERATOR MATCHES "Make|Ninja")
-      block()
-        set(RunCMake_TEST_BINARY_DIR  ${RunCMake_BINARY_DIR}/AutogenSkipLinting-build)
-        list(APPEND RunCMake_TEST_OPTIONS
-          "-DPSEUDO_CPPCHECK=${PSEUDO_CPPCHECK}"
-          "-DPSEUDO_CPPLINT=${PSEUDO_CPPLINT}"
-          "-DPSEUDO_IWYU=${PSEUDO_IWYU}"
-          "-DPSEUDO_TIDY=${PSEUDO_TIDY}")
-
-        run_cmake(AutogenSkipLinting)
-        set(RunCMake_TEST_NO_CLEAN 1)
-        run_cmake_command(AutogenSkipLinting-build ${CMAKE_COMMAND} --build . --config Debug --verbose)
-      endblock()
-    endif()
-  endif()
-
-  if(RunCMake_GENERATOR_IS_MULTI_CONFIG AND NOT RunCMake_GENERATOR MATCHES "Xcode")
-    block()
-      set(RunCMake_TEST_BINARY_DIR  ${RunCMake_BINARY_DIR}/MocGeneratedFile-build)
-      run_cmake(MocGeneratedFile)
-      set(RunCMake_TEST_NO_CLEAN 1)
-      run_cmake_command(MocGeneratedFile-build ${CMAKE_COMMAND} --build . --config Debug --verbose)
-    endblock()
-    if(RunCMake_GENERATOR MATCHES "Ninja Multi-Config")
-      block()
-        set(RunCMake_TEST_BINARY_DIR  ${RunCMake_BINARY_DIR}/MocGeneratedFile-cross-config-build)
-        list(APPEND RunCMake_TEST_OPTIONS -DCMAKE_CROSS_CONFIGS=all)
-        run_cmake(MocGeneratedFile)
-        set(RunCMake_TEST_NO_CLEAN 1)
-        run_cmake_command(MocGeneratedFile-cross-config-build ${CMAKE_COMMAND} --build . --config Release --target libgen:Debug)
-        run_cmake_command(MocGeneratedFile-cross-config-build ${CMAKE_COMMAND} --build . --config Debug --target libgen:Release)
-      endblock()
-    endif()
-  endif()
-
-  if(RunCMake_GENERATOR MATCHES "Make|Ninja")
-    block()
-      if(QtCore_VERSION VERSION_GREATER_EQUAL 5.15.0)
-        if (RunCMake_GENERATOR MATCHES "Ninja Multi-Config")
-          set(config_list Debug Release RelWithDebInfo)
-          set(use_better_graph_list ON OFF)
-        else()
-          set(config_list single-config)
-          set(use_better_graph_list OFF)
-        endif()
-
-        foreach(use_better_graph IN ITEMS ${use_better_graph_list})
-          foreach(config IN ITEMS ${config_list})
-            block()
-              if (config STREQUAL "single-config")
-                set(config_suffix "")
-              else()
-                set(config_path "_${config}")
-                if (use_better_graph)
-                  set(config_suffix "_${config}")
-                endif()
-              endif()
-
-              set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/QtAutoMocDeps${config_path}-build)
-              run_cmake_with_options(QtAutoMocDeps ${RunCMake_TEST_OPTIONS} -DCMAKE_AUTOGEN_BETTER_GRAPH_MULTI_CONFIG=${use_better_graph})
-              set(RunCMake_TEST_NO_CLEAN 1)
-              # Build the project.
-              if (config STREQUAL "single-config")
-                set(config_param "")
-              else()
-                set(config_param "--config ${config}")
-              endif()
-              run_cmake_command(QtAutoMocDeps-build ${CMAKE_COMMAND} --build . --verbose ${config_param})
-              # Touch just the library source file, which shouldn't cause a rerun of AUTOMOC
-              # for app_with_qt target.
-              file(TOUCH "${RunCMake_SOURCE_DIR}/simple_lib.cpp")
-              set(RunCMake_TEST_NOT_EXPECT_stdout "Automatic MOC for target app_with_qt|\
-Automatic MOC for target sub_exe_1|\
-Automatic MOC for target sub_exe_2")
-              set(RunCMake_TEST_VARIANT_DESCRIPTION "-Don't execute AUTOMOC for 'app_with_qt', 'sub_exe_1' and 'sub_exe_2'")
-              # Build and assert that AUTOMOC was not run for app_with_qt, sub_exe_1 and sub_exe_2.
-              run_cmake_command(QtAutoMocDeps-build ${CMAKE_COMMAND} --build . --verbose ${config_param})
-              unset(RunCMake_TEST_VARIANT_DESCRIPTION)
-              unset(RunCMake_TEST_NOT_EXPECT_stdout)
-
-              macro(check_file_exists file)
-                if (EXISTS "${file}")
-                  set(check_result "PASSED")
-                  set(message_type "STATUS")
-                else()
-                  set(check_result "FAILED")
-                  set(message_type "FATAL_ERROR")
-                endif()
-
-                message(${message_type} "QtAutoMocDeps-build-\"${file}\" was generated - ${check_result}")
-              endmacro()
-
-              check_file_exists("${RunCMake_TEST_BINARY_DIR}/app_with_qt_autogen/deps${config_suffix}")
-              check_file_exists("${RunCMake_TEST_BINARY_DIR}/QtSubDir1/sub_exe_1_autogen/deps${config_suffix}")
-              check_file_exists("${RunCMake_TEST_BINARY_DIR}/QtSubDir2/sub_exe_2_autogen/deps${config_suffix}")
-
-              check_file_exists("${RunCMake_TEST_BINARY_DIR}/app_with_qt_autogen/timestamp${config_suffix}")
-              check_file_exists("${RunCMake_TEST_BINARY_DIR}/QtSubDir1/sub_exe_1_autogen/timestamp${config_suffix}")
-              check_file_exists("${RunCMake_TEST_BINARY_DIR}/QtSubDir2/sub_exe_2_autogen/timestamp${config_suffix}")
-
-              # Touch a header file to make sure an automoc dependency cycle is not introduced.
-              file(TOUCH "${RunCMake_SOURCE_DIR}/MyWindow.h")
-              set(RunCMake_TEST_VARIANT_DESCRIPTION "-First build after touch to detect dependency cycle")
-              run_cmake_command(QtAutoMocDeps-build ${CMAKE_COMMAND} --build . --verbose)
-              # Need to run a second time to hit the dependency cycle.
-              set(RunCMake_TEST_VARIANT_DESCRIPTION "-Don't hit dependency cycle")
-              run_cmake_command(QtAutoMocDeps-build ${CMAKE_COMMAND} --build . --verbose)
-            endblock()
-          endforeach()
-        endforeach()
-      endif()
-    endblock()
-  endif()
-
-  function(run_make_program dir)
-    execute_process(
-      COMMAND "${RunCMake_MAKE_PROGRAM}" ${ARGN}
-      WORKING_DIRECTORY "${dir}"
-      OUTPUT_VARIABLE make_program_stdout
-      ERROR_VARIABLE make_program_stderr
-      RESULT_VARIABLE make_program_result
-      )
-      if (NOT DEFINED RunMakeProgram_expected_result)
-        set(RunMakeProgram_expected_result 0)
-      endif()
-      if(NOT "${make_program_result}" MATCHES "${RunMakeProgram_expected_result}")
-        message(STATUS "
-============ beginning of ${RunCMake_MAKE_PROGRAM}'s stdout ============
-${make_program_stdout}
-=============== end of ${RunCMake_MAKE_PROGRAM}'s stdout ===============
-")
-        message(STATUS "
-============ beginning of ${RunCMake_MAKE_PROGRAM}'s stderr ============
-${make_program_stderr}
-=============== end of ${RunCMake_MAKE_PROGRAM}'s stderr ===============
-")
-        message(FATAL_ERROR
-                "top ${RunCMake_MAKE_PROGRAM} build failed exited with status ${make_program_result}")
-    endif()
-    set(make_program_stdout "${make_program_stdout}" PARENT_SCOPE)
-  endfunction(run_make_program)
-
-  function(count_substring STRING SUBSTRING COUNT_VAR)
-      string(LENGTH "${STRING}" STRING_LENGTH)
-      string(LENGTH "${SUBSTRING}" SUBSTRING_LENGTH)
-      if (SUBSTRING_LENGTH EQUAL 0)
-          message(FATAL_ERROR "SUBSTRING_LENGTH is 0")
-      endif()
-
-      if (STRING_LENGTH EQUAL 0)
-          message(FATAL_ERROR "STRING_LENGTH is 0")
-      endif()
-
-      if (STRING_LENGTH LESS SUBSTRING_LENGTH)
-          message(FATAL_ERROR "STRING_LENGTH is less than SUBSTRING_LENGTH")
-      endif()
-
-      set(COUNT 0)
-      string(FIND "${STRING}" "${SUBSTRING}" SUBSTRING_START)
-      while(SUBSTRING_START GREATER_EQUAL 0)
-          math(EXPR COUNT "${COUNT} + 1")
-          math(EXPR SUBSTRING_START "${SUBSTRING_START} + ${SUBSTRING_LENGTH}")
-          string(SUBSTRING "${STRING}" ${SUBSTRING_START} -1 STRING)
-          string(FIND "${STRING}" "${SUBSTRING}" SUBSTRING_START)
-      endwhile()
-
-      set(${COUNT_VAR} ${COUNT} PARENT_SCOPE)
-  endfunction()
-
-  function(expect_only_once make_program_stdout expected_output test_name)
-    count_substring("${make_program_stdout}" "${expected_output}" count)
-    if(NOT count EQUAL 1)
-      message(STATUS "${test_name}-expect_only_once - FAILED")
-      message(FATAL_ERROR "Expected to find ${expected_output} exactly once in ${make_program_stdout} but found ${count} occurrences of ${expected_output}")
-    else()
-      message(STATUS "${test_name}-expect_only_once - PASSED")
-    endif()
-  endfunction()
-
-  function(expect_n_times string_to_check expected_output expected_count test_name)
-    count_substring("${string_to_check}" "${expected_output}" count)
-    if(NOT count EQUAL ${expected_count})
-      message(STATUS "${test_name}-expect_${expected_count}_times - FAILED")
-      message(FATAL_ERROR "Expected to find ${expected_output} exactly ${expected_count} times in ${string_to_check} but found ${count} occurrences of ${expected_output}")
-    else()
-      message(STATUS "${test_name}-expect_${expected_count}_times - PASSED")
-    endif()
-  endfunction()
-
-  function(not_expect make_program_stdout unexpected_output test_name)
-    count_substring("${make_program_stdout}" "${unexpected_output}" count)
-    if(NOT count EQUAL 0)
-      message(STATUS "${test_name}-not_expect - FAILED")
-      message(FATAL_ERROR "Expected to find ${unexpected_output} exactly 0 times in ${make_program_stdout} but found ${count} occurrences of ${unexpected_output}")
-    else()
-      message(STATUS "${test_name}-not_expect - PASSED")
-    endif()
-  endfunction()
-
-  if (QtCore_VERSION VERSION_GREATER_EQUAL 5.15.0)
-    foreach(exe IN ITEMS Moc Uic Rcc)
-      if(RunCMake_GENERATOR MATCHES "Ninja Multi-Config")
-        block()
-          set(RunCMake_TEST_VARIANT_DESCRIPTION "-CMake-configure")
-          set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Auto${exe}ExecutableConfig-multi-config-build)
-          run_cmake_with_options(Auto${exe}ExecutableConfig ${RunCMake_TEST_OPTIONS} -DCMAKE_AUTOGEN_VERBOSE=ON -DCMAKE_AUTOGEN_BETTER_GRAPH_MULTI_CONFIG=ON)
-          unset(RunCMake_TEST_VARIANT_DESCRIPTION)
-          set(RunCMake_TEST_NO_CLEAN 1)
-          foreach(config IN ITEMS Debug Release RelWithDebInfo)
-            block()
-              set(RunCMake_TEST_EXPECT_stdout ".*running_exe_${config}*")
-              set(RunCMake_TEST_VARIANT_DESCRIPTION "-${config}-expect_running_exe_${config}")
-              run_cmake_command(Auto${exe}ExecutableConfig-multi-config-build ${CMAKE_COMMAND} --build . --config ${config})
-            endblock()
-          endforeach()
-          set(RunCMake_TEST_EXPECT_stdout "ninja: no work to do")
-          foreach(config IN ITEMS Debug Release RelWithDebInfo)
-            block()
-            set(RunCMake_TEST_VARIANT_DESCRIPTION "-${config}-expect_no_work_to_do")
-              run_cmake_command(Auto${exe}ExecutableConfig-multi-config-build ${CMAKE_COMMAND} --build . --config ${config})
-            endblock()
-          endforeach()
-        endblock()
-        block()
-          set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Auto${exe}ExecutableConfig-build)
-          run_cmake_with_options(Auto${exe}ExecutableConfig ${RunCMake_TEST_OPTIONS} -DCMAKE_AUTOGEN_VERBOSE=ON -DCMAKE_AUTOGEN_BETTER_GRAPH_MULTI_CONFIG=ON)
-          foreach(config IN ITEMS Debug Release RelWithDebInfo)
-            block()
-              run_make_program(${RunCMake_TEST_BINARY_DIR} --verbose -f build-${config}.ninja)
-
-              set(expected_output "running_exe_${config}")
-              expect_only_once("${make_program_stdout}" "${expected_output}" "Auto${exe}ExecutableConfig-${config}-${expected_output}")
-
-              foreach(sub_config IN ITEMS Debug Release RelWithDebInfo)
-                if(NOT sub_config STREQUAL config)
-                  set(unexpected_output "running_exe_${sub_config}")
-                  not_expect("${make_program_stdout}" "${unexpected_output}" "Auto${exe}ExecutableConfig-${config}-${unexpected_output}")
-                endif()
-              endforeach()
-
-              if (exe STREQUAL "Moc" OR exe STREQUAL "Uic")
-                set(expected_output "cmake_autogen")
-              else()
-                set(expected_output "cmake_autorcc")
-              endif()
-              expect_only_once("${make_program_stdout}" "${expected_output}" "Auto${exe}ExecutableConfig-${config}-${expected_output}")
-            endblock()
-          endforeach()
-        endblock()
-        block()
-          foreach(ninja_config IN ITEMS Debug Release RelWithDebInfo)
-            foreach(target_config IN ITEMS Debug Release RelWithDebInfo)
-              block()
-                set(TEST_SUFFIX "-CrossConfig-${ninja_config}-${target_config}")
-                set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Auto${exe}ExecutableConfig${TEST_SUFFIX}-build)
-                set(RunCMake_TEST_VARIANT_DESCRIPTION ${TEST_SUFFIX})
-                run_cmake_with_options(Auto${exe}ExecutableConfig ${RunCMake_TEST_OPTIONS} -DCMAKE_CROSS_CONFIGS=all -DCMAKE_DEFAULT_BUILD_TYPE=${ninja_config} -DCMAKE_AUTOGEN_BETTER_GRAPH_MULTI_CONFIG=ON)
-                unset(RunCMake_TEST_VARIANT_DESCRIPTION)
-
-                run_make_program(${RunCMake_TEST_BINARY_DIR} --verbose -f build-${ninja_config}.ninja dummy:${target_config})
-
-                set(expected_output "running_exe_${ninja_config}")
-                expect_only_once("${make_program_stdout}" "${expected_output}" "Auto${exe}ExecutableConfig${TEST_SUFFIX}-${expected_output}")
-
-                foreach(sub_config IN ITEMS Debug Release RelWithDebInfo)
-                  if(NOT sub_config STREQUAL ninja_config)
-                    set(unexpected_output "running_exe_${sub_config}")
-                    not_expect("${make_program_stdout}" "${unexpected_output}" "Auto${exe}ExecutableConfig${TEST_SUFFIX}-${unexpected_output}")
-                  endif()
-                endforeach()
-
-                if (exe STREQUAL "Moc" OR exe STREQUAL "Uic")
-                  set(expected_output "cmake_autogen")
-                else()
-                  set(expected_output "cmake_autorcc")
-                endif()
-                expect_only_once("${make_program_stdout}" "${expected_output}" "Auto${exe}ExecutableConfig${TEST_SUFFIX}-${expected_output}")
-              endblock()
-            endforeach()
-          endforeach()
-        endblock()
-        block()
-          foreach(ninja_config IN ITEMS Debug Release RelWithDebInfo)
-            set(TEST_SUFFIX "-CrossConfig-${ninja_config}-all-all")
-            set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Auto${exe}ExecutableConfig${TEST_SUFFIX}-build)
-            set(RunCMake_TEST_VARIANT_DESCRIPTION ${TEST_SUFFIX})
-            run_cmake_with_options(Auto${exe}ExecutableConfig ${RunCMake_TEST_OPTIONS} -DCMAKE_CROSS_CONFIGS=all -DCMAKE_AUTOGEN_BETTER_GRAPH_MULTI_CONFIG=ON)
-            unset(RunCMake_TEST_VARIANT_DESCRIPTION)
-            run_make_program(${RunCMake_TEST_BINARY_DIR} --verbose -f build-${ninja_config}.ninja all:all)
-          endforeach()
-        endblock()
-      elseif (RunCMake_GENERATOR MATCHES "Ninja|Make")
-        block()
-          set(RunCMake_TEST_BINARY_DIR  ${RunCMake_BINARY_DIR}/Auto${exe}ExecutableConfig-build)
-          foreach(config IN ITEMS Debug Release RelWithDebInfo)
-            block()
-              set(RunCMake_TEST_VARIANT_DESCRIPTION "-${config}")
-              run_cmake_with_options(Auto${exe}ExecutableConfig ${RunCMake_TEST_OPTIONS} -DCMAKE_BUILD_TYPE=${config} -DCMAKE_AUTOGEN_VERBOSE=ON)
-              unset(RunCMake_TEST_VARIANT_DESCRIPTION)
-              set(RunCMake_TEST_NO_CLEAN 1)
-              set(RunCMake_TEST_EXPECT_stdout ".*running_exe_${config}*")
-              run_cmake_command(Auto${exe}ExecutableConfig-${config}-build ${CMAKE_COMMAND} --build .)
-            endblock()
-          endforeach()
-        endblock()
-      endif()
-    endforeach()
-  endif()
-
-  # Visual Studio specific dependency tests
-  if (RunCMake_GENERATOR MATCHES "Visual Studio")
-      foreach(exe IN ITEMS Moc Uic Rcc)
-          block()
-            set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${exe}Example-build)
-            set(RunCMake_TEST_VARIANT_DESCRIPTION "-CMake-configure")
-            run_cmake_with_options(${exe}Example ${RunCMake_TEST_OPTIONS} -DCMAKE_AUTOGEN_VERBOSE=ON)
-            unset(RunCMake_TEST_VARIANT_DESCRIPTION)
-            set(RunCMake_TEST_NO_CLEAN 1)
-            foreach(config IN ITEMS Debug Release RelWithDebInfo)
-              block()
-                set(RunCMake_TEST_VARIANT_DESCRIPTION "-${config}-first-build")
-                run_cmake_command(${exe}Example-build ${CMAKE_COMMAND} --build . --config ${config})
-              endblock()
-            endforeach()
-            foreach(config IN ITEMS Debug Release RelWithDebInfo)
-              block()
-                if (exe STREQUAL "Moc" OR exe STREQUAL "Uic")
-                  set(RunCMake_TEST_NOT_EXPECT_stdout "Auto${exe}")
-                  set(not_expect_descripton "Auto${exe}")
-                else ()
-                  set(RunCMake_TEST_NOT_EXPECT_stdout "Auto${exe}")
-                  set(not_expect_descripton "Auto${exe}")
-                endif()
-                set(RunCMake_TEST_VARIANT_DESCRIPTION "-second-build-${config}_expect_no_${not_expect_descripton}")
-                run_cmake_command(${exe}Example-build ${CMAKE_COMMAND} --build . --config ${config})
-              endblock()
-            endforeach()
-          endblock()
-      endforeach()
-  endif()
-
-  if (RunCMake_GENERATOR MATCHES "Xcode")
-    foreach(exe IN ITEMS Moc Uic Rcc)
-      block()
-        set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${exe}Example-build)
-        set(RunCMake_TEST_VARIANT_DESCRIPTION "-CMake-configure")
-        set(RunCMake_TEST_EXPECT_stderr ".*")
-        run_cmake_with_options(${exe}Example ${RunCMake_TEST_OPTIONS} -DCMAKE_AUTOGEN_VERBOSE=ON)
-        set(RunCMake_TEST_NO_CLEAN 1)
-        set(RunCMake_MAKE_PROGRAM ${CMAKE_COMMAND})
-        run_make_program(${RunCMake_TEST_BINARY_DIR}  --build . --config Debug)
-        if (exe STREQUAL "Moc")
-          set(expected_count 16)
-        elseif (exe STREQUAL "Uic")
-          set(expected_count 4)
-        else()
-          set(expected_count 12)
-        endif()
-        expect_n_times("${make_program_stdout}" "Auto${exe}:" ${expected_count} "${exe}Example-build-Auto${exe}")
-        expect_n_times("${make_program_stdout}" "Auto${exe}:" ${expected_count} "${exe}Example-build-Auto${exe}")
-
-        if (exe STREQUAL "Moc" OR exe STREQUAL "Uic")
-          expect_n_times("${make_program_stdout}" "AutoGen:" 20 "${exe}Example-build-AutoGen:")
-        endif()
-
-        foreach(config IN ITEMS Debug Release RelWithDebInfo)
-          block()
-            run_make_program(${RunCMake_TEST_BINARY_DIR} --build . --config ${config})
-            not_expect("${make_program_stdout}" "Auto${exe}" "${exe}Example-${config}_Auto${exe}")
-            not_expect("${make_program_stdout}" "AutoGen:" "${exe}Example-${config}_AutoGen")
-          endblock()
-        endforeach()
-      endblock()
-    endforeach()
-  endif()
-
-  if (QtCore_VERSION VERSION_GREATER_EQUAL 6)
-    if (RunCMake_GENERATOR MATCHES "Make|Ninja")
-      foreach(value IN ITEMS ON OFF)
-        block()
-          set(RunCMake_TEST_BINARY_DIR
-            ${RunCMake_BINARY_DIR}/RccNoZTSD-${value}-build)
-          run_cmake_with_options(RccExample ${RunCMake_TEST_OPTIONS}
-            -DCMAKE_AUTOGEN_VERBOSE=ON -DZSTD_VALUE=${value})
-          if (value STREQUAL "OFF")
-            set(RunCMake_TEST_EXPECT_stdout "--no-zstd")
-          else()
-            set(RunCMake_TEST_NOT_EXPECT_stdout "--no-zstd")
-          endif()
-          set(RunCMake_TEST_NO_CLEAN 1)
-          run_cmake_command(RccNoZTSD-${value}-build ${CMAKE_COMMAND}
-            --build . --config Debug)
-        endblock()
-      endforeach()
-    endif()
-  endif()
-endif ()
diff --git a/Tests/RunCMake/Autogen/exe.cpp b/Tests/RunCMake/Autogen/exe.cpp
deleted file mode 100644
index f8b643a..0000000
--- a/Tests/RunCMake/Autogen/exe.cpp
+++ /dev/null
@@ -1,4 +0,0 @@
-int main()
-{
-  return 0;
-}
diff --git a/Tests/RunCMake/Autogen/AutogenSkipLinting-build-stderr.txt b/Tests/RunCMake/Autogen_1/AutogenSkipLinting-build-stderr.txt
similarity index 100%
rename from Tests/RunCMake/Autogen/AutogenSkipLinting-build-stderr.txt
rename to Tests/RunCMake/Autogen_1/AutogenSkipLinting-build-stderr.txt
diff --git a/Tests/RunCMake/Autogen/AutogenSkipLinting.cmake b/Tests/RunCMake/Autogen_1/AutogenSkipLinting.cmake
similarity index 100%
rename from Tests/RunCMake/Autogen/AutogenSkipLinting.cmake
rename to Tests/RunCMake/Autogen_1/AutogenSkipLinting.cmake
diff --git a/Tests/RunCMake/Autogen/AutogenUseSystemIncludeCommon.cmake b/Tests/RunCMake/Autogen_1/AutogenUseSystemIncludeCommon.cmake
similarity index 100%
rename from Tests/RunCMake/Autogen/AutogenUseSystemIncludeCommon.cmake
rename to Tests/RunCMake/Autogen_1/AutogenUseSystemIncludeCommon.cmake
diff --git a/Tests/RunCMake/Autogen/AutogenUseSystemIncludeOff.cmake b/Tests/RunCMake/Autogen_1/AutogenUseSystemIncludeOff.cmake
similarity index 100%
rename from Tests/RunCMake/Autogen/AutogenUseSystemIncludeOff.cmake
rename to Tests/RunCMake/Autogen_1/AutogenUseSystemIncludeOff.cmake
diff --git a/Tests/RunCMake/Autogen/AutogenUseSystemIncludeOn.cmake b/Tests/RunCMake/Autogen_1/AutogenUseSystemIncludeOn.cmake
similarity index 100%
rename from Tests/RunCMake/Autogen/AutogenUseSystemIncludeOn.cmake
rename to Tests/RunCMake/Autogen_1/AutogenUseSystemIncludeOn.cmake
diff --git a/Tests/RunCMake/Autogen/CMP0111-imported-target-full.cmake b/Tests/RunCMake/Autogen_1/CMP0111-imported-target-full.cmake
similarity index 100%
rename from Tests/RunCMake/Autogen/CMP0111-imported-target-full.cmake
rename to Tests/RunCMake/Autogen_1/CMP0111-imported-target-full.cmake
diff --git a/Tests/RunCMake/Autogen/CMP0111-imported-target-implib-only.cmake b/Tests/RunCMake/Autogen_1/CMP0111-imported-target-implib-only.cmake
similarity index 100%
rename from Tests/RunCMake/Autogen/CMP0111-imported-target-implib-only.cmake
rename to Tests/RunCMake/Autogen_1/CMP0111-imported-target-implib-only.cmake
diff --git a/Tests/RunCMake/Autogen/CMP0111-imported-target-libname.cmake b/Tests/RunCMake/Autogen_1/CMP0111-imported-target-libname.cmake
similarity index 100%
rename from Tests/RunCMake/Autogen/CMP0111-imported-target-libname.cmake
rename to Tests/RunCMake/Autogen_1/CMP0111-imported-target-libname.cmake
diff --git a/Tests/RunCMake/Autogen/CMP0111-imported-target-prelude.cmake b/Tests/RunCMake/Autogen_1/CMP0111-imported-target-prelude.cmake
similarity index 100%
rename from Tests/RunCMake/Autogen/CMP0111-imported-target-prelude.cmake
rename to Tests/RunCMake/Autogen_1/CMP0111-imported-target-prelude.cmake
diff --git a/Tests/RunCMake/Autogen/CMP0151-common.cmake b/Tests/RunCMake/Autogen_1/CMP0151-common.cmake
similarity index 100%
rename from Tests/RunCMake/Autogen/CMP0151-common.cmake
rename to Tests/RunCMake/Autogen_1/CMP0151-common.cmake
diff --git a/Tests/RunCMake/Autogen/CMP0151-new.cmake b/Tests/RunCMake/Autogen_1/CMP0151-new.cmake
similarity index 100%
rename from Tests/RunCMake/Autogen/CMP0151-new.cmake
rename to Tests/RunCMake/Autogen_1/CMP0151-new.cmake
diff --git a/Tests/RunCMake/Autogen/CMP0151-old.cmake b/Tests/RunCMake/Autogen_1/CMP0151-old.cmake
similarity index 100%
rename from Tests/RunCMake/Autogen/CMP0151-old.cmake
rename to Tests/RunCMake/Autogen_1/CMP0151-old.cmake
diff --git a/Tests/RunCMake/Autogen/CMakeLists.txt b/Tests/RunCMake/Autogen_1/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/Autogen/CMakeLists.txt
rename to Tests/RunCMake/Autogen_1/CMakeLists.txt
diff --git a/Tests/RunCMake/Autogen/Inspect.cmake b/Tests/RunCMake/Autogen_1/Inspect.cmake
similarity index 100%
rename from Tests/RunCMake/Autogen/Inspect.cmake
rename to Tests/RunCMake/Autogen_1/Inspect.cmake
diff --git a/Tests/RunCMake/Autogen/MocGeneratedFile.cmake b/Tests/RunCMake/Autogen_1/MocGeneratedFile.cmake
similarity index 100%
rename from Tests/RunCMake/Autogen/MocGeneratedFile.cmake
rename to Tests/RunCMake/Autogen_1/MocGeneratedFile.cmake
diff --git a/Tests/RunCMake/Autogen/MocPredefs-build-stderr.txt b/Tests/RunCMake/Autogen_1/MocPredefs-build-stderr.txt
similarity index 100%
rename from Tests/RunCMake/Autogen/MocPredefs-build-stderr.txt
rename to Tests/RunCMake/Autogen_1/MocPredefs-build-stderr.txt
diff --git a/Tests/RunCMake/Autogen/MocPredefs-check.cxx b/Tests/RunCMake/Autogen_1/MocPredefs-check.cxx
similarity index 100%
rename from Tests/RunCMake/Autogen/MocPredefs-check.cxx
rename to Tests/RunCMake/Autogen_1/MocPredefs-check.cxx
diff --git a/Tests/RunCMake/Autogen/MocPredefs-prefix.cmake b/Tests/RunCMake/Autogen_1/MocPredefs-prefix.cmake
similarity index 100%
rename from Tests/RunCMake/Autogen/MocPredefs-prefix.cmake
rename to Tests/RunCMake/Autogen_1/MocPredefs-prefix.cmake
diff --git a/Tests/RunCMake/Autogen/MocPredefs.cmake b/Tests/RunCMake/Autogen_1/MocPredefs.cmake
similarity index 100%
rename from Tests/RunCMake/Autogen/MocPredefs.cmake
rename to Tests/RunCMake/Autogen_1/MocPredefs.cmake
diff --git a/Tests/RunCMake/Autogen/MocPredefs.cxx b/Tests/RunCMake/Autogen_1/MocPredefs.cxx
similarity index 100%
rename from Tests/RunCMake/Autogen/MocPredefs.cxx
rename to Tests/RunCMake/Autogen_1/MocPredefs.cxx
diff --git a/Tests/RunCMake/Autogen/NoQt-stderr.txt b/Tests/RunCMake/Autogen_1/NoQt-stderr.txt
similarity index 100%
rename from Tests/RunCMake/Autogen/NoQt-stderr.txt
rename to Tests/RunCMake/Autogen_1/NoQt-stderr.txt
diff --git a/Tests/RunCMake/Autogen/NoQt.cmake b/Tests/RunCMake/Autogen_1/NoQt.cmake
similarity index 100%
rename from Tests/RunCMake/Autogen/NoQt.cmake
rename to Tests/RunCMake/Autogen_1/NoQt.cmake
diff --git a/Tests/RunCMake/Autogen/QtInFunction.cmake b/Tests/RunCMake/Autogen_1/QtInFunction.cmake
similarity index 100%
rename from Tests/RunCMake/Autogen/QtInFunction.cmake
rename to Tests/RunCMake/Autogen_1/QtInFunction.cmake
diff --git a/Tests/RunCMake/Autogen/QtInFunctionNested-stderr.txt b/Tests/RunCMake/Autogen_1/QtInFunctionNested-stderr.txt
similarity index 100%
rename from Tests/RunCMake/Autogen/QtInFunctionNested-stderr.txt
rename to Tests/RunCMake/Autogen_1/QtInFunctionNested-stderr.txt
diff --git a/Tests/RunCMake/Autogen/QtInFunctionNested.cmake b/Tests/RunCMake/Autogen_1/QtInFunctionNested.cmake
similarity index 100%
rename from Tests/RunCMake/Autogen/QtInFunctionNested.cmake
rename to Tests/RunCMake/Autogen_1/QtInFunctionNested.cmake
diff --git a/Tests/RunCMake/Autogen/QtInFunctionProperty.cmake b/Tests/RunCMake/Autogen_1/QtInFunctionProperty.cmake
similarity index 100%
rename from Tests/RunCMake/Autogen/QtInFunctionProperty.cmake
rename to Tests/RunCMake/Autogen_1/QtInFunctionProperty.cmake
diff --git a/Tests/RunCMake/Autogen_1/RunCMakeTest.cmake b/Tests/RunCMake/Autogen_1/RunCMakeTest.cmake
new file mode 100644
index 0000000..64add97
--- /dev/null
+++ b/Tests/RunCMake/Autogen_1/RunCMakeTest.cmake
@@ -0,0 +1,125 @@
+include(RunCMake)
+
+run_cmake(NoQt)
+if (DEFINED with_qt_version)
+  set(RunCMake_TEST_OPTIONS
+    -Dwith_qt_version=${with_qt_version}
+    "-DQt${with_qt_version}_DIR:PATH=${Qt${with_qt_version}_DIR}"
+    "-DCMAKE_PREFIX_PATH:STRING=${CMAKE_PREFIX_PATH}"
+  )
+
+  run_cmake(QtInFunction)
+  run_cmake(QtInFunctionNested)
+  run_cmake(QtInFunctionProperty)
+
+  run_cmake(CMP0111-imported-target-full)
+  run_cmake(CMP0111-imported-target-libname)
+  run_cmake(CMP0111-imported-target-implib-only)
+
+  block()
+    set(RunCMake_TEST_BINARY_DIR  ${RunCMake_BINARY_DIR}/MocPredefs-build)
+    run_cmake(MocPredefs)
+    set(RunCMake_TEST_NO_CLEAN 1)
+    run_cmake_command(MocPredefs-build ${CMAKE_COMMAND} --build . --config Debug)
+  endblock()
+
+  # Detect information from the toolchain:
+  # - CMAKE_INCLUDE_FLAG_CXX
+  # - CMAKE_INCLUDE_SYSTEM_FLAG_CXX
+  run_cmake(Inspect)
+  include("${RunCMake_BINARY_DIR}/Inspect-build/info.cmake")
+
+  if(CMAKE_INCLUDE_SYSTEM_FLAG_CXX)
+    if(RunCMake_GENERATOR MATCHES "Visual Studio")
+      string(REGEX REPLACE "^-" "/" test_expect_stdout "${CMAKE_INCLUDE_SYSTEM_FLAG_CXX}")
+    else()
+      set(test_expect_stdout "-*${CMAKE_INCLUDE_SYSTEM_FLAG_CXX}")
+    endif()
+    string(APPEND test_expect_stdout " *(\"[^\"]*|([^ ]|\\ )*)[\\/]dummy_autogen[\\/]include")
+    if(RunCMake_GENERATOR_IS_MULTI_CONFIG)
+      string(APPEND test_expect_stdout "_Debug")
+    endif()
+
+    block()
+      set(RunCMake_TEST_BINARY_DIR  ${RunCMake_BINARY_DIR}/CMP0151-new-build)
+      run_cmake_with_options(CMP0151-new ${RunCMake_TEST_OPTIONS} -DCMAKE_POLICY_DEFAULT_CMP0151=NEW)
+      set(RunCMake_TEST_NO_CLEAN 1)
+      set(RunCMake_TEST_EXPECT_stdout "${test_expect_stdout}")
+      run_cmake_command(CMP0151-new-build ${CMAKE_COMMAND} --build . --config Debug --verbose)
+    endblock()
+
+    block()
+      set(RunCMake_TEST_BINARY_DIR  ${RunCMake_BINARY_DIR}/AutogenUseSystemIncludeOn-build)
+      run_cmake_with_options(AutogenUseSystemIncludeOn ${RunCMake_TEST_OPTIONS} -DCMAKE_POLICY_DEFAULT_CMP0151=NEW)
+      set(RunCMake_TEST_NO_CLEAN 1)
+      set(RunCMake_TEST_EXPECT_stdout "${test_expect_stdout}")
+      run_cmake_command(AutogenUseSystemIncludeOn ${CMAKE_COMMAND} --build . --config Debug --verbose)
+    endblock()
+  endif()
+
+  if(CMAKE_INCLUDE_FLAG_CXX)
+    if(RunCMake_GENERATOR MATCHES "Visual Studio")
+      string(REGEX REPLACE "^-" "/" test_expect_stdout "${CMAKE_INCLUDE_FLAG_CXX}")
+    else()
+      set(test_expect_stdout "-*${CMAKE_INCLUDE_FLAG_CXX}")
+    endif()
+    string(APPEND test_expect_stdout " *(\"[^\"]*|([^ ]|\\ )*)[\\/]dummy_autogen[\\/]include")
+    if(RunCMake_GENERATOR_IS_MULTI_CONFIG)
+      string(APPEND test_expect_stdout "_Debug")
+    endif()
+
+    block()
+      set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/CMP0151-old-build)
+      run_cmake_with_options(CMP0151-old ${RunCMake_TEST_OPTIONS} -DCMAKE_POLICY_DEFAULT_CMP0151=OLD)
+      set(RunCMake_TEST_NO_CLEAN 1)
+      set(RunCMake_TEST_EXPECT_stdout "${test_expect_stdout}")
+      run_cmake_command(CMP0151-old-build ${CMAKE_COMMAND} --build . --config Debug --verbose)
+    endblock()
+
+    block()
+      set(RunCMake_TEST_BINARY_DIR  ${RunCMake_BINARY_DIR}/AutogenUseSystemIncludeOff-build)
+      run_cmake_with_options(AutogenUseSystemIncludeOff ${RunCMake_TEST_OPTIONS} -DCMAKE_POLICY_DEFAULT_CMP0151=NEW)
+      set(RunCMake_TEST_NO_CLEAN 1)
+      set(RunCMake_TEST_EXPECT_stdout "${test_expect_stdout}")
+      run_cmake_command(AutogenUseSystemIncludeOff ${CMAKE_COMMAND} --build . --config Debug --verbose)
+    endblock()
+
+    if(RunCMake_GENERATOR MATCHES "Make|Ninja")
+      block()
+        set(RunCMake_TEST_BINARY_DIR  ${RunCMake_BINARY_DIR}/AutogenSkipLinting-build)
+        list(APPEND RunCMake_TEST_OPTIONS
+          "-DPSEUDO_CPPCHECK=${PSEUDO_CPPCHECK}"
+          "-DPSEUDO_CPPLINT=${PSEUDO_CPPLINT}"
+          "-DPSEUDO_IWYU=${PSEUDO_IWYU}"
+          "-DPSEUDO_TIDY=${PSEUDO_TIDY}")
+
+        run_cmake(AutogenSkipLinting)
+        set(RunCMake_TEST_NO_CLEAN 1)
+        run_cmake_command(AutogenSkipLinting-build ${CMAKE_COMMAND} --build . --config Debug --verbose)
+      endblock()
+    endif()
+  endif()
+
+  if(RunCMake_GENERATOR_IS_MULTI_CONFIG AND NOT RunCMake_GENERATOR MATCHES "Xcode")
+    block()
+      set(RunCMake_TEST_BINARY_DIR  ${RunCMake_BINARY_DIR}/MocGeneratedFile-build)
+      run_cmake(MocGeneratedFile)
+      set(RunCMake_TEST_NO_CLEAN 1)
+      run_cmake_command(MocGeneratedFile-build ${CMAKE_COMMAND} --build . --config Debug --verbose)
+    endblock()
+    if(RunCMake_GENERATOR MATCHES "Ninja Multi-Config")
+      block()
+        set(RunCMake_TEST_BINARY_DIR  ${RunCMake_BINARY_DIR}/MocGeneratedFile-cross-config-build)
+        list(APPEND RunCMake_TEST_OPTIONS -DCMAKE_CROSS_CONFIGS=all)
+        set(RunCMake_TEST_VARIANT_DESCRIPTION "-CMAKE_CROSS_CONFIGS-all")
+        run_cmake(MocGeneratedFile)
+        set(RunCMake_TEST_NO_CLEAN 1)
+        set(RunCMake_TEST_VARIANT_DESCRIPTION "-Release")
+        run_cmake_command(MocGeneratedFile-cross-config-build ${CMAKE_COMMAND} --build . --config Release --target libgen:Debug)
+        set(RunCMake_TEST_VARIANT_DESCRIPTION "-Debug")
+        run_cmake_command(MocGeneratedFile-cross-config-build ${CMAKE_COMMAND} --build . --config Debug --target libgen:Release)
+        unset(RunCMake_TEST_VARIANT_DESCRIPTION)
+      endblock()
+    endif()
+  endif()
+endif ()
diff --git a/Tests/RunCMake/Autogen/SkipLinting.cxx b/Tests/RunCMake/Autogen_1/SkipLinting.cxx
similarity index 100%
rename from Tests/RunCMake/Autogen/SkipLinting.cxx
rename to Tests/RunCMake/Autogen_1/SkipLinting.cxx
diff --git a/Tests/RunCMake/Autogen/SkipLinting.h b/Tests/RunCMake/Autogen_1/SkipLinting.h
similarity index 100%
rename from Tests/RunCMake/Autogen/SkipLinting.h
rename to Tests/RunCMake/Autogen_1/SkipLinting.h
diff --git a/Tests/RunCMake/Autogen/empty.cpp b/Tests/RunCMake/Autogen_1/empty.cpp
similarity index 100%
rename from Tests/RunCMake/Autogen/empty.cpp
rename to Tests/RunCMake/Autogen_1/empty.cpp
diff --git a/Tests/RunCMake/Autogen/CMakeLists.txt b/Tests/RunCMake/Autogen_2/CMakeLists.txt
similarity index 100%
copy from Tests/RunCMake/Autogen/CMakeLists.txt
copy to Tests/RunCMake/Autogen_2/CMakeLists.txt
diff --git a/Tests/RunCMake/Autogen/MyWindow.cpp b/Tests/RunCMake/Autogen_2/MyWindow.cpp
similarity index 100%
rename from Tests/RunCMake/Autogen/MyWindow.cpp
rename to Tests/RunCMake/Autogen_2/MyWindow.cpp
diff --git a/Tests/RunCMake/Autogen/MyWindow.h b/Tests/RunCMake/Autogen_2/MyWindow.h
similarity index 100%
rename from Tests/RunCMake/Autogen/MyWindow.h
rename to Tests/RunCMake/Autogen_2/MyWindow.h
diff --git a/Tests/RunCMake/Autogen/MyWindow.ui b/Tests/RunCMake/Autogen_2/MyWindow.ui
similarity index 100%
rename from Tests/RunCMake/Autogen/MyWindow.ui
rename to Tests/RunCMake/Autogen_2/MyWindow.ui
diff --git a/Tests/RunCMake/Autogen/QtAutoMocDeps-stderr.txt b/Tests/RunCMake/Autogen_2/QtAutoMocDeps-stderr.txt
similarity index 100%
rename from Tests/RunCMake/Autogen/QtAutoMocDeps-stderr.txt
rename to Tests/RunCMake/Autogen_2/QtAutoMocDeps-stderr.txt
diff --git a/Tests/RunCMake/Autogen/QtAutoMocDeps.cmake b/Tests/RunCMake/Autogen_2/QtAutoMocDeps.cmake
similarity index 100%
rename from Tests/RunCMake/Autogen/QtAutoMocDeps.cmake
rename to Tests/RunCMake/Autogen_2/QtAutoMocDeps.cmake
diff --git a/Tests/RunCMake/Autogen/QtSubDir1/CMakeLists.txt b/Tests/RunCMake/Autogen_2/QtSubDir1/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/Autogen/QtSubDir1/CMakeLists.txt
rename to Tests/RunCMake/Autogen_2/QtSubDir1/CMakeLists.txt
diff --git a/Tests/RunCMake/Autogen/QtSubDir2/CMakeLists.txt b/Tests/RunCMake/Autogen_2/QtSubDir2/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/Autogen/QtSubDir2/CMakeLists.txt
rename to Tests/RunCMake/Autogen_2/QtSubDir2/CMakeLists.txt
diff --git a/Tests/RunCMake/Autogen/QtSubDir3/CMakeLists.txt b/Tests/RunCMake/Autogen_2/QtSubDir3/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/Autogen/QtSubDir3/CMakeLists.txt
rename to Tests/RunCMake/Autogen_2/QtSubDir3/CMakeLists.txt
diff --git a/Tests/RunCMake/Autogen_2/RunCMakeTest.cmake b/Tests/RunCMake/Autogen_2/RunCMakeTest.cmake
new file mode 100644
index 0000000..e97e896
--- /dev/null
+++ b/Tests/RunCMake/Autogen_2/RunCMakeTest.cmake
@@ -0,0 +1,87 @@
+include(RunCMake)
+
+if (DEFINED with_qt_version)
+  set(RunCMake_TEST_OPTIONS
+    -Dwith_qt_version=${with_qt_version}
+    "-DQt${with_qt_version}_DIR:PATH=${Qt${with_qt_version}_DIR}"
+    "-DCMAKE_PREFIX_PATH:STRING=${CMAKE_PREFIX_PATH}"
+  )
+  if(RunCMake_GENERATOR MATCHES "Make|Ninja")
+    block()
+      if(QtCore_VERSION VERSION_GREATER_EQUAL 5.15.0)
+        if (RunCMake_GENERATOR MATCHES "Ninja Multi-Config")
+          set(config_list Debug Release RelWithDebInfo)
+          set(use_better_graph_list ON OFF)
+        else()
+          set(config_list single-config)
+          set(use_better_graph_list OFF)
+        endif()
+
+        foreach(use_better_graph IN ITEMS ${use_better_graph_list})
+          foreach(config IN ITEMS ${config_list})
+            block()
+              if (config STREQUAL "single-config")
+                set(config_suffix "")
+              else()
+                set(config_path "_${config}")
+                if (use_better_graph)
+                  set(config_suffix "_${config}")
+                endif()
+              endif()
+
+              set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/QtAutoMocDeps${config_path}-build)
+              run_cmake_with_options(QtAutoMocDeps ${RunCMake_TEST_OPTIONS} -DCMAKE_AUTOGEN_BETTER_GRAPH_MULTI_CONFIG=${use_better_graph})
+              set(RunCMake_TEST_NO_CLEAN 1)
+              # Build the project.
+              if (config STREQUAL "single-config")
+                set(config_param "")
+              else()
+                set(config_param "--config ${config}")
+              endif()
+              run_cmake_command(QtAutoMocDeps-build ${CMAKE_COMMAND} --build . --verbose ${config_param})
+              # Touch just the library source file, which shouldn't cause a rerun of AUTOMOC
+              # for app_with_qt target.
+              file(TOUCH "${RunCMake_SOURCE_DIR}/simple_lib.cpp")
+              set(RunCMake_TEST_NOT_EXPECT_stdout "Automatic MOC for target app_with_qt|\
+Automatic MOC for target sub_exe_1|\
+Automatic MOC for target sub_exe_2")
+              set(RunCMake_TEST_VARIANT_DESCRIPTION "-Don't execute AUTOMOC for 'app_with_qt', 'sub_exe_1' and 'sub_exe_2'")
+              # Build and assert that AUTOMOC was not run for app_with_qt, sub_exe_1 and sub_exe_2.
+              run_cmake_command(QtAutoMocDeps-build ${CMAKE_COMMAND} --build . --verbose ${config_param})
+              unset(RunCMake_TEST_VARIANT_DESCRIPTION)
+              unset(RunCMake_TEST_NOT_EXPECT_stdout)
+
+              macro(check_file_exists file)
+                if (EXISTS "${file}")
+                  set(check_result "PASSED")
+                  set(message_type "STATUS")
+                else()
+                  set(check_result "FAILED")
+                  set(message_type "FATAL_ERROR")
+                endif()
+
+                message(${message_type} "QtAutoMocDeps-build-\"${file}\" was generated - ${check_result}")
+              endmacro()
+
+              check_file_exists("${RunCMake_TEST_BINARY_DIR}/app_with_qt_autogen/deps${config_suffix}")
+              check_file_exists("${RunCMake_TEST_BINARY_DIR}/QtSubDir1/sub_exe_1_autogen/deps${config_suffix}")
+              check_file_exists("${RunCMake_TEST_BINARY_DIR}/QtSubDir2/sub_exe_2_autogen/deps${config_suffix}")
+
+              check_file_exists("${RunCMake_TEST_BINARY_DIR}/app_with_qt_autogen/timestamp${config_suffix}")
+              check_file_exists("${RunCMake_TEST_BINARY_DIR}/QtSubDir1/sub_exe_1_autogen/timestamp${config_suffix}")
+              check_file_exists("${RunCMake_TEST_BINARY_DIR}/QtSubDir2/sub_exe_2_autogen/timestamp${config_suffix}")
+
+              # Touch a header file to make sure an automoc dependency cycle is not introduced.
+              file(TOUCH "${RunCMake_SOURCE_DIR}/MyWindow.h")
+              set(RunCMake_TEST_VARIANT_DESCRIPTION "-First build after touch to detect dependency cycle")
+              run_cmake_command(QtAutoMocDeps-build ${CMAKE_COMMAND} --build . --verbose)
+              # Need to run a second time to hit the dependency cycle.
+              set(RunCMake_TEST_VARIANT_DESCRIPTION "-Don't hit dependency cycle")
+              run_cmake_command(QtAutoMocDeps-build ${CMAKE_COMMAND} --build . --verbose)
+            endblock()
+          endforeach()
+        endforeach()
+      endif()
+    endblock()
+  endif()
+endif ()
diff --git a/Tests/RunCMake/Autogen/app.cpp b/Tests/RunCMake/Autogen_2/app.cpp
similarity index 100%
rename from Tests/RunCMake/Autogen/app.cpp
rename to Tests/RunCMake/Autogen_2/app.cpp
diff --git a/Tests/RunCMake/Autogen/app_qt.cpp b/Tests/RunCMake/Autogen_2/app_qt.cpp
similarity index 100%
rename from Tests/RunCMake/Autogen/app_qt.cpp
rename to Tests/RunCMake/Autogen_2/app_qt.cpp
diff --git a/Tests/RunCMake/Autogen/simple_lib.cpp b/Tests/RunCMake/Autogen_2/simple_lib.cpp
similarity index 100%
rename from Tests/RunCMake/Autogen/simple_lib.cpp
rename to Tests/RunCMake/Autogen_2/simple_lib.cpp
diff --git a/Tests/RunCMake/Autogen/AutoMocExecutableConfig.cmake b/Tests/RunCMake/Autogen_3/AutoMocExecutableConfig.cmake
similarity index 62%
rename from Tests/RunCMake/Autogen/AutoMocExecutableConfig.cmake
rename to Tests/RunCMake/Autogen_3/AutoMocExecutableConfig.cmake
index 3ee9be9..fc6ed7f 100644
--- a/Tests/RunCMake/Autogen/AutoMocExecutableConfig.cmake
+++ b/Tests/RunCMake/Autogen_3/AutoMocExecutableConfig.cmake
@@ -7,9 +7,9 @@
 get_target_property(moc_location Qt${with_qt_version}::moc IMPORTED_LOCATION)
 set_target_properties(dummy PROPERTIES AUTOMOC_MOC_OPTIONS "EXE_PATH=${moc_location}")
 
-add_executable(mymoc $<$<CONFIG:Debug>:exe_debug.cpp>
-                     $<$<CONFIG:Release>:exe_release.cpp>
-                     $<$<CONFIG:RelWithDebInfo>:exe_relwithdebinfo.cpp>
+add_executable(mymoc $<$<CONFIG:Debug>:../Autogen_common/exe_debug.cpp>
+                     $<$<CONFIG:Release>:../Autogen_common/exe_release.cpp>
+                     $<$<CONFIG:RelWithDebInfo>:../Autogen_common/exe_relwithdebinfo.cpp>
 )
 
 set_target_properties(dummy PROPERTIES AUTOMOC_EXECUTABLE $<TARGET_FILE:mymoc>)
diff --git a/Tests/RunCMake/Autogen/CMakeLists.txt b/Tests/RunCMake/Autogen_3/CMakeLists.txt
similarity index 100%
copy from Tests/RunCMake/Autogen/CMakeLists.txt
copy to Tests/RunCMake/Autogen_3/CMakeLists.txt
diff --git a/Tests/RunCMake/Autogen/MocExample.cmake b/Tests/RunCMake/Autogen_3/MocExample.cmake
similarity index 85%
rename from Tests/RunCMake/Autogen/MocExample.cmake
rename to Tests/RunCMake/Autogen_3/MocExample.cmake
index f06f8f6..b4f4729 100644
--- a/Tests/RunCMake/Autogen/MocExample.cmake
+++ b/Tests/RunCMake/Autogen_3/MocExample.cmake
@@ -3,7 +3,7 @@
 set(CMAKE_CXX_STANDARD 11)
 find_package(Qt${with_qt_version} REQUIRED COMPONENTS Core Widgets Gui)
 
-add_library(dummy STATIC example.cpp)
+add_library(dummy STATIC ../Autogen_common/example.cpp)
 target_link_libraries(dummy Qt${with_qt_version}::Core
                             Qt${with_qt_version}::Widgets
                             Qt${with_qt_version}::Gui)
diff --git a/Tests/RunCMake/Autogen_3/RunCMakeTest.cmake b/Tests/RunCMake/Autogen_3/RunCMakeTest.cmake
new file mode 100644
index 0000000..a2fb3df
--- /dev/null
+++ b/Tests/RunCMake/Autogen_3/RunCMakeTest.cmake
@@ -0,0 +1,11 @@
+include(RunCMake)
+include(Autogen_common/utils)
+
+if (DEFINED with_qt_version)
+  set(RunCMake_TEST_OPTIONS
+    -Dwith_qt_version=${with_qt_version}
+    "-DQt${with_qt_version}_DIR:PATH=${Qt${with_qt_version}_DIR}"
+    "-DCMAKE_PREFIX_PATH:STRING=${CMAKE_PREFIX_PATH}"
+  )
+  autogen_executable_test(Moc)
+endif ()
diff --git a/Tests/RunCMake/Autogen/AutoUicExecutableConfig.cmake b/Tests/RunCMake/Autogen_4/AutoUicExecutableConfig.cmake
similarity index 61%
rename from Tests/RunCMake/Autogen/AutoUicExecutableConfig.cmake
rename to Tests/RunCMake/Autogen_4/AutoUicExecutableConfig.cmake
index 55b88b8..72a0d9f 100644
--- a/Tests/RunCMake/Autogen/AutoUicExecutableConfig.cmake
+++ b/Tests/RunCMake/Autogen_4/AutoUicExecutableConfig.cmake
@@ -7,9 +7,9 @@
 get_target_property(uic_location Qt${with_qt_version}::uic IMPORTED_LOCATION)
 set_target_properties(dummy PROPERTIES AUTOUIC_OPTIONS "EXE_PATH=${uic_location}")
 
-add_executable(myuic $<$<CONFIG:Debug>:exe_debug.cpp>
-                     $<$<CONFIG:Release>:exe_release.cpp>
-                     $<$<CONFIG:RelWithDebInfo>:exe_relwithdebinfo.cpp>
+add_executable(myuic $<$<CONFIG:Debug>:../Autogen_common/exe_debug.cpp>
+                     $<$<CONFIG:Release>:../Autogen_common/exe_release.cpp>
+                     $<$<CONFIG:RelWithDebInfo>:../Autogen_common/exe_relwithdebinfo.cpp>
 )
 
 set_target_properties(dummy PROPERTIES AUTOUIC_EXECUTABLE $<TARGET_FILE:myuic>)
diff --git a/Tests/RunCMake/Autogen/CMakeLists.txt b/Tests/RunCMake/Autogen_4/CMakeLists.txt
similarity index 100%
copy from Tests/RunCMake/Autogen/CMakeLists.txt
copy to Tests/RunCMake/Autogen_4/CMakeLists.txt
diff --git a/Tests/RunCMake/Autogen_4/RunCMakeTest.cmake b/Tests/RunCMake/Autogen_4/RunCMakeTest.cmake
new file mode 100644
index 0000000..ac8c5d4
--- /dev/null
+++ b/Tests/RunCMake/Autogen_4/RunCMakeTest.cmake
@@ -0,0 +1,11 @@
+include(RunCMake)
+include(Autogen_common/utils)
+
+if (DEFINED with_qt_version)
+  set(RunCMake_TEST_OPTIONS
+    -Dwith_qt_version=${with_qt_version}
+    "-DQt${with_qt_version}_DIR:PATH=${Qt${with_qt_version}_DIR}"
+    "-DCMAKE_PREFIX_PATH:STRING=${CMAKE_PREFIX_PATH}"
+  )
+  autogen_executable_test(Uic)
+endif ()
diff --git a/Tests/RunCMake/Autogen/UicExample.cmake b/Tests/RunCMake/Autogen_4/UicExample.cmake
similarity index 100%
rename from Tests/RunCMake/Autogen/UicExample.cmake
rename to Tests/RunCMake/Autogen_4/UicExample.cmake
diff --git a/Tests/RunCMake/Autogen/example_ui.cpp b/Tests/RunCMake/Autogen_4/example_ui.cpp
similarity index 100%
rename from Tests/RunCMake/Autogen/example_ui.cpp
rename to Tests/RunCMake/Autogen_4/example_ui.cpp
diff --git a/Tests/RunCMake/Autogen/example_ui.h b/Tests/RunCMake/Autogen_4/example_ui.h
similarity index 100%
rename from Tests/RunCMake/Autogen/example_ui.h
rename to Tests/RunCMake/Autogen_4/example_ui.h
diff --git a/Tests/RunCMake/Autogen/uiA.ui b/Tests/RunCMake/Autogen_4/uiA.ui
similarity index 100%
rename from Tests/RunCMake/Autogen/uiA.ui
rename to Tests/RunCMake/Autogen_4/uiA.ui
diff --git a/Tests/RunCMake/Autogen/AutoRccExecutableConfig.cmake b/Tests/RunCMake/Autogen_5/AutoRccExecutableConfig.cmake
similarity index 61%
rename from Tests/RunCMake/Autogen/AutoRccExecutableConfig.cmake
rename to Tests/RunCMake/Autogen_5/AutoRccExecutableConfig.cmake
index 0e46420..b15dd72 100644
--- a/Tests/RunCMake/Autogen/AutoRccExecutableConfig.cmake
+++ b/Tests/RunCMake/Autogen_5/AutoRccExecutableConfig.cmake
@@ -7,9 +7,9 @@
 get_target_property(rcc_location Qt${with_qt_version}::rcc IMPORTED_LOCATION)
 set_target_properties(dummy PROPERTIES AUTORCC_OPTIONS "EXE_PATH=${rcc_location}")
 
-add_executable(myrcc $<$<CONFIG:Debug>:exe_debug.cpp>
-                     $<$<CONFIG:Release>:exe_release.cpp>
-                     $<$<CONFIG:RelWithDebInfo>:exe_relwithdebinfo.cpp>
+add_executable(myrcc $<$<CONFIG:Debug>:../Autogen_common/exe_debug.cpp>
+                     $<$<CONFIG:Release>:../Autogen_common/exe_release.cpp>
+                     $<$<CONFIG:RelWithDebInfo>:../Autogen_common/exe_relwithdebinfo.cpp>
 )
 
 set_target_properties(dummy PROPERTIES AUTORCC_EXECUTABLE $<TARGET_FILE:myrcc>)
diff --git a/Tests/RunCMake/Autogen/CMakeLists.txt b/Tests/RunCMake/Autogen_5/CMakeLists.txt
similarity index 100%
copy from Tests/RunCMake/Autogen/CMakeLists.txt
copy to Tests/RunCMake/Autogen_5/CMakeLists.txt
diff --git a/Tests/RunCMake/Autogen/RccExample.cmake b/Tests/RunCMake/Autogen_5/RccExample.cmake
similarity index 86%
rename from Tests/RunCMake/Autogen/RccExample.cmake
rename to Tests/RunCMake/Autogen_5/RccExample.cmake
index ade0fef..9f8dc59 100644
--- a/Tests/RunCMake/Autogen/RccExample.cmake
+++ b/Tests/RunCMake/Autogen_5/RccExample.cmake
@@ -3,7 +3,7 @@
 set(CMAKE_CXX_STANDARD 11)
 find_package(Qt${with_qt_version} REQUIRED COMPONENTS Core Widgets Gui)
 
-add_library(dummy STATIC example.cpp data.qrc)
+add_library(dummy STATIC ../Autogen_common/example.cpp data.qrc)
 target_link_libraries(dummy Qt${with_qt_version}::Core
                             Qt${with_qt_version}::Widgets
                             Qt${with_qt_version}::Gui)
diff --git a/Tests/RunCMake/Autogen_5/RunCMakeTest.cmake b/Tests/RunCMake/Autogen_5/RunCMakeTest.cmake
new file mode 100644
index 0000000..8060ec4
--- /dev/null
+++ b/Tests/RunCMake/Autogen_5/RunCMakeTest.cmake
@@ -0,0 +1,31 @@
+include(RunCMake)
+include(Autogen_common/utils)
+
+if (DEFINED with_qt_version)
+  set(RunCMake_TEST_OPTIONS
+    -Dwith_qt_version=${with_qt_version}
+    "-DQt${with_qt_version}_DIR:PATH=${Qt${with_qt_version}_DIR}"
+    "-DCMAKE_PREFIX_PATH:STRING=${CMAKE_PREFIX_PATH}"
+  )
+  autogen_executable_test(Rcc)
+  if (QtCore_VERSION VERSION_GREATER_EQUAL 6)
+    if (RunCMake_GENERATOR MATCHES "Make|Ninja")
+      foreach(value IN ITEMS ON OFF)
+        block()
+          set(RunCMake_TEST_BINARY_DIR
+            ${RunCMake_BINARY_DIR}/RccNoZTSD-${value}-build)
+          run_cmake_with_options(RccExample ${RunCMake_TEST_OPTIONS}
+            -DCMAKE_AUTOGEN_VERBOSE=ON -DZSTD_VALUE=${value})
+          if (value STREQUAL "OFF")
+            set(RunCMake_TEST_EXPECT_stdout "--no-zstd")
+          else()
+            set(RunCMake_TEST_NOT_EXPECT_stdout "--no-zstd")
+          endif()
+          set(RunCMake_TEST_NO_CLEAN 1)
+          run_cmake_command(RccNoZTSD-${value}-build ${CMAKE_COMMAND}
+            --build . --config Debug)
+        endblock()
+      endforeach()
+    endif()
+  endif()
+endif ()
diff --git a/Tests/RunCMake/Autogen/data.qrc b/Tests/RunCMake/Autogen_5/data.qrc
similarity index 100%
rename from Tests/RunCMake/Autogen/data.qrc
rename to Tests/RunCMake/Autogen_5/data.qrc
diff --git a/Tests/RunCMake/Autogen/example.cpp b/Tests/RunCMake/Autogen_common/example.cpp
similarity index 100%
rename from Tests/RunCMake/Autogen/example.cpp
rename to Tests/RunCMake/Autogen_common/example.cpp
diff --git a/Tests/RunCMake/Autogen/example.h b/Tests/RunCMake/Autogen_common/example.h
similarity index 100%
rename from Tests/RunCMake/Autogen/example.h
rename to Tests/RunCMake/Autogen_common/example.h
diff --git a/Tests/RunCMake/Autogen/exe_common.h b/Tests/RunCMake/Autogen_common/exe_common.h
similarity index 100%
rename from Tests/RunCMake/Autogen/exe_common.h
rename to Tests/RunCMake/Autogen_common/exe_common.h
diff --git a/Tests/RunCMake/Autogen/exe_debug.cpp b/Tests/RunCMake/Autogen_common/exe_debug.cpp
similarity index 100%
rename from Tests/RunCMake/Autogen/exe_debug.cpp
rename to Tests/RunCMake/Autogen_common/exe_debug.cpp
diff --git a/Tests/RunCMake/Autogen/exe_release.cpp b/Tests/RunCMake/Autogen_common/exe_release.cpp
similarity index 100%
rename from Tests/RunCMake/Autogen/exe_release.cpp
rename to Tests/RunCMake/Autogen_common/exe_release.cpp
diff --git a/Tests/RunCMake/Autogen/exe_relwithdebinfo.cpp b/Tests/RunCMake/Autogen_common/exe_relwithdebinfo.cpp
similarity index 100%
rename from Tests/RunCMake/Autogen/exe_relwithdebinfo.cpp
rename to Tests/RunCMake/Autogen_common/exe_relwithdebinfo.cpp
diff --git a/Tests/RunCMake/Autogen_common/utils.cmake b/Tests/RunCMake/Autogen_common/utils.cmake
new file mode 100644
index 0000000..86efa85
--- /dev/null
+++ b/Tests/RunCMake/Autogen_common/utils.cmake
@@ -0,0 +1,259 @@
+function(run_make_program dir)
+  execute_process(
+    COMMAND "${RunCMake_MAKE_PROGRAM}" ${ARGN}
+    WORKING_DIRECTORY "${dir}"
+    OUTPUT_VARIABLE make_program_stdout
+    ERROR_VARIABLE make_program_stderr
+    RESULT_VARIABLE make_program_result
+    )
+    if (NOT DEFINED RunMakeProgram_expected_result)
+      set(RunMakeProgram_expected_result 0)
+    endif()
+    if(NOT "${make_program_result}" MATCHES "${RunMakeProgram_expected_result}")
+      message(STATUS "
+============ beginning of ${RunCMake_MAKE_PROGRAM}'s stdout ============
+${make_program_stdout}
+=============== end of ${RunCMake_MAKE_PROGRAM}'s stdout ===============
+")
+    message(STATUS "
+============ beginning of ${RunCMake_MAKE_PROGRAM}'s stderr ============
+${make_program_stderr}
+=============== end of ${RunCMake_MAKE_PROGRAM}'s stderr ===============
+")
+    message(FATAL_ERROR
+            "top ${RunCMake_MAKE_PROGRAM} build failed exited with status ${make_program_result}")
+    endif()
+  set(make_program_stdout "${make_program_stdout}" PARENT_SCOPE)
+endfunction(run_make_program)
+
+function(count_substring STRING SUBSTRING COUNT_VAR)
+  string(LENGTH "${STRING}" STRING_LENGTH)
+  string(LENGTH "${SUBSTRING}" SUBSTRING_LENGTH)
+  if (SUBSTRING_LENGTH EQUAL 0)
+    message(FATAL_ERROR "SUBSTRING_LENGTH is 0")
+  endif()
+
+  if (STRING_LENGTH EQUAL 0)
+      message(FATAL_ERROR "STRING_LENGTH is 0")
+  endif()
+
+  if (STRING_LENGTH LESS SUBSTRING_LENGTH)
+    message(FATAL_ERROR "STRING_LENGTH is less than SUBSTRING_LENGTH")
+  endif()
+
+  set(COUNT 0)
+  string(FIND "${STRING}" "${SUBSTRING}" SUBSTRING_START)
+  while(SUBSTRING_START GREATER_EQUAL 0)
+    math(EXPR COUNT "${COUNT} + 1")
+    math(EXPR SUBSTRING_START "${SUBSTRING_START} + ${SUBSTRING_LENGTH}")
+    string(SUBSTRING "${STRING}" ${SUBSTRING_START} -1 STRING)
+    string(FIND "${STRING}" "${SUBSTRING}" SUBSTRING_START)
+  endwhile()
+
+  set(${COUNT_VAR} ${COUNT} PARENT_SCOPE)
+endfunction()
+
+function(not_expect make_program_stdout unexpected_output test_name)
+  count_substring("${make_program_stdout}" "${unexpected_output}" count)
+  if(NOT count EQUAL 0)
+    message(STATUS "${test_name}-not_expect - FAILED")
+    message(FATAL_ERROR "Expected to find ${unexpected_output} exactly 0 times in ${make_program_stdout} but found ${count} occurrences of ${unexpected_output}")
+  else()
+    message(STATUS "${test_name}-not_expect - PASSED")
+  endif()
+endfunction()
+
+function(expect_only_once make_program_stdout expected_output test_name)
+  count_substring("${make_program_stdout}" "${expected_output}" count)
+  if(NOT count EQUAL 1)
+    message(STATUS "${test_name}-expect_only_once - FAILED")
+    message(FATAL_ERROR "Expected to find ${expected_output} exactly once in ${make_program_stdout} but found ${count} occurrences of ${expected_output}")
+  else()
+    message(STATUS "${test_name}-expect_only_once - PASSED")
+  endif()
+endfunction()
+
+function(expect_n_times string_to_check expected_output expected_count test_name)
+  count_substring("${string_to_check}" "${expected_output}" count)
+  if(NOT count EQUAL ${expected_count})
+    message(STATUS "${test_name}-expect_${expected_count}_times - FAILED")
+    message(FATAL_ERROR "Expected to find ${expected_output} exactly ${expected_count} times in ${string_to_check} but found ${count} occurrences of ${expected_output}")
+  else()
+    message(STATUS "${test_name}-expect_${expected_count}_times - PASSED")
+  endif()
+endfunction()
+
+function(autogen_executable_test exe)
+  if (QtCore_VERSION VERSION_GREATER_EQUAL 5.15.0)
+    if(RunCMake_GENERATOR MATCHES "Ninja Multi-Config")
+      block()
+        set(RunCMake_TEST_VARIANT_DESCRIPTION "-CMake-configure")
+        set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Auto${exe}ExecutableConfig-multi-config-build)
+        run_cmake_with_options(Auto${exe}ExecutableConfig ${RunCMake_TEST_OPTIONS} -DCMAKE_AUTOGEN_VERBOSE=ON -DCMAKE_AUTOGEN_BETTER_GRAPH_MULTI_CONFIG=ON)
+        unset(RunCMake_TEST_VARIANT_DESCRIPTION)
+        set(RunCMake_TEST_NO_CLEAN 1)
+        foreach(config IN ITEMS Debug Release RelWithDebInfo)
+          block()
+            set(RunCMake_TEST_EXPECT_stdout ".*running_exe_${config}*")
+            set(RunCMake_TEST_VARIANT_DESCRIPTION "-${config}-expect_running_exe_${config}")
+            run_cmake_command(Auto${exe}ExecutableConfig-multi-config-build ${CMAKE_COMMAND} --build . --config ${config})
+          endblock()
+        endforeach()
+        set(RunCMake_TEST_EXPECT_stdout "ninja: no work to do")
+        foreach(config IN ITEMS Debug Release RelWithDebInfo)
+          block()
+          set(RunCMake_TEST_VARIANT_DESCRIPTION "-${config}-expect_no_work_to_do")
+            run_cmake_command(Auto${exe}ExecutableConfig-multi-config-build ${CMAKE_COMMAND} --build . --config ${config})
+          endblock()
+        endforeach()
+      endblock()
+      block()
+        set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Auto${exe}ExecutableConfig-build)
+        run_cmake_with_options(Auto${exe}ExecutableConfig ${RunCMake_TEST_OPTIONS} -DCMAKE_AUTOGEN_VERBOSE=ON -DCMAKE_AUTOGEN_BETTER_GRAPH_MULTI_CONFIG=ON)
+        foreach(config IN ITEMS Debug Release RelWithDebInfo)
+          block()
+            run_make_program(${RunCMake_TEST_BINARY_DIR} --verbose -f build-${config}.ninja)
+
+            set(expected_output "running_exe_${config}")
+            expect_only_once("${make_program_stdout}" "${expected_output}" "Auto${exe}ExecutableConfig-${config}-${expected_output}")
+
+            foreach(sub_config IN ITEMS Debug Release RelWithDebInfo)
+              if(NOT sub_config STREQUAL config)
+                set(unexpected_output "running_exe_${sub_config}")
+                not_expect("${make_program_stdout}" "${unexpected_output}" "Auto${exe}ExecutableConfig-${config}-${unexpected_output}")
+              endif()
+            endforeach()
+
+            if (exe STREQUAL "Moc" OR exe STREQUAL "Uic")
+              set(expected_output "cmake_autogen")
+            else()
+              set(expected_output "cmake_autorcc")
+            endif()
+            expect_only_once("${make_program_stdout}" "${expected_output}" "Auto${exe}ExecutableConfig-${config}-${expected_output}")
+          endblock()
+        endforeach()
+      endblock()
+      block()
+        foreach(ninja_config IN ITEMS Debug Release RelWithDebInfo)
+          foreach(target_config IN ITEMS Debug Release RelWithDebInfo)
+            block()
+              set(TEST_SUFFIX "-CrossConfig-${ninja_config}-${target_config}")
+              set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Auto${exe}ExecutableConfig${TEST_SUFFIX}-build)
+              set(RunCMake_TEST_VARIANT_DESCRIPTION ${TEST_SUFFIX})
+              run_cmake_with_options(Auto${exe}ExecutableConfig ${RunCMake_TEST_OPTIONS} -DCMAKE_CROSS_CONFIGS=all -DCMAKE_DEFAULT_BUILD_TYPE=${ninja_config} -DCMAKE_AUTOGEN_BETTER_GRAPH_MULTI_CONFIG=ON)
+              unset(RunCMake_TEST_VARIANT_DESCRIPTION)
+
+              run_make_program(${RunCMake_TEST_BINARY_DIR} --verbose -f build-${ninja_config}.ninja dummy:${target_config})
+
+              set(expected_output "running_exe_${ninja_config}")
+              expect_only_once("${make_program_stdout}" "${expected_output}" "Auto${exe}ExecutableConfig${TEST_SUFFIX}-${expected_output}")
+
+              foreach(sub_config IN ITEMS Debug Release RelWithDebInfo)
+                if(NOT sub_config STREQUAL ninja_config)
+                  set(unexpected_output "running_exe_${sub_config}")
+                  not_expect("${make_program_stdout}" "${unexpected_output}" "Auto${exe}ExecutableConfig${TEST_SUFFIX}-${unexpected_output}")
+                endif()
+              endforeach()
+
+              if (exe STREQUAL "Moc" OR exe STREQUAL "Uic")
+                set(expected_output "cmake_autogen")
+              else()
+                set(expected_output "cmake_autorcc")
+              endif()
+              expect_only_once("${make_program_stdout}" "${expected_output}" "Auto${exe}ExecutableConfig${TEST_SUFFIX}-${expected_output}")
+            endblock()
+          endforeach()
+        endforeach()
+      endblock()
+      block()
+        foreach(ninja_config IN ITEMS Debug Release RelWithDebInfo)
+          set(TEST_SUFFIX "-CrossConfig-${ninja_config}-all-all")
+          set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Auto${exe}ExecutableConfig${TEST_SUFFIX}-build)
+          set(RunCMake_TEST_VARIANT_DESCRIPTION ${TEST_SUFFIX})
+          run_cmake_with_options(Auto${exe}ExecutableConfig ${RunCMake_TEST_OPTIONS} -DCMAKE_CROSS_CONFIGS=all -DCMAKE_AUTOGEN_BETTER_GRAPH_MULTI_CONFIG=ON)
+          unset(RunCMake_TEST_VARIANT_DESCRIPTION)
+          run_make_program(${RunCMake_TEST_BINARY_DIR} --verbose -f build-${ninja_config}.ninja all:all)
+        endforeach()
+      endblock()
+    elseif (RunCMake_GENERATOR MATCHES "Ninja|Make")
+      block()
+        set(RunCMake_TEST_BINARY_DIR  ${RunCMake_BINARY_DIR}/Auto${exe}ExecutableConfig-build)
+        foreach(config IN ITEMS Debug Release RelWithDebInfo)
+          block()
+            set(RunCMake_TEST_VARIANT_DESCRIPTION "-${config}")
+            run_cmake_with_options(Auto${exe}ExecutableConfig ${RunCMake_TEST_OPTIONS} -DCMAKE_BUILD_TYPE=${config} -DCMAKE_AUTOGEN_VERBOSE=ON)
+            unset(RunCMake_TEST_VARIANT_DESCRIPTION)
+            set(RunCMake_TEST_NO_CLEAN 1)
+            set(RunCMake_TEST_EXPECT_stdout ".*running_exe_${config}*")
+            run_cmake_command(Auto${exe}ExecutableConfig-${config}-build ${CMAKE_COMMAND} --build .)
+          endblock()
+        endforeach()
+      endblock()
+    endif()
+  endif()
+
+  # Visual Studio specific dependency tests
+  if (RunCMake_GENERATOR MATCHES "Visual Studio")
+    block()
+      set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${exe}Example-build)
+      set(RunCMake_TEST_VARIANT_DESCRIPTION "-CMake-configure")
+      run_cmake_with_options(${exe}Example ${RunCMake_TEST_OPTIONS} -DCMAKE_AUTOGEN_VERBOSE=ON)
+      unset(RunCMake_TEST_VARIANT_DESCRIPTION)
+      set(RunCMake_TEST_NO_CLEAN 1)
+      foreach(config IN ITEMS Debug Release RelWithDebInfo)
+        block()
+          set(RunCMake_TEST_VARIANT_DESCRIPTION "-${config}-first-build")
+          run_cmake_command(${exe}Example-build ${CMAKE_COMMAND} --build . --config ${config})
+        endblock()
+      endforeach()
+      foreach(config IN ITEMS Debug Release RelWithDebInfo)
+        block()
+          if (exe STREQUAL "Moc" OR exe STREQUAL "Uic")
+            set(RunCMake_TEST_NOT_EXPECT_stdout "Auto${exe}")
+            set(not_expect_descripton "Auto${exe}")
+          else ()
+            set(RunCMake_TEST_NOT_EXPECT_stdout "Auto${exe}")
+            set(not_expect_descripton "Auto${exe}")
+          endif()
+          set(RunCMake_TEST_VARIANT_DESCRIPTION "-second-build-${config}_expect_no_${not_expect_descripton}")
+          run_cmake_command(${exe}Example-build ${CMAKE_COMMAND} --build . --config ${config})
+        endblock()
+      endforeach()
+    endblock()
+  endif()
+
+  if (RunCMake_GENERATOR MATCHES "Xcode")
+    foreach(exe IN ITEMS Moc Uic Rcc)
+      block()
+        set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${exe}Example-build)
+        set(RunCMake_TEST_VARIANT_DESCRIPTION "-CMake-configure")
+        set(RunCMake_TEST_EXPECT_stderr ".*")
+        run_cmake_with_options(${exe}Example ${RunCMake_TEST_OPTIONS} -DCMAKE_AUTOGEN_VERBOSE=ON)
+        set(RunCMake_TEST_NO_CLEAN 1)
+        set(RunCMake_MAKE_PROGRAM ${CMAKE_COMMAND})
+        run_make_program(${RunCMake_TEST_BINARY_DIR}  --build . --config Debug)
+        if (exe STREQUAL "Moc")
+          set(expected_count 16)
+        elseif (exe STREQUAL "Uic")
+          set(expected_count 4)
+        else()
+          set(expected_count 12)
+        endif()
+        expect_n_times("${make_program_stdout}" "Auto${exe}:" ${expected_count} "${exe}Example-build-Auto${exe}")
+        expect_n_times("${make_program_stdout}" "Auto${exe}:" ${expected_count} "${exe}Example-build-Auto${exe}")
+
+        if (exe STREQUAL "Moc" OR exe STREQUAL "Uic")
+          expect_n_times("${make_program_stdout}" "AutoGen:" 20 "${exe}Example-build-AutoGen:")
+        endif()
+
+        foreach(config IN ITEMS Debug Release RelWithDebInfo)
+          block()
+            run_make_program(${RunCMake_TEST_BINARY_DIR} --build . --config ${config})
+            not_expect("${make_program_stdout}" "Auto${exe}" "${exe}Example-${config}_Auto${exe}")
+            not_expect("${make_program_stdout}" "AutoGen:" "${exe}Example-${config}_AutoGen")
+          endblock()
+        endforeach()
+      endblock()
+    endforeach()
+  endif()
+endfunction()
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index 213c18d..bfa59d6 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -288,28 +288,35 @@
   cmake_path(GET Qt6_DIR  PARENT_PATH base_dir)  # <base>/lib/cmake
   cmake_path(GET base_dir PARENT_PATH base_dir)  # <base>/lib
   cmake_path(GET base_dir PARENT_PATH base_dir)  # <base>
-  add_RunCMake_test(AutogenQt6 TEST_DIR Autogen
-    -Dwith_qt_version=6
-    -DQtCore_VERSION=${Qt6Core_VERSION}
-    "-DQt6_DIR:PATH=${Qt6_DIR}"
-    "-DCMAKE_PREFIX_PATH:STRING=${base_dir}"
-    -DPSEUDO_TIDY=$<TARGET_FILE:pseudo_tidy>
-    -DPSEUDO_IWYU=$<TARGET_FILE:pseudo_iwyu>
-    -DPSEUDO_CPPLINT=$<TARGET_FILE:pseudo_cpplint>
-    -DPSEUDO_CPPCHECK=$<TARGET_FILE:pseudo_cppcheck>
-  )
+  # Note: Since RunCMake.Autogen tests cause time out on some CI,
+  # we split the tests.
+  set(autogen_test_number 1 2 3 4 5)
+  foreach(val IN ITEMS ${autogen_test_number})
+    add_RunCMake_test("Autogen_Qt6_${val}" TEST_DIR "Autogen_${val}"
+      -Dwith_qt_version=6
+      -DQtCore_VERSION=${Qt6Core_VERSION}
+      "-DQt6_DIR:PATH=${Qt6_DIR}"
+      "-DCMAKE_PREFIX_PATH:STRING=${base_dir}"
+      -DPSEUDO_TIDY=$<TARGET_FILE:pseudo_tidy>
+      -DPSEUDO_IWYU=$<TARGET_FILE:pseudo_iwyu>
+      -DPSEUDO_CPPLINT=$<TARGET_FILE:pseudo_cpplint>
+      -DPSEUDO_CPPCHECK=$<TARGET_FILE:pseudo_cppcheck>
+    )
+  endforeach()
   set(want_NoQt_test FALSE)
 endif ()
 if(CMake_TEST_Qt5 AND Qt5Widgets_FOUND)
-  add_RunCMake_test(AutogenQt5 TEST_DIR Autogen
-    -Dwith_qt_version=5
-    -DQtCore_VERSION=${Qt5Core_VERSION}
-    "-DQt5_DIR:PATH=${Qt5_DIR}"
-  )
+  foreach(val IN ITEMS ${autogen_test_number})
+    add_RunCMake_test("Autogen_Qt5_${val}" TEST_DIR "Autogen_${val}"
+      -Dwith_qt_version=5
+      -DQtCore_VERSION=${Qt5Core_VERSION}
+      "-DQt5_DIR:PATH=${Qt5_DIR}"
+    )
+  endforeach()
   set(want_NoQt_test FALSE)
 endif ()
 if(want_NoQt_test)
-  add_RunCMake_test(AutogenNoQt TEST_DIR Autogen)
+  add_RunCMake_test(AutogenNoQt TEST_DIR Autogen_1)
 endif()
 
 if(NOT DEFINED CMake_TEST_BuildDepends_GNU_AS
@@ -588,6 +595,7 @@
   endif()
 endforeach()
 add_RunCMake_test(file-DOWNLOAD)
+add_RunCMake_test(file-MAKE_DIRECTORY)
 add_RunCMake_test(file-RPATH
   -DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME}
   -DCMake_TEST_ELF_LARGE=${CMake_TEST_ELF_LARGE}
@@ -1059,6 +1067,7 @@
   DEB.DEB_DESCRIPTION
   DEB.PROJECT_META
   DEB.COMPONENT_WITH_SPECIAL_CHARS
+  DEB.MULTIARCH
 
   RPM.AUTO_SUFFIXES
   RPM.CUSTOM_BINARY_SPEC_FILE
diff --git a/Tests/RunCMake/CPack/README.txt b/Tests/RunCMake/CPack/README.txt
index 2165125..d403db0 100644
--- a/Tests/RunCMake/CPack/README.txt
+++ b/Tests/RunCMake/CPack/README.txt
@@ -10,8 +10,8 @@
 All phases are executed separately for each generator that is bound to a test.
 Tests for each generator are subtests of test 'RunCMake.CPack_<generator_name>'.
 
-Each test must also be added to 'RunCMakeTest.cmake' script located in CPack
-test root directory.
+Each test must be added to list "cpack_tests" in 'Tests/RunCMake/CMakeLists.txt'
+and also to 'RunCMakeTest.cmake' script located in 'Tests/RunCMake/CPack/'.
 
 Line that adds a test is:
 run_cpack_test(<test_name> "<generator_name_list>" <compile_stage>
@@ -53,7 +53,7 @@
 - verification of generated files
 
 The phases are executed once per specified generator, packaging type and subtest
-combinatiion.
+combination.
 
 test prerequirements phase (optional):
 --------------------------------------
@@ -136,7 +136,7 @@
 - EXPECTED_FILES_COUNT variable that contains the number of expected files that
   will be generated (0 or more)
 
-- EXPECTED_FILE_<file_number_starting_with_1> that contains globing expression
+- EXPECTED_FILE_<file_number_starting_with_1> that contains globbing expression
   that uniquely defines expected file name (will be used to find expected file)
   and should be present once for each expected file.
   NOTE: This variable should be used only as last resort as it sets generator
diff --git a/Tests/RunCMake/CPack/RunCMakeTest.cmake b/Tests/RunCMake/CPack/RunCMakeTest.cmake
index 5d32404..54671aa 100644
--- a/Tests/RunCMake/CPack/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CPack/RunCMakeTest.cmake
@@ -73,3 +73,4 @@
 run_cpack_test_subtests(DUPLICATE_FILE "success;conflict_file;conflict_symlink" "TGZ" false "COMPONENT;GROUP")
 run_cpack_test(COMPONENT_WITH_SPECIAL_CHARS "RPM.COMPONENT_WITH_SPECIAL_CHARS;DEB.COMPONENT_WITH_SPECIAL_CHARS;7Z;TBZ2;TGZ;TXZ;TZ;ZIP;STGZ" false "MONOLITHIC;COMPONENT;GROUP")
 run_cpack_test_package_target(COMPONENT_WITH_SPECIAL_CHARS "RPM.COMPONENT_WITH_SPECIAL_CHARS;DEB.COMPONENT_WITH_SPECIAL_CHARS;7Z;TBZ2;TGZ;TXZ;TZ;ZIP;STGZ" false "MONOLITHIC;COMPONENT;GROUP")
+run_cpack_test_subtests(MULTIARCH "same;foreign;allowed;fail" "DEB.MULTIARCH" false "MONOLITHIC;COMPONENT")
diff --git a/Tests/RunCMake/CPack/tests/MULTIARCH/DEB-fail-stderr.txt b/Tests/RunCMake/CPack/tests/MULTIARCH/DEB-fail-stderr.txt
new file mode 100644
index 0000000..8164e83
--- /dev/null
+++ b/Tests/RunCMake/CPack/tests/MULTIARCH/DEB-fail-stderr.txt
@@ -0,0 +1 @@
+Error: invalid value for Multi-Arch: fail\. Valid values are: same, foreign, allowed
diff --git a/Tests/RunCMake/CPack/tests/MULTIARCH/ExpectedFiles.cmake b/Tests/RunCMake/CPack/tests/MULTIARCH/ExpectedFiles.cmake
new file mode 100644
index 0000000..14b898f
--- /dev/null
+++ b/Tests/RunCMake/CPack/tests/MULTIARCH/ExpectedFiles.cmake
@@ -0,0 +1,5 @@
+set(EXPECTED_FILES_COUNT "0")
+if(NOT ${RunCMake_SUBTEST_SUFFIX} STREQUAL "fail")
+    set(EXPECTED_FILES_COUNT "1")
+    set(EXPECTED_FILE_CONTENT_1_LIST "/foo;/foo/CMakeLists.txt")
+endif ()
diff --git a/Tests/RunCMake/CPack/tests/MULTIARCH/VerifyResult.cmake b/Tests/RunCMake/CPack/tests/MULTIARCH/VerifyResult.cmake
new file mode 100644
index 0000000..f4e8050
--- /dev/null
+++ b/Tests/RunCMake/CPack/tests/MULTIARCH/VerifyResult.cmake
@@ -0,0 +1,4 @@
+if(NOT ${RunCMake_SUBTEST_SUFFIX} STREQUAL "fail")
+    set(MULTIARCH_control "Multi-Arch: ${RunCMake_SUBTEST_SUFFIX}")
+    verifyDebControl("${FOUND_FILE_1}" "MULTIARCH" "control")
+endif ()
diff --git a/Tests/RunCMake/CPack/tests/MULTIARCH/test.cmake b/Tests/RunCMake/CPack/tests/MULTIARCH/test.cmake
new file mode 100644
index 0000000..9784342
--- /dev/null
+++ b/Tests/RunCMake/CPack/tests/MULTIARCH/test.cmake
@@ -0,0 +1,7 @@
+install(FILES CMakeLists.txt DESTINATION foo COMPONENT test)
+
+set(CPACK_DEBIAN_PACKAGE_MULTIARCH ${RunCMake_SUBTEST_SUFFIX})
+
+if(PACKAGING_TYPE STREQUAL "COMPONENT")
+  set(CPACK_COMPONENTS_ALL test)
+endif()
diff --git a/Tests/RunCMake/Framework/FrameworkLayout-check-common.cmake b/Tests/RunCMake/Framework/FrameworkLayout-check-common.cmake
new file mode 100644
index 0000000..13a91df
--- /dev/null
+++ b/Tests/RunCMake/Framework/FrameworkLayout-check-common.cmake
@@ -0,0 +1,24 @@
+macro(check_plist key expect)
+  execute_process(
+    COMMAND plutil -extract "${key}" xml1 "${plist-file}" -o -
+    RESULT_VARIABLE result
+    OUTPUT_VARIABLE actual
+    OUTPUT_STRIP_TRAILING_WHITESPACE
+    )
+  if(actual MATCHES "<string>([^<>]*)</string>")
+    set(actual "${CMAKE_MATCH_1}")
+  endif()
+  if(NOT "${actual}" STREQUAL "${expect}")
+    string(CONCAT RunCMake_TEST_FAILED
+      "Framework Info.plist key \"${key}\" has value:\n"
+      "  \"${actual}\"\n"
+      "but we expected:\n"
+      "  \"${expect}\""
+      )
+  endif()
+endmacro()
+
+check_plist(CFBundleIdentifier MyFrameworkId)
+check_plist(CFBundleName MyFrameworkBundleName)
+check_plist(CFBundleVersion 3.2.1)
+check_plist(CFBundleShortVersionString 3)
diff --git a/Tests/RunCMake/Framework/FrameworkLayout.cmake b/Tests/RunCMake/Framework/FrameworkLayout.cmake
index d09e8a0..e230e07 100644
--- a/Tests/RunCMake/Framework/FrameworkLayout.cmake
+++ b/Tests/RunCMake/Framework/FrameworkLayout.cmake
@@ -15,6 +15,10 @@
                         FRAMEWORK TRUE)
 endif()
 set_target_properties(Framework PROPERTIES
+                      MACOSX_FRAMEWORK_BUNDLE_NAME MyFrameworkBundleName
+                      MACOSX_FRAMEWORK_BUNDLE_VERSION 3.2.1
+                      MACOSX_FRAMEWORK_SHORT_VERSION_STRING 3
+                      MACOSX_FRAMEWORK_IDENTIFIER MyFrameworkId
                       PUBLIC_HEADER foo.h
                       RESOURCE "res.txt")
 set_source_files_properties(flatresource.txt PROPERTIES MACOSX_PACKAGE_LOCATION Resources)
diff --git a/Tests/RunCMake/Framework/FrameworkMultiConfigPostfix-build-final-check.cmake b/Tests/RunCMake/Framework/FrameworkMultiConfigPostfix-build-final-check.cmake
index 76fe6b8..7a1d70e 100644
--- a/Tests/RunCMake/Framework/FrameworkMultiConfigPostfix-build-final-check.cmake
+++ b/Tests/RunCMake/Framework/FrameworkMultiConfigPostfix-build-final-check.cmake
@@ -20,26 +20,32 @@
 endif()
 
 if(NOT IS_DIRECTORY ${framework_dir})
-  message(SEND_ERROR "Framework dir not found at ${framework_dir}")
+  set(RunCMake_TEST_FAILED "Framework dir not found at \n  ${framework_dir}")
+  return()
 endif()
 
 if(IS_DIRECTORY ${non_existent_debug_framework_dir})
-  message(SEND_ERROR
-      "A framework dir with a debug suffix should not exist at ${non_existent_debug_framework_dir}")
+  set(RunCMake_TEST_FAILED
+      "A framework dir with a debug suffix should not exist at \n  ${non_existent_debug_framework_dir}")
+  return()
 endif()
 
 if(NOT IS_SYMLINK "${symlink_release_path}")
-  message(SEND_ERROR "Release framework symlink not found at ${symlink_release_path}")
+  set(RunCMake_TEST_FAILED "Release framework symlink not found at \n  ${symlink_release_path}")
+  return()
 endif()
 
 if(NOT IS_SYMLINK "${symlink_debug_path}")
-  message(SEND_ERROR "Debug framework symlink not found at ${symlink_debug_path}")
+  set(RunCMake_TEST_FAILED "Debug framework symlink not found at \n  ${symlink_debug_path}")
+  return()
 endif()
 
 if(NOT EXISTS "${framework_release_path}")
-  message(SEND_ERROR "Release framework not found at ${framework_release_path}")
+  set(RunCMake_TEST_FAILED "Release framework not found at \n  ${framework_release_path}")
+  return()
 endif()
 
 if(NOT EXISTS "${framework_debug_path}")
-  message(SEND_ERROR "Debug framework not found at ${framework_debug_path}")
+  set(RunCMake_TEST_FAILED "Debug framework not found at \n  ${framework_debug_path}")
+  return()
 endif()
diff --git a/Tests/RunCMake/Framework/OSXFrameworkLayout-build-check.cmake b/Tests/RunCMake/Framework/OSXFrameworkLayout-build-check.cmake
index eb71394..b436128 100644
--- a/Tests/RunCMake/Framework/OSXFrameworkLayout-build-check.cmake
+++ b/Tests/RunCMake/Framework/OSXFrameworkLayout-build-check.cmake
@@ -10,41 +10,53 @@
 set(framework-header "${framework-dir}/Headers/foo.h")
 
 if(NOT IS_DIRECTORY ${framework-dir})
-  message(SEND_ERROR "Framework not found at ${framework-dir}")
+  set(RunCMake_TEST_FAILED "Framework not found at \n  ${framework-dir}")
+  return()
 endif()
 
 if(NOT EXISTS ${plist-file})
-  message(SEND_ERROR "plist file not found at ${plist-file}")
+  set(RunCMake_TEST_FAILED "plist file not found at \n  ${plist-file}")
+  return()
 endif()
 
 if(NOT EXISTS ${framework-library})
-  message(SEND_ERROR "Framework library not found at ${framework-library}")
+  set(RunCMake_TEST_FAILED "Framework library not found at \n  ${framework-library}")
+  return()
 endif()
 
 if(NOT EXISTS ${framework-resource-file})
-  message(SEND_ERROR "Framework resource file not found at ${framework-resource-file}")
+  set(RunCMake_TEST_FAILED "Framework resource file not found at \n  ${framework-resource-file}")
+  return()
 endif()
 
 if(NOT EXISTS ${framework-flat-resource-file})
-  message(SEND_ERROR "Framework flat resource file not found at ${framework-flat-resource-file}")
+  set(RunCMake_TEST_FAILED "Framework flat resource file not found at \n  ${framework-flat-resource-file}")
+  return()
 endif()
 
 if(NOT EXISTS ${framework-deep-resource-file})
-  message(SEND_ERROR "Framework deep resource file not found at ${framework-deep-resource-file}")
+  set(RunCMake_TEST_FAILED "Framework deep resource file not found at \n  ${framework-deep-resource-file}")
+  return()
 endif()
 
 if(NOT EXISTS ${framework-some-file})
-  message(SEND_ERROR "Framework some file not found at ${framework-some-file}")
+  set(RunCMake_TEST_FAILED "Framework some file not found at \n  ${framework-some-file}")
+  return()
 endif()
 
 if(NOT EXISTS ${framework-versions})
-  message(SEND_ERROR "Framework versions not found at ${framework-versions}")
+  set(RunCMake_TEST_FAILED "Framework versions not found at \n  ${framework-versions}")
+  return()
 endif()
 
 if(NOT EXISTS ${framework-resources})
-  message(SEND_ERROR "Framework Resources not found at ${framework-resources}")
+  set(RunCMake_TEST_FAILED "Framework Resources not found at \n  ${framework-resources}")
+  return()
 endif()
 
 if(NOT EXISTS ${framework-header})
-  message(SEND_ERROR "Framework header file not found at ${framework-header}")
+  set(RunCMake_TEST_FAILED "Framework header file not found at \n  ${framework-header}")
+  return()
 endif()
+
+include(${CMAKE_CURRENT_LIST_DIR}/FrameworkLayout-check-common.cmake)
diff --git a/Tests/RunCMake/Framework/iOSFrameworkLayout-build-check.cmake b/Tests/RunCMake/Framework/iOSFrameworkLayout-build-check.cmake
index 2da60d2..be9a5fe 100644
--- a/Tests/RunCMake/Framework/iOSFrameworkLayout-build-check.cmake
+++ b/Tests/RunCMake/Framework/iOSFrameworkLayout-build-check.cmake
@@ -10,41 +10,53 @@
 set(framework-header "${framework-dir}/Headers/foo.h")
 
 if(NOT IS_DIRECTORY ${framework-dir})
-  message(SEND_ERROR "Framework not found at ${framework-dir}")
+  set(RunCMake_TEST_FAILED "Framework not found at\n  ${framework-dir}")
+  return()
 endif()
 
 if(NOT EXISTS ${plist-file})
-  message(SEND_ERROR "plist file not found at ${plist-file}")
+  set(RunCMake_TEST_FAILED "plist file not found at\n  ${plist-file}")
+  return()
 endif()
 
 if(NOT EXISTS ${framework-library})
-  message(SEND_ERROR "Framework library not found at ${framework-library}")
+  set(RunCMake_TEST_FAILED "Framework library not found at\n  ${framework-library}")
+  return()
 endif()
 
 if(NOT EXISTS ${framework-resource-file})
-  message(SEND_ERROR "Framework resource file not found at ${framework-resource-file}")
+  set(RunCMake_TEST_FAILED "Framework resource file not found at\n  ${framework-resource-file}")
+  return()
 endif()
 
 if(NOT EXISTS ${framework-flat-resource-file})
-  message(SEND_ERROR "Framework flat resource file not found at ${framework-flat-resource-file}")
+  set(RunCMake_TEST_FAILED "Framework flat resource file not found at\n  ${framework-flat-resource-file}")
+  return()
 endif()
 
 if(NOT EXISTS ${framework-deep-resource-file})
-  message(SEND_ERROR "Framework deep resource file not found at ${framework-deep-resource-file}")
+  set(RunCMake_TEST_FAILED "Framework deep resource file not found at\n  ${framework-deep-resource-file}")
+  return()
 endif()
 
 if(NOT EXISTS ${framework-some-file})
-  message(SEND_ERROR "Framework some file not found at ${framework-some-file}")
+  set(RunCMake_TEST_FAILED "Framework some file not found at\n  ${framework-some-file}")
+  return()
 endif()
 
 if(EXISTS ${framework-versions})
-  message(SEND_ERROR "Framework versions found at ${framework-versions}")
+  set(RunCMake_TEST_FAILED "Framework versions found at\n  ${framework-versions}")
+  return()
 endif()
 
 if(EXISTS ${framework-resources})
-  message(SEND_ERROR "Framework Resources found at ${framework-resources}")
+  set(RunCMake_TEST_FAILED "Framework Resources found at\n  ${framework-resources}")
+  return()
 endif()
 
 if(NOT EXISTS ${framework-header})
-  message(SEND_ERROR "Framework headers not found at ${framework-header}")
+  set(RunCMake_TEST_FAILED "Framework headers not found at\n  ${framework-header}")
+  return()
 endif()
+
+include(${CMAKE_CURRENT_LIST_DIR}/FrameworkLayout-check-common.cmake)
diff --git a/Tests/RunCMake/GenEx-LINK_LIBRARY/RunCMakeTest.cmake b/Tests/RunCMake/GenEx-LINK_LIBRARY/RunCMakeTest.cmake
index a061127..fdad38d 100644
--- a/Tests/RunCMake/GenEx-LINK_LIBRARY/RunCMakeTest.cmake
+++ b/Tests/RunCMake/GenEx-LINK_LIBRARY/RunCMakeTest.cmake
@@ -36,9 +36,12 @@
 run_cmake(override-features4)
 run_cmake(override-features5)
 
-# testing feature properties specification
-run_cmake(bad-feature-properties1)
-run_cmake(bad-feature-properties2)
-run_cmake(bad-feature-properties3)
-run_cmake(bad-feature-properties4)
-run_cmake(bad-feature-properties5)
+# testing feature attributes specification
+run_cmake(bad-feature-attributes1)
+run_cmake(bad-feature-attributes2)
+run_cmake(bad-feature-attributes3)
+run_cmake(bad-feature-attributes4)
+run_cmake(bad-feature-attributes5)
+run_cmake(unsupported-library_type)
+run_cmake(cyclic-override)
+run_cmake(multiple-override)
diff --git a/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-properties1-result.txt b/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-attributes1-result.txt
similarity index 100%
rename from Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-properties1-result.txt
rename to Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-attributes1-result.txt
diff --git a/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-attributes1-stderr.txt b/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-attributes1-stderr.txt
new file mode 100644
index 0000000..5923654
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-attributes1-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error:
+  Erroneous option\(s\) for 'CMAKE_LINK_LIBRARY_feature_ATTRIBUTES':
+
+    BAD_ATTRIBUTE=XXX
diff --git a/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-properties5.cmake b/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-attributes1.cmake
similarity index 80%
rename from Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-properties5.cmake
rename to Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-attributes1.cmake
index 06efe7e..dc743a8 100644
--- a/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-properties5.cmake
+++ b/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-attributes1.cmake
@@ -2,7 +2,7 @@
 
 set(CMAKE_LINK_LIBRARY_USING_feature "<LIBRARY>")
 set(CMAKE_LINK_LIBRARY_USING_feature_SUPPORTED TRUE)
-set(CMAKE_LINK_LIBRARY_feature_PROPERTIES UNICITY=YES,NO)
+set(CMAKE_LINK_LIBRARY_feature_ATTRIBUTES BAD_ATTRIBUTE=XXX)
 
 add_library(dep SHARED empty.c)
 
diff --git a/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-properties2-result.txt b/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-attributes2-result.txt
similarity index 100%
rename from Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-properties2-result.txt
rename to Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-attributes2-result.txt
diff --git a/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-attributes2-stderr.txt b/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-attributes2-stderr.txt
new file mode 100644
index 0000000..5923654
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-attributes2-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error:
+  Erroneous option\(s\) for 'CMAKE_LINK_LIBRARY_feature_ATTRIBUTES':
+
+    BAD_ATTRIBUTE=XXX
diff --git a/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-properties2.cmake b/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-attributes2.cmake
similarity index 71%
copy from Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-properties2.cmake
copy to Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-attributes2.cmake
index dea98d2..3012308 100644
--- a/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-properties2.cmake
+++ b/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-attributes2.cmake
@@ -2,7 +2,7 @@
 
 set(CMAKE_LINK_LIBRARY_USING_feature "<LIBRARY>")
 set(CMAKE_LINK_LIBRARY_USING_feature_SUPPORTED TRUE)
-set(CMAKE_LINK_LIBRARY_feature_PROPERTIES LIBRARY_TYPE=STATIC BAD_PROPERTY=XXX UNICITY=YES)
+set(CMAKE_LINK_LIBRARY_feature_ATTRIBUTES LIBRARY_TYPE=STATIC BAD_ATTRIBUTE=XXX DEDUPLICATION=YES)
 
 add_library(dep SHARED empty.c)
 
diff --git a/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-properties3-result.txt b/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-attributes3-result.txt
similarity index 100%
rename from Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-properties3-result.txt
rename to Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-attributes3-result.txt
diff --git a/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-attributes3-stderr.txt b/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-attributes3-stderr.txt
new file mode 100644
index 0000000..a0b0a75
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-attributes3-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error:
+  Erroneous option\(s\) for 'CMAKE_LINK_LIBRARY_feature_ATTRIBUTES':
+
+    LIBRARY_TYPE=STATIC,BAD_TYPE
diff --git a/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-properties3.cmake b/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-attributes3.cmake
similarity index 80%
rename from Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-properties3.cmake
rename to Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-attributes3.cmake
index 0a535db..8887934 100644
--- a/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-properties3.cmake
+++ b/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-attributes3.cmake
@@ -2,7 +2,7 @@
 
 set(CMAKE_LINK_LIBRARY_USING_feature "<LIBRARY>")
 set(CMAKE_LINK_LIBRARY_USING_feature_SUPPORTED TRUE)
-set(CMAKE_LINK_LIBRARY_feature_PROPERTIES LIBRARY_TYPE=STATIC,BAD_TYPE)
+set(CMAKE_LINK_LIBRARY_feature_ATTRIBUTES LIBRARY_TYPE=STATIC,BAD_TYPE)
 
 add_library(dep SHARED empty.c)
 
diff --git a/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-properties4-result.txt b/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-attributes4-result.txt
similarity index 100%
rename from Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-properties4-result.txt
rename to Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-attributes4-result.txt
diff --git a/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-attributes4-stderr.txt b/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-attributes4-stderr.txt
new file mode 100644
index 0000000..a0b0a75
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-attributes4-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error:
+  Erroneous option\(s\) for 'CMAKE_LINK_LIBRARY_feature_ATTRIBUTES':
+
+    LIBRARY_TYPE=STATIC,BAD_TYPE
diff --git a/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-properties2.cmake b/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-attributes4.cmake
similarity index 73%
rename from Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-properties2.cmake
rename to Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-attributes4.cmake
index dea98d2..3edf268 100644
--- a/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-properties2.cmake
+++ b/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-attributes4.cmake
@@ -2,7 +2,7 @@
 
 set(CMAKE_LINK_LIBRARY_USING_feature "<LIBRARY>")
 set(CMAKE_LINK_LIBRARY_USING_feature_SUPPORTED TRUE)
-set(CMAKE_LINK_LIBRARY_feature_PROPERTIES LIBRARY_TYPE=STATIC BAD_PROPERTY=XXX UNICITY=YES)
+set(CMAKE_LINK_LIBRARY_feature_ATTRIBUTES DEDUPLICATION=YES LIBRARY_TYPE=STATIC,BAD_TYPE)
 
 add_library(dep SHARED empty.c)
 
diff --git a/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-properties5-result.txt b/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-attributes5-result.txt
similarity index 100%
rename from Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-properties5-result.txt
rename to Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-attributes5-result.txt
diff --git a/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-attributes5-stderr.txt b/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-attributes5-stderr.txt
new file mode 100644
index 0000000..34c1143
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-attributes5-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error:
+  Erroneous option\(s\) for 'CMAKE_LINK_LIBRARY_feature_ATTRIBUTES':
+
+    DEDUPLICATION=YES,NO
diff --git a/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-properties5.cmake b/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-attributes5.cmake
similarity index 79%
copy from Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-properties5.cmake
copy to Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-attributes5.cmake
index 06efe7e..5af99cd 100644
--- a/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-properties5.cmake
+++ b/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-attributes5.cmake
@@ -2,7 +2,7 @@
 
 set(CMAKE_LINK_LIBRARY_USING_feature "<LIBRARY>")
 set(CMAKE_LINK_LIBRARY_USING_feature_SUPPORTED TRUE)
-set(CMAKE_LINK_LIBRARY_feature_PROPERTIES UNICITY=YES,NO)
+set(CMAKE_LINK_LIBRARY_feature_ATTRIBUTES DEDUPLICATION=YES,NO)
 
 add_library(dep SHARED empty.c)
 
diff --git a/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-properties1-stderr.txt b/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-properties1-stderr.txt
deleted file mode 100644
index ac07251..0000000
--- a/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-properties1-stderr.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-CMake Error:
-  Erroneous option\(s\) for 'CMAKE_LINK_LIBRARY_feature_PROPERTIES':
-
-    BAD_PROPERTY=XXX
diff --git a/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-properties1.cmake b/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-properties1.cmake
deleted file mode 100644
index e5790a8..0000000
--- a/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-properties1.cmake
+++ /dev/null
@@ -1,10 +0,0 @@
-enable_language(C)
-
-set(CMAKE_LINK_LIBRARY_USING_feature "<LIBRARY>")
-set(CMAKE_LINK_LIBRARY_USING_feature_SUPPORTED TRUE)
-set(CMAKE_LINK_LIBRARY_feature_PROPERTIES BAD_PROPERTY=XXX)
-
-add_library(dep SHARED empty.c)
-
-add_library(lib SHARED empty.c)
-target_link_libraries(lib PRIVATE "$<LINK_LIBRARY:feature,dep>")
diff --git a/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-properties2-stderr.txt b/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-properties2-stderr.txt
deleted file mode 100644
index ac07251..0000000
--- a/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-properties2-stderr.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-CMake Error:
-  Erroneous option\(s\) for 'CMAKE_LINK_LIBRARY_feature_PROPERTIES':
-
-    BAD_PROPERTY=XXX
diff --git a/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-properties3-stderr.txt b/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-properties3-stderr.txt
deleted file mode 100644
index 29f5f66..0000000
--- a/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-properties3-stderr.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-CMake Error:
-  Erroneous option\(s\) for 'CMAKE_LINK_LIBRARY_feature_PROPERTIES':
-
-    LIBRARY_TYPE=STATIC,BAD_TYPE
diff --git a/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-properties4-stderr.txt b/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-properties4-stderr.txt
deleted file mode 100644
index 29f5f66..0000000
--- a/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-properties4-stderr.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-CMake Error:
-  Erroneous option\(s\) for 'CMAKE_LINK_LIBRARY_feature_PROPERTIES':
-
-    LIBRARY_TYPE=STATIC,BAD_TYPE
diff --git a/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-properties4.cmake b/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-properties4.cmake
deleted file mode 100644
index c106653..0000000
--- a/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-properties4.cmake
+++ /dev/null
@@ -1,10 +0,0 @@
-enable_language(C)
-
-set(CMAKE_LINK_LIBRARY_USING_feature "<LIBRARY>")
-set(CMAKE_LINK_LIBRARY_USING_feature_SUPPORTED TRUE)
-set(CMAKE_LINK_LIBRARY_feature_PROPERTIES UNICITY=YES LIBRARY_TYPE=STATIC,BAD_TYPE)
-
-add_library(dep SHARED empty.c)
-
-add_library(lib SHARED empty.c)
-target_link_libraries(lib PRIVATE "$<LINK_LIBRARY:feature,dep>")
diff --git a/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-properties5-stderr.txt b/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-properties5-stderr.txt
deleted file mode 100644
index 3e57782..0000000
--- a/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-properties5-stderr.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-CMake Error:
-  Erroneous option\(s\) for 'CMAKE_LINK_LIBRARY_feature_PROPERTIES':
-
-    UNICITY=YES,NO
diff --git a/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-properties1-result.txt b/Tests/RunCMake/GenEx-LINK_LIBRARY/cyclic-override-result.txt
similarity index 100%
copy from Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-properties1-result.txt
copy to Tests/RunCMake/GenEx-LINK_LIBRARY/cyclic-override-result.txt
diff --git a/Tests/RunCMake/GenEx-LINK_LIBRARY/cyclic-override-stderr.txt b/Tests/RunCMake/GenEx-LINK_LIBRARY/cyclic-override-stderr.txt
new file mode 100644
index 0000000..4476271
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_LIBRARY/cyclic-override-stderr.txt
@@ -0,0 +1,6 @@
+CMake Error at cyclic-override.cmake:[0-9]+ \(add_library\):
+  Impossible to link target 'lib' because the link item 'dep' is specified
+  with the features 'feature2' and 'feature1', and both have an 'OVERRIDE'
+  attribute that overrides the other.  Such cycles are not allowed.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-LINK_LIBRARY/cyclic-override.cmake b/Tests/RunCMake/GenEx-LINK_LIBRARY/cyclic-override.cmake
new file mode 100644
index 0000000..69b670b
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_LIBRARY/cyclic-override.cmake
@@ -0,0 +1,14 @@
+enable_language(C)
+
+set(CMAKE_LINK_LIBRARY_USING_feature1 "<LIBRARY>")
+set(CMAKE_LINK_LIBRARY_USING_feature1_SUPPORTED TRUE)
+set(CMAKE_LINK_LIBRARY_feature1_ATTRIBUTES OVERRIDE=feature2)
+
+set(CMAKE_LINK_LIBRARY_USING_feature2 "<LIBRARY>")
+set(CMAKE_LINK_LIBRARY_USING_feature2_SUPPORTED TRUE)
+set(CMAKE_LINK_LIBRARY_feature2_ATTRIBUTES OVERRIDE=feature1)
+
+add_library(dep SHARED empty.c)
+
+add_library(lib SHARED empty.c)
+target_link_libraries(lib PRIVATE "$<LINK_LIBRARY:feature1,dep>" "$<LINK_LIBRARY:feature2,dep>")
diff --git a/Tests/RunCMake/GenEx-LINK_LIBRARY/library-ignored.cmake b/Tests/RunCMake/GenEx-LINK_LIBRARY/library-ignored.cmake
index 675b87d..b5e52b5 100644
--- a/Tests/RunCMake/GenEx-LINK_LIBRARY/library-ignored.cmake
+++ b/Tests/RunCMake/GenEx-LINK_LIBRARY/library-ignored.cmake
@@ -2,7 +2,7 @@
 
 set(CMAKE_C_LINK_LIBRARY_USING_feat_SUPPORTED TRUE)
 set(CMAKE_C_LINK_LIBRARY_USING_feat "<LIBRARY>")
-set(CMAKE_C_LINK_LIBRARY_feat_PROPERTIES "LIBRARY_TYPE=STATIC")
+set(CMAKE_C_LINK_LIBRARY_feat_ATTRIBUTES "LIBRARY_TYPE=STATIC")
 
 add_library(dep OBJECT empty.c)
 
diff --git a/Tests/RunCMake/GenEx-LINK_LIBRARY/multiple-override.cmake b/Tests/RunCMake/GenEx-LINK_LIBRARY/multiple-override.cmake
new file mode 100644
index 0000000..97d85d0
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_LIBRARY/multiple-override.cmake
@@ -0,0 +1,14 @@
+enable_language(C)
+
+set(CMAKE_LINK_LIBRARY_USING_feature1 "<LIBRARY>")
+set(CMAKE_LINK_LIBRARY_USING_feature1_SUPPORTED TRUE)
+set(CMAKE_LINK_LIBRARY_feature1_ATTRIBUTES OVERRIDE=feature2)
+
+set(CMAKE_LINK_LIBRARY_USING_feature2 "<LIBRARY>")
+set(CMAKE_LINK_LIBRARY_USING_feature2_SUPPORTED TRUE)
+set(CMAKE_LINK_LIBRARY_feature2_ATTRIBUTES OVERRIDE=feature3)
+
+add_library(dep SHARED empty.c)
+
+add_library(lib SHARED empty.c)
+target_link_libraries(lib PRIVATE "$<LINK_LIBRARY:feature1,dep>" "$<LINK_LIBRARY:feature2,dep>")
diff --git a/Tests/RunCMake/GenEx-LINK_LIBRARY/unsupported-library_type-stderr.txt b/Tests/RunCMake/GenEx-LINK_LIBRARY/unsupported-library_type-stderr.txt
new file mode 100644
index 0000000..a95648b
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_LIBRARY/unsupported-library_type-stderr.txt
@@ -0,0 +1,6 @@
+CMake Warning \(dev\) at unsupported-library_type.cmake:[0-9]+ \(add_library\):
+  The feature 'feature', specified as part of a generator-expression
+  '\$<LINK_LIBRARY:feature>', will not be applied to the SHARED_LIBRARY 'dep'.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)
+This warning is for project developers.  Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-properties5.cmake b/Tests/RunCMake/GenEx-LINK_LIBRARY/unsupported-library_type.cmake
similarity index 79%
copy from Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-properties5.cmake
copy to Tests/RunCMake/GenEx-LINK_LIBRARY/unsupported-library_type.cmake
index 06efe7e..29aba56 100644
--- a/Tests/RunCMake/GenEx-LINK_LIBRARY/bad-feature-properties5.cmake
+++ b/Tests/RunCMake/GenEx-LINK_LIBRARY/unsupported-library_type.cmake
@@ -2,7 +2,7 @@
 
 set(CMAKE_LINK_LIBRARY_USING_feature "<LIBRARY>")
 set(CMAKE_LINK_LIBRARY_USING_feature_SUPPORTED TRUE)
-set(CMAKE_LINK_LIBRARY_feature_PROPERTIES UNICITY=YES,NO)
+set(CMAKE_LINK_LIBRARY_feature_ATTRIBUTES LIBRARY_TYPE=STATIC)
 
 add_library(dep SHARED empty.c)
 
diff --git a/Tests/RunCMake/LinkLibrariesProcessing/InvalidConfiguration1.cmake b/Tests/RunCMake/LinkLibrariesProcessing/InvalidConfiguration1.cmake
index e79eb45..ac5f7f1 100644
--- a/Tests/RunCMake/LinkLibrariesProcessing/InvalidConfiguration1.cmake
+++ b/Tests/RunCMake/LinkLibrariesProcessing/InvalidConfiguration1.cmake
@@ -1,7 +1,7 @@
 
 enable_language(C)
 
-set(CMAKE_C_LINK_LIBRARIES_PROCESSING ORDER= UNICITY=ALL)
+set(CMAKE_C_LINK_LIBRARIES_PROCESSING ORDER= DEDUPLICATION=ALL)
 
 add_library(lib STATIC lib.c)
 
diff --git a/Tests/RunCMake/LinkLibrariesProcessing/InvalidConfiguration2.cmake b/Tests/RunCMake/LinkLibrariesProcessing/InvalidConfiguration2.cmake
index c9da734..63edfd3 100644
--- a/Tests/RunCMake/LinkLibrariesProcessing/InvalidConfiguration2.cmake
+++ b/Tests/RunCMake/LinkLibrariesProcessing/InvalidConfiguration2.cmake
@@ -1,7 +1,7 @@
 
 enable_language(C)
 
-set(CMAKE_C_LINK_LIBRARIES_PROCESSING UNICITY=ALL ORDER)
+set(CMAKE_C_LINK_LIBRARIES_PROCESSING DEDUPLICATION=ALL ORDER)
 
 add_library(lib STATIC lib.c)
 
diff --git a/Tests/RunCMake/LinkLibrariesProcessing/InvalidConfiguration3.cmake b/Tests/RunCMake/LinkLibrariesProcessing/InvalidConfiguration3.cmake
index a1311fe..0bd7c5f 100644
--- a/Tests/RunCMake/LinkLibrariesProcessing/InvalidConfiguration3.cmake
+++ b/Tests/RunCMake/LinkLibrariesProcessing/InvalidConfiguration3.cmake
@@ -1,7 +1,7 @@
 
 enable_language(C)
 
-set(CMAKE_C_LINK_LIBRARIES_PROCESSING WRONG=REVERSE UNICITY=ALL)
+set(CMAKE_C_LINK_LIBRARIES_PROCESSING WRONG=REVERSE DEDUPLICATION=ALL)
 
 add_library(lib STATIC lib.c)
 
diff --git a/Tests/RunCMake/LinkLibrariesProcessing/InvalidConfiguration4-stderr.txt b/Tests/RunCMake/LinkLibrariesProcessing/InvalidConfiguration4-stderr.txt
index 46d5513..256fd4e 100644
--- a/Tests/RunCMake/LinkLibrariesProcessing/InvalidConfiguration4-stderr.txt
+++ b/Tests/RunCMake/LinkLibrariesProcessing/InvalidConfiguration4-stderr.txt
@@ -2,7 +2,7 @@
   Erroneous option\(s\) for 'CMAKE_C_LINK_LIBRARIES_PROCESSING':
 
     WRONG=REVERSE
-    UNICITY=WRONG
+    DEDUPLICATION=WRONG
 
 Call Stack \(most recent call first\):
   CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/LinkLibrariesProcessing/InvalidConfiguration4.cmake b/Tests/RunCMake/LinkLibrariesProcessing/InvalidConfiguration4.cmake
index 9d48f4f..ccb4dae 100644
--- a/Tests/RunCMake/LinkLibrariesProcessing/InvalidConfiguration4.cmake
+++ b/Tests/RunCMake/LinkLibrariesProcessing/InvalidConfiguration4.cmake
@@ -1,7 +1,7 @@
 
 enable_language(C)
 
-set(CMAKE_C_LINK_LIBRARIES_PROCESSING WRONG=REVERSE UNICITY=WRONG)
+set(CMAKE_C_LINK_LIBRARIES_PROCESSING WRONG=REVERSE DEDUPLICATION=WRONG)
 
 add_library(lib STATIC lib.c)
 
diff --git a/Tests/RunCMake/LinkLibrariesProcessing/Invalid_UNICITY-result.txt b/Tests/RunCMake/LinkLibrariesProcessing/Invalid_DEDUPLICATION-result.txt
similarity index 100%
rename from Tests/RunCMake/LinkLibrariesProcessing/Invalid_UNICITY-result.txt
rename to Tests/RunCMake/LinkLibrariesProcessing/Invalid_DEDUPLICATION-result.txt
diff --git a/Tests/RunCMake/LinkLibrariesProcessing/Invalid_UNICITY-stderr.txt b/Tests/RunCMake/LinkLibrariesProcessing/Invalid_DEDUPLICATION-stderr.txt
similarity index 60%
rename from Tests/RunCMake/LinkLibrariesProcessing/Invalid_UNICITY-stderr.txt
rename to Tests/RunCMake/LinkLibrariesProcessing/Invalid_DEDUPLICATION-stderr.txt
index 4d759b7..1138a31 100644
--- a/Tests/RunCMake/LinkLibrariesProcessing/Invalid_UNICITY-stderr.txt
+++ b/Tests/RunCMake/LinkLibrariesProcessing/Invalid_DEDUPLICATION-stderr.txt
@@ -1,7 +1,7 @@
-CMake Error at Invalid_UNICITY.cmake:[0-9]+ \(add_executable\):
+CMake Error at Invalid_DEDUPLICATION.cmake:[0-9]+ \(add_executable\):
   Erroneous option\(s\) for 'CMAKE_C_LINK_LIBRARIES_PROCESSING':
 
-    UNICITY=WRONG
+    DEDUPLICATION=WRONG
 
 Call Stack \(most recent call first\):
   CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/LinkLibrariesProcessing/Invalid_UNICITY.cmake b/Tests/RunCMake/LinkLibrariesProcessing/Invalid_DEDUPLICATION.cmake
similarity index 62%
rename from Tests/RunCMake/LinkLibrariesProcessing/Invalid_UNICITY.cmake
rename to Tests/RunCMake/LinkLibrariesProcessing/Invalid_DEDUPLICATION.cmake
index f423eef..e5ff622 100644
--- a/Tests/RunCMake/LinkLibrariesProcessing/Invalid_UNICITY.cmake
+++ b/Tests/RunCMake/LinkLibrariesProcessing/Invalid_DEDUPLICATION.cmake
@@ -1,7 +1,7 @@
 
 enable_language(C)
 
-set(CMAKE_C_LINK_LIBRARIES_PROCESSING ORDER=REVERSE UNICITY=WRONG)
+set(CMAKE_C_LINK_LIBRARIES_PROCESSING ORDER=REVERSE DEDUPLICATION=WRONG)
 
 add_library(lib STATIC lib.c)
 
diff --git a/Tests/RunCMake/LinkLibrariesProcessing/Invalid_ORDER.cmake b/Tests/RunCMake/LinkLibrariesProcessing/Invalid_ORDER.cmake
index 72a7e02..f0c7ee3 100644
--- a/Tests/RunCMake/LinkLibrariesProcessing/Invalid_ORDER.cmake
+++ b/Tests/RunCMake/LinkLibrariesProcessing/Invalid_ORDER.cmake
@@ -1,7 +1,7 @@
 
 enable_language(C)
 
-set(CMAKE_C_LINK_LIBRARIES_PROCESSING ORDER=WRONG UNICITY=ALL)
+set(CMAKE_C_LINK_LIBRARIES_PROCESSING ORDER=WRONG DEDUPLICATION=ALL)
 
 add_library(lib STATIC lib.c)
 
diff --git a/Tests/RunCMake/LinkLibrariesProcessing/RunCMakeTest.cmake b/Tests/RunCMake/LinkLibrariesProcessing/RunCMakeTest.cmake
index 763f48b..d4105b4 100644
--- a/Tests/RunCMake/LinkLibrariesProcessing/RunCMakeTest.cmake
+++ b/Tests/RunCMake/LinkLibrariesProcessing/RunCMakeTest.cmake
@@ -1,7 +1,7 @@
 include(RunCMake)
 
 run_cmake(Invalid_ORDER)
-run_cmake(Invalid_UNICITY)
+run_cmake(Invalid_DEDUPLICATION)
 run_cmake(InvalidConfiguration1)
 run_cmake(InvalidConfiguration2)
 run_cmake(InvalidConfiguration3)
diff --git a/Tests/RunCMake/add_subdirectory/ChangeConfigMulti.cmake b/Tests/RunCMake/add_subdirectory/ChangeConfigMulti.cmake
new file mode 100644
index 0000000..449c5c8
--- /dev/null
+++ b/Tests/RunCMake/add_subdirectory/ChangeConfigMulti.cmake
@@ -0,0 +1 @@
+add_subdirectory(ChangeConfigMulti)
diff --git a/Tests/RunCMake/add_subdirectory/ChangeConfigMulti/CMakeLists.txt b/Tests/RunCMake/add_subdirectory/ChangeConfigMulti/CMakeLists.txt
new file mode 100644
index 0000000..3ea7fc5
--- /dev/null
+++ b/Tests/RunCMake/add_subdirectory/ChangeConfigMulti/CMakeLists.txt
@@ -0,0 +1 @@
+set(CMAKE_CONFIGURATION_TYPES NotDebug NotRelease)
diff --git a/Tests/RunCMake/add_subdirectory/RunCMakeTest.cmake b/Tests/RunCMake/add_subdirectory/RunCMakeTest.cmake
index 3c70d07..801abae 100644
--- a/Tests/RunCMake/add_subdirectory/RunCMakeTest.cmake
+++ b/Tests/RunCMake/add_subdirectory/RunCMakeTest.cmake
@@ -7,6 +7,10 @@
 run_cmake(System)
 unset(RunCMake_TEST_OPTIONS)
 
+if(RunCMake_GENERATOR_IS_MULTI_CONFIG)
+  run_cmake_with_options(ChangeConfigMulti "-DCMAKE_CONFIGURATION_TYPES=Debug\\;Release")
+endif()
+
 macro(run_cmake_install case)
   set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${case}-build)
   set(RunCMake_TEST_NO_CLEAN 1)
diff --git a/Tests/RunCMake/file-MAKE_DIRECTORY/CMakeLists.txt b/Tests/RunCMake/file-MAKE_DIRECTORY/CMakeLists.txt
new file mode 100644
index 0000000..93ee9df
--- /dev/null
+++ b/Tests/RunCMake/file-MAKE_DIRECTORY/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.5)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/file-MAKE_DIRECTORY/MAKE_DIRECTORY-Result-many-dirs-FAIL-stdout.txt b/Tests/RunCMake/file-MAKE_DIRECTORY/MAKE_DIRECTORY-Result-many-dirs-FAIL-stdout.txt
new file mode 100644
index 0000000..63d46fd
--- /dev/null
+++ b/Tests/RunCMake/file-MAKE_DIRECTORY/MAKE_DIRECTORY-Result-many-dirs-FAIL-stdout.txt
@@ -0,0 +1,3 @@
+^-- Result=Failed to create directory: [^
+]*/Tests/RunCMake/file-MAKE_DIRECTORY/MAKE_DIRECTORY-Result-many-dirs-FAIL-build/file/directory0 Error: [^
+]*$
diff --git a/Tests/RunCMake/file-MAKE_DIRECTORY/MAKE_DIRECTORY-Result-many-dirs-FAIL.cmake b/Tests/RunCMake/file-MAKE_DIRECTORY/MAKE_DIRECTORY-Result-many-dirs-FAIL.cmake
new file mode 100644
index 0000000..0cfccbf
--- /dev/null
+++ b/Tests/RunCMake/file-MAKE_DIRECTORY/MAKE_DIRECTORY-Result-many-dirs-FAIL.cmake
@@ -0,0 +1,9 @@
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/file" "")
+
+file(MAKE_DIRECTORY
+  "${CMAKE_CURRENT_BINARY_DIR}/file/directory0"
+  "${CMAKE_CURRENT_BINARY_DIR}/file/directory1"
+  "${CMAKE_CURRENT_BINARY_DIR}/file/directory2"
+  RESULT resultVal
+)
+message(STATUS "Result=${resultVal}")
diff --git a/Tests/RunCMake/file-MAKE_DIRECTORY/MAKE_DIRECTORY-Result-many-dirs-SUCCESS-stdout.txt b/Tests/RunCMake/file-MAKE_DIRECTORY/MAKE_DIRECTORY-Result-many-dirs-SUCCESS-stdout.txt
new file mode 100644
index 0000000..09df4f9
--- /dev/null
+++ b/Tests/RunCMake/file-MAKE_DIRECTORY/MAKE_DIRECTORY-Result-many-dirs-SUCCESS-stdout.txt
@@ -0,0 +1 @@
+^-- Result=0
diff --git a/Tests/RunCMake/file-MAKE_DIRECTORY/MAKE_DIRECTORY-Result-many-dirs-SUCCESS.cmake b/Tests/RunCMake/file-MAKE_DIRECTORY/MAKE_DIRECTORY-Result-many-dirs-SUCCESS.cmake
new file mode 100644
index 0000000..e0781ce
--- /dev/null
+++ b/Tests/RunCMake/file-MAKE_DIRECTORY/MAKE_DIRECTORY-Result-many-dirs-SUCCESS.cmake
@@ -0,0 +1,7 @@
+file(MAKE_DIRECTORY
+  "${CMAKE_CURRENT_BINARY_DIR}/file/directory0"
+  "${CMAKE_CURRENT_BINARY_DIR}/file/directory1"
+  "${CMAKE_CURRENT_BINARY_DIR}/file/directory2"
+  RESULT resultVal
+)
+message(STATUS "Result=${resultVal}")
diff --git a/Tests/RunCMake/file-MAKE_DIRECTORY/MAKE_DIRECTORY-Result-one-dir-FAIL-stdout.txt b/Tests/RunCMake/file-MAKE_DIRECTORY/MAKE_DIRECTORY-Result-one-dir-FAIL-stdout.txt
new file mode 100644
index 0000000..5d16178
--- /dev/null
+++ b/Tests/RunCMake/file-MAKE_DIRECTORY/MAKE_DIRECTORY-Result-one-dir-FAIL-stdout.txt
@@ -0,0 +1,3 @@
+^-- Result=Failed to create directory: [^
+]*/Tests/RunCMake/file-MAKE_DIRECTORY/MAKE_DIRECTORY-Result-one-dir-FAIL-build/file/directory Error: [^
+]*$
diff --git a/Tests/RunCMake/file-MAKE_DIRECTORY/MAKE_DIRECTORY-Result-one-dir-FAIL.cmake b/Tests/RunCMake/file-MAKE_DIRECTORY/MAKE_DIRECTORY-Result-one-dir-FAIL.cmake
new file mode 100644
index 0000000..0287d67
--- /dev/null
+++ b/Tests/RunCMake/file-MAKE_DIRECTORY/MAKE_DIRECTORY-Result-one-dir-FAIL.cmake
@@ -0,0 +1,3 @@
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/file" "")
+file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/file/directory" RESULT resultVal)
+message(STATUS "Result=${resultVal}")
diff --git a/Tests/RunCMake/file-MAKE_DIRECTORY/MAKE_DIRECTORY-Result-one-dir-SUCCESS-stdout.txt b/Tests/RunCMake/file-MAKE_DIRECTORY/MAKE_DIRECTORY-Result-one-dir-SUCCESS-stdout.txt
new file mode 100644
index 0000000..09df4f9
--- /dev/null
+++ b/Tests/RunCMake/file-MAKE_DIRECTORY/MAKE_DIRECTORY-Result-one-dir-SUCCESS-stdout.txt
@@ -0,0 +1 @@
+^-- Result=0
diff --git a/Tests/RunCMake/file-MAKE_DIRECTORY/MAKE_DIRECTORY-Result-one-dir-SUCCESS.cmake b/Tests/RunCMake/file-MAKE_DIRECTORY/MAKE_DIRECTORY-Result-one-dir-SUCCESS.cmake
new file mode 100644
index 0000000..3005b83
--- /dev/null
+++ b/Tests/RunCMake/file-MAKE_DIRECTORY/MAKE_DIRECTORY-Result-one-dir-SUCCESS.cmake
@@ -0,0 +1,2 @@
+file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/file/directory" RESULT resultVal)
+message(STATUS "Result=${resultVal}")
diff --git a/Tests/RunCMake/file/MAKE_DIRECTORY-fail-result.txt b/Tests/RunCMake/file-MAKE_DIRECTORY/MAKE_DIRECTORY-one-dir-FAIL-result.txt
similarity index 100%
rename from Tests/RunCMake/file/MAKE_DIRECTORY-fail-result.txt
rename to Tests/RunCMake/file-MAKE_DIRECTORY/MAKE_DIRECTORY-one-dir-FAIL-result.txt
diff --git a/Tests/RunCMake/file-MAKE_DIRECTORY/MAKE_DIRECTORY-one-dir-FAIL-stderr.txt b/Tests/RunCMake/file-MAKE_DIRECTORY/MAKE_DIRECTORY-one-dir-FAIL-stderr.txt
new file mode 100644
index 0000000..2bc275c
--- /dev/null
+++ b/Tests/RunCMake/file-MAKE_DIRECTORY/MAKE_DIRECTORY-one-dir-FAIL-stderr.txt
@@ -0,0 +1,9 @@
+^CMake Error at [^
+]*/MAKE_DIRECTORY-one-dir-FAIL.cmake:[0-9]+ \(file\):
+  file failed to create directory:
+
+    [^
+]*/Tests/RunCMake/file-MAKE_DIRECTORY/MAKE_DIRECTORY-one-dir-FAIL-build/file/directory
+
+  because: [^
+]+$
diff --git a/Tests/RunCMake/file/MAKE_DIRECTORY-fail.cmake b/Tests/RunCMake/file-MAKE_DIRECTORY/MAKE_DIRECTORY-one-dir-FAIL.cmake
similarity index 100%
rename from Tests/RunCMake/file/MAKE_DIRECTORY-fail.cmake
rename to Tests/RunCMake/file-MAKE_DIRECTORY/MAKE_DIRECTORY-one-dir-FAIL.cmake
diff --git a/Tests/RunCMake/file-MAKE_DIRECTORY/RunCMakeTest.cmake b/Tests/RunCMake/file-MAKE_DIRECTORY/RunCMakeTest.cmake
new file mode 100644
index 0000000..1eacd90
--- /dev/null
+++ b/Tests/RunCMake/file-MAKE_DIRECTORY/RunCMakeTest.cmake
@@ -0,0 +1,7 @@
+include(RunCMake)
+
+run_cmake_script(MAKE_DIRECTORY-one-dir-FAIL)
+run_cmake_script(MAKE_DIRECTORY-Result-one-dir-FAIL)
+run_cmake_script(MAKE_DIRECTORY-Result-one-dir-SUCCESS)
+run_cmake_script(MAKE_DIRECTORY-Result-many-dirs-FAIL)
+run_cmake_script(MAKE_DIRECTORY-Result-many-dirs-SUCCESS)
diff --git a/Tests/RunCMake/file/MAKE_DIRECTORY-fail-stderr.txt b/Tests/RunCMake/file/MAKE_DIRECTORY-fail-stderr.txt
deleted file mode 100644
index 95fccdf..0000000
--- a/Tests/RunCMake/file/MAKE_DIRECTORY-fail-stderr.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-^CMake Error at [^
-]*/MAKE_DIRECTORY-fail.cmake:[0-9]+ \(file\):
-  file failed to create directory:
-
-    [^
-]*/Tests/RunCMake/file/MAKE_DIRECTORY-fail-build/file/directory
-
-  because: [^
-]+$
diff --git a/Tests/RunCMake/file/RunCMakeTest.cmake b/Tests/RunCMake/file/RunCMakeTest.cmake
index be8ee7c..524636d 100644
--- a/Tests/RunCMake/file/RunCMakeTest.cmake
+++ b/Tests/RunCMake/file/RunCMakeTest.cmake
@@ -62,8 +62,6 @@
 run_cmake_script(COPY_FILE-input-missing)
 run_cmake_script(COPY_FILE-output-missing)
 
-run_cmake_script(MAKE_DIRECTORY-fail)
-
 run_cmake_script(RENAME-file-replace)
 run_cmake_script(RENAME-file-to-file)
 run_cmake_script(RENAME-file-to-dir-capture)
diff --git a/Utilities/cmlibuv/CMakeLists.txt b/Utilities/cmlibuv/CMakeLists.txt
index 29dd18e..a0b161b 100644
--- a/Utilities/cmlibuv/CMakeLists.txt
+++ b/Utilities/cmlibuv/CMakeLists.txt
@@ -191,8 +191,8 @@
     src/unix/bsd-ifaddrs.c
     src/unix/darwin.c
     src/unix/darwin-proctitle.c
-    src/unix/no-fsevents.c
-    src/unix/posix-poll.c
+    src/unix/fsevents.c
+    src/unix/kqueue.c
     src/unix/proctitle.c
     )
 endif()
diff --git a/Utilities/cmlibuv/include/uv/darwin.h b/Utilities/cmlibuv/include/uv/darwin.h
index 7eeb194..d226415 100644
--- a/Utilities/cmlibuv/include/uv/darwin.h
+++ b/Utilities/cmlibuv/include/uv/darwin.h
@@ -30,11 +30,6 @@
 # define UV_PLATFORM_SEM_T semaphore_t
 #endif
 
-#if 1 /* FIXME(#25839): use posix poll to avoid kqueue hangs on macOS.  */
-# include "posix.h"
-#else
-#define UV_HAVE_KQUEUE 1
-
 #define UV_IO_PRIVATE_PLATFORM_FIELDS                                         \
   int rcount;                                                                 \
   int wcount;                                                                 \
@@ -58,9 +53,9 @@
   int cf_error;                                                               \
   uv_mutex_t cf_mutex;                                                        \
 
-#endif
-
 #define UV_STREAM_PRIVATE_PLATFORM_FIELDS                                     \
   void* select;                                                               \
 
+#define UV_HAVE_KQUEUE 1
+
 #endif /* UV_DARWIN_H */
diff --git a/Utilities/cmlibuv/src/unix/core.c b/Utilities/cmlibuv/src/unix/core.c
index d0b0e00..83e8b61 100644
--- a/Utilities/cmlibuv/src/unix/core.c
+++ b/Utilities/cmlibuv/src/unix/core.c
@@ -366,6 +366,7 @@
       (uv__has_active_handles(loop) || uv__has_active_reqs(loop)) &&
       QUEUE_EMPTY(&loop->pending_queue) &&
       QUEUE_EMPTY(&loop->idle_handles) &&
+      (loop->flags & UV_LOOP_REAP_CHILDREN) == 0 &&
       loop->closing_handles == NULL)
     return uv__next_timeout(loop);
   return 0;
diff --git a/Utilities/cmlibuv/src/unix/darwin.c b/Utilities/cmlibuv/src/unix/darwin.c
index b9c8084..62f04d3 100644
--- a/Utilities/cmlibuv/src/unix/darwin.c
+++ b/Utilities/cmlibuv/src/unix/darwin.c
@@ -41,7 +41,6 @@
 
 typedef unsigned char UInt8;
 
-#ifdef UV_HAVE_KQUEUE
 int uv__platform_loop_init(uv_loop_t* loop) {
   loop->cf_state = NULL;
 
@@ -55,7 +54,6 @@
 void uv__platform_loop_delete(uv_loop_t* loop) {
   uv__fsevents_loop_delete(loop);
 }
-#endif
 
 
 static void uv__hrtime_init_once(void) {
diff --git a/Utilities/cmlibuv/src/unix/internal.h b/Utilities/cmlibuv/src/unix/internal.h
index f41ee3c..1b10516 100644
--- a/Utilities/cmlibuv/src/unix/internal.h
+++ b/Utilities/cmlibuv/src/unix/internal.h
@@ -272,6 +272,7 @@
 int uv__platform_loop_init(uv_loop_t* loop);
 void uv__platform_loop_delete(uv_loop_t* loop);
 void uv__platform_invalidate_fd(uv_loop_t* loop, int fd);
+int uv__process_init(uv_loop_t* loop);
 
 /* various */
 void uv__async_close(uv_async_t* handle);
diff --git a/Utilities/cmlibuv/src/unix/kqueue.c b/Utilities/cmlibuv/src/unix/kqueue.c
index 5dac76a..581c552 100644
--- a/Utilities/cmlibuv/src/unix/kqueue.c
+++ b/Utilities/cmlibuv/src/unix/kqueue.c
@@ -235,6 +235,9 @@
                   ARRAY_SIZE(events),
                   timeout == -1 ? NULL : &spec);
 
+    if (nfds == -1)
+      assert(errno == EINTR);
+
     if (pset != NULL)
       pthread_sigmask(SIG_UNBLOCK, pset, NULL);
 
@@ -242,36 +245,26 @@
      * timeout == 0 (i.e. non-blocking poll) but there is no guarantee that the
      * operating system didn't reschedule our process while in the syscall.
      */
-    SAVE_ERRNO(uv__update_time(loop));
+    uv__update_time(loop);
 
-    if (nfds == 0) {
-      if (reset_timeout != 0) {
-        timeout = user_timeout;
-        reset_timeout = 0;
-        if (timeout == -1)
-          continue;
-        if (timeout > 0)
-          goto update_timeout;
+    if (nfds == 0 || nfds == -1) {
+      /* If kqueue is empty or interrupted, we might still have children ready
+       * to reap immediately. */
+      if (loop->flags & UV_LOOP_REAP_CHILDREN) {
+        loop->flags &= ~UV_LOOP_REAP_CHILDREN;
+        uv__wait_children(loop);
+        assert((reset_timeout == 0 ? timeout : user_timeout) == 0);
+        return; /* Equivalent to fall-through behavior. */
       }
 
-      assert(timeout != -1);
-      return;
-    }
-
-    if (nfds == -1) {
-      if (errno != EINTR)
-        abort();
-
       if (reset_timeout != 0) {
         timeout = user_timeout;
         reset_timeout = 0;
-      }
-
-      if (timeout == 0)
+      } else if (nfds == 0) {
+        /* Reached the user timeout value. */
+        assert(timeout != -1);
         return;
-
-      if (timeout == -1)
-        continue;
+      }
 
       /* Interrupted by a signal. Update timeout and poll again. */
       goto update_timeout;
@@ -423,13 +416,13 @@
       return;
     }
 
+update_timeout:
     if (timeout == 0)
       return;
 
     if (timeout == -1)
       continue;
 
-update_timeout:
     assert(timeout > 0);
 
     diff = loop->time - base;
diff --git a/Utilities/cmlibuv/src/unix/loop.c b/Utilities/cmlibuv/src/unix/loop.c
index a88e71c..8939926 100644
--- a/Utilities/cmlibuv/src/unix/loop.c
+++ b/Utilities/cmlibuv/src/unix/loop.c
@@ -79,12 +79,9 @@
     goto fail_platform_init;
 
   uv__signal_global_once_init();
-  err = uv_signal_init(loop, &loop->child_watcher);
+  err = uv__process_init(loop);
   if (err)
     goto fail_signal_init;
-
-  uv__handle_unref(&loop->child_watcher);
-  loop->child_watcher.flags |= UV_HANDLE_INTERNAL;
   QUEUE_INIT(&loop->process_handles);
 
   err = uv_rwlock_init(&loop->cloexec_lock);
diff --git a/Utilities/cmlibuv/src/unix/process.c b/Utilities/cmlibuv/src/unix/process.c
index 3427847..ebe185d 100644
--- a/Utilities/cmlibuv/src/unix/process.c
+++ b/Utilities/cmlibuv/src/unix/process.c
@@ -92,8 +92,28 @@
   assert(signum == SIGCHLD);
   uv__wait_children(handle->loop);
 }
+
+
+int uv__process_init(uv_loop_t* loop) {
+  int err;
+
+  err = uv_signal_init(loop, &loop->child_watcher);
+  if (err)
+    return err;
+  uv__handle_unref(&loop->child_watcher);
+  loop->child_watcher.flags |= UV_HANDLE_INTERNAL;
+  return 0;
+}
+
+
+#else
+int uv__process_init(uv_loop_t* loop) {
+  memset(&loop->child_watcher, 0, sizeof(loop->child_watcher));
+  return 0;
+}
 #endif
 
+
 void uv__wait_children(uv_loop_t* loop) {
   uv_process_t* process;
   int exit_status;
@@ -118,6 +138,7 @@
       continue;
     options = 0;
     process->flags &= ~UV_HANDLE_REAP;
+    loop->nfds--;
 #else
     options = WNOHANG;
 #endif
@@ -1070,6 +1091,10 @@
       process->flags |= UV_HANDLE_REAP;
       loop->flags |= UV_LOOP_REAP_CHILDREN;
     }
+    /* This prevents uv__io_poll() from bailing out prematurely, being unaware
+     * that we added an event here for it to react to. We will decrement this
+     * again after the waitpid call succeeds. */
+    loop->nfds++;
 #endif
 
     process->pid = pid;
@@ -1138,6 +1163,8 @@
 void uv__process_close(uv_process_t* handle) {
   QUEUE_REMOVE(&handle->queue);
   uv__handle_stop(handle);
+#ifdef UV_USE_SIGCHLD
   if (QUEUE_EMPTY(&handle->loop->process_handles))
     uv_signal_stop(&handle->loop->child_watcher);
+#endif
 }
diff --git a/Utilities/cmlibuv/src/unix/signal.c b/Utilities/cmlibuv/src/unix/signal.c
index 1133c73..bb70523 100644
--- a/Utilities/cmlibuv/src/unix/signal.c
+++ b/Utilities/cmlibuv/src/unix/signal.c
@@ -279,6 +279,8 @@
 
 
 int uv__signal_loop_fork(uv_loop_t* loop) {
+  if (loop->signal_pipefd[0] == -1)
+    return 0;
   uv__io_stop(loop, &loop->signal_io_watcher, POLLIN);
   uv__close(loop->signal_pipefd[0]);
   uv__close(loop->signal_pipefd[1]);