Merge branch 'release-4.2'
diff --git a/.git-remote-files b/.git-remote-files
new file mode 100644
index 0000000..b1653be
--- /dev/null
+++ b/.git-remote-files
@@ -0,0 +1,5 @@
+[file "update-common.sh" from "https://gitlab.kitware.com/utils/git-import-third-party.git"]
+commit = 8e52fdc2adb7d481798581af64047cbc228fea8e
+branch = master
+target = Utilities/Scripts/update-third-party.bash
+comment = Core third party import logic
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index e5d67a0..110ea49 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -544,6 +544,17 @@
         - .run_dependent
         - .needs_centos7_x86_64
 
+t:cuda13.0-aarch64-nvidia:
+    extends:
+        - .cuda13.0_aarch64_nvidia
+        - .cmake_test_linux_release
+        - .linux_aarch64_tags_cuda_arch_75
+        - .cmake_junit_artifacts
+        - .run_dependent
+        - .needs_centos7_aarch64
+    variables:
+        CMAKE_CI_JOB_NIGHTLY: "true"
+
 t:cuda13.0-nvidia-fastbuild:
     extends:
         - .cuda13.0_nvidia_fastbuild
diff --git a/.gitlab/.gitignore b/.gitlab/.gitignore
index e8f9c98..a4a3ddd 100644
--- a/.gitlab/.gitignore
+++ b/.gitlab/.gitignore
@@ -1,5 +1,6 @@
 # Ignore files known to be downloaded by CI jobs.
 /5.15.1-0-202009071110*
+/6.9.3-0-202509261207*
 /appimagetool
 /bcc*
 /cmake*
@@ -11,7 +12,6 @@
 /innosetup
 /jom
 /llvm*
-/MacOS*
 /mingw
 /msvc*
 /ninja*
diff --git a/.gitlab/ci/configure_cuda13.0_aarch64_nvidia.cmake b/.gitlab/ci/configure_cuda13.0_aarch64_nvidia.cmake
new file mode 100644
index 0000000..71aafcf
--- /dev/null
+++ b/.gitlab/ci/configure_cuda13.0_aarch64_nvidia.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_LIST_DIR}/configure_cuda13.0_nvidia_common.cmake")
diff --git a/.gitlab/ci/configure_macos_package.cmake b/.gitlab/ci/configure_macos_package.cmake
index cdc8fd2..9a86aeb 100644
--- a/.gitlab/ci/configure_macos_package.cmake
+++ b/.gitlab/ci/configure_macos_package.cmake
@@ -1,5 +1,6 @@
 set(CPACK_SYSTEM_NAME "macos-universal" CACHE STRING "")
 set(CMAKE_OSX_DEPLOYMENT_TARGET "10.13" CACHE STRING "")
+set(CMake_GUI_OSX_DEPLOYMENT_TARGET "12" CACHE STRING "")
 set(CMAKE_C_STANDARD "11" CACHE STRING "")
 set(CMAKE_CXX_STANDARD "17" CACHE STRING "")
 
diff --git a/.gitlab/ci/configure_macos_package_common.cmake b/.gitlab/ci/configure_macos_package_common.cmake
index 2ac7ad6..05206bd 100644
--- a/.gitlab/ci/configure_macos_package_common.cmake
+++ b/.gitlab/ci/configure_macos_package_common.cmake
@@ -11,7 +11,6 @@
 set(BUILD_QtDialog "TRUE" CACHE BOOL "")
 set(CMake_GUI_DISTRIBUTE_WITH_Qt_LGPL "3" CACHE STRING "")
 set(CMake_INSTALL_DEPENDENCIES "ON" CACHE BOOL "")
-set(CMAKE_SKIP_RPATH "TRUE" CACHE BOOL "")
 set(CMake_TEST_BOOTSTRAP OFF CACHE BOOL "")
 set(CMake_TEST_NO_FindPackageModeMakefileTest "TRUE" CACHE BOOL "")
 
diff --git a/.gitlab/ci/ctest_exclusions.cmake b/.gitlab/ci/ctest_exclusions.cmake
index 30f796b..34aa164 100644
--- a/.gitlab/ci/ctest_exclusions.cmake
+++ b/.gitlab/ci/ctest_exclusions.cmake
@@ -34,6 +34,7 @@
     "^RunCMake.Autogen_Qt6_1$"
     "^RunCMake.GoogleTest$"
     "^RunCMake.CXXModules$"
+    "^RunCMake.CXXModulesCompile$"
     "^RunCMake.CommandLine$"
 
     # Too spurious under Valgrind.
@@ -41,6 +42,20 @@
     )
 endif()
 
+if ("$ENV{CMAKE_CONFIGURATION}" MATCHES "_xcode")
+  list(APPEND test_exclusions
+    # FIXME(#27358): Qt6Autogen.RerunMocOnAddFile fails in Xcode.
+    "^Qt6Autogen.RerunMocOnAddFile$"
+    )
+endif()
+
+if ("$ENV{CMAKE_CONFIGURATION}" MATCHES "^macos_x86_64_")
+  list(APPEND test_exclusions
+    # FIXME(#27376): CMakeGUI's simpleConfigure:fail case hangs.
+    "^CMakeGUI$"
+    )
+endif()
+
 string(REPLACE ";" "|" test_exclusions "${test_exclusions}")
 if (test_exclusions)
   set(test_exclusions "(${test_exclusions})")
diff --git a/.gitlab/ci/docker/cuda13.0-aarch64/Dockerfile b/.gitlab/ci/docker/cuda13.0-aarch64/Dockerfile
new file mode 100644
index 0000000..1dc4131
--- /dev/null
+++ b/.gitlab/ci/docker/cuda13.0-aarch64/Dockerfile
@@ -0,0 +1,32 @@
+# syntax=docker/dockerfile:1
+
+ARG BASE_IMAGE=kitware/nvidia-cuda:13.0.1-devel-ubuntu24.04
+
+FROM ${BASE_IMAGE} AS apt-config
+ADD https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2404/sbsa/cuda-keyring_1.1-1_all.deb /root/
+RUN --mount=type=tmpfs,target=/var/log \
+    dpkg -i /root/cuda-keyring_1.1-1_all.deb \
+ && rm /root/cuda-keyring_1.1-1_all.deb /etc/apt/sources.list.d/cuda.list
+
+FROM apt-config AS apt-cache
+# Populate APT cache w/ the fresh metadata and prefetch packages.
+# Use an empty `docker-clean` file to "hide" the image-provided
+# file to disallow removing packages after `apt-get` operations.
+RUN --mount=type=tmpfs,target=/var/log \
+    --mount=type=bind,source=docker-clean,target=/etc/apt/apt.conf.d/docker-clean \
+    --mount=type=bind,source=deps_packages.lst,target=/root/deps_packages.lst \
+    apt-get update \
+ && apt-get --download-only -y install $(grep -h '^[^#]\+$' /root/*.lst)
+
+FROM apt-config
+MAINTAINER Brad King <brad.king@kitware.com>
+
+RUN --mount=type=bind,source=install_deps.sh,target=/root/install_deps.sh \
+    --mount=type=bind,source=deps_packages.lst,target=/root/deps_packages.lst \
+    --mount=type=bind,source=dpkg-exclude,target=/etc/dpkg/dpkg.cfg.d/exclude \
+    --mount=type=bind,source=docker-clean,target=/etc/apt/apt.conf.d/docker-clean \
+    --mount=type=cache,from=apt-cache,source=/var/lib/apt/lists,target=/var/lib/apt/lists \
+    --mount=type=cache,from=apt-cache,source=/var/cache/apt,target=/var/cache/apt,sharing=private \
+    --mount=type=tmpfs,target=/var/log \
+    --mount=type=tmpfs,target=/tmp \
+    sh /root/install_deps.sh
diff --git a/.gitlab/ci/docker/cuda13.0-aarch64/deps_packages.lst b/.gitlab/ci/docker/cuda13.0-aarch64/deps_packages.lst
new file mode 100644
index 0000000..4637272
--- /dev/null
+++ b/.gitlab/ci/docker/cuda13.0-aarch64/deps_packages.lst
@@ -0,0 +1,11 @@
+# Host tools
+curl
+git
+unzip
+
+# Compilers
+g++
+
+# CUDA Dependencies
+ocl-icd-opencl-dev
+opencl-headers
diff --git a/.gitlab/ci/docker/cuda13.0/docker-clean b/.gitlab/ci/docker/cuda13.0-aarch64/docker-clean
similarity index 100%
rename from .gitlab/ci/docker/cuda13.0/docker-clean
rename to .gitlab/ci/docker/cuda13.0-aarch64/docker-clean
diff --git a/.gitlab/ci/docker/cuda13.0/dpkg-exclude b/.gitlab/ci/docker/cuda13.0-aarch64/dpkg-exclude
similarity index 100%
rename from .gitlab/ci/docker/cuda13.0/dpkg-exclude
rename to .gitlab/ci/docker/cuda13.0-aarch64/dpkg-exclude
diff --git a/.gitlab/ci/docker/cuda13.0/install_deps.sh b/.gitlab/ci/docker/cuda13.0-aarch64/install_deps.sh
similarity index 100%
rename from .gitlab/ci/docker/cuda13.0/install_deps.sh
rename to .gitlab/ci/docker/cuda13.0-aarch64/install_deps.sh
diff --git a/.gitlab/ci/docker/cuda13.0/Dockerfile b/.gitlab/ci/docker/cuda13.0-x86_64/Dockerfile
similarity index 100%
rename from .gitlab/ci/docker/cuda13.0/Dockerfile
rename to .gitlab/ci/docker/cuda13.0-x86_64/Dockerfile
diff --git a/.gitlab/ci/docker/cuda13.0/deps_packages.lst b/.gitlab/ci/docker/cuda13.0-x86_64/deps_packages.lst
similarity index 100%
rename from .gitlab/ci/docker/cuda13.0/deps_packages.lst
rename to .gitlab/ci/docker/cuda13.0-x86_64/deps_packages.lst
diff --git a/.gitlab/ci/docker/cuda13.0/docker-clean b/.gitlab/ci/docker/cuda13.0-x86_64/docker-clean
similarity index 100%
copy from .gitlab/ci/docker/cuda13.0/docker-clean
copy to .gitlab/ci/docker/cuda13.0-x86_64/docker-clean
diff --git a/.gitlab/ci/docker/cuda13.0/dpkg-exclude b/.gitlab/ci/docker/cuda13.0-x86_64/dpkg-exclude
similarity index 100%
copy from .gitlab/ci/docker/cuda13.0/dpkg-exclude
copy to .gitlab/ci/docker/cuda13.0-x86_64/dpkg-exclude
diff --git a/.gitlab/ci/docker/cuda13.0/install_deps.sh b/.gitlab/ci/docker/cuda13.0-x86_64/install_deps.sh
similarity index 100%
copy from .gitlab/ci/docker/cuda13.0/install_deps.sh
copy to .gitlab/ci/docker/cuda13.0-x86_64/install_deps.sh
diff --git a/.gitlab/ci/download_qt.cmake b/.gitlab/ci/download_qt.cmake
index d2560dd..3715283 100644
--- a/.gitlab/ci/download_qt.cmake
+++ b/.gitlab/ci/download_qt.cmake
@@ -9,6 +9,8 @@
 set(qt_version "${qt_version_major}.${qt_version_minor}.${qt_version_patch}")
 set(qt_version_nodot "${qt_version_major}${qt_version_minor}${qt_version_patch}")
 
+set(qt_tar_workdir ".gitlab")
+
 # Files needed to download.
 set(qt_files)
 if ("$ENV{CMAKE_CONFIGURATION}" MATCHES "windows.*package")
@@ -61,14 +63,19 @@
   set(qt_url_path "${qt_platform}/desktop/qt5_${qt_version_nodot}/qt.qt5.${qt_version_nodot}.${qt_abi}")
 elseif ("$ENV{CMAKE_CONFIGURATION}" MATCHES "macos")
   if ("$ENV{CMAKE_CONFIGURATION}" MATCHES "macos10.10_package")
+    set(qt_url_root "https://cmake.org/files/dependencies")
+    set(qt_url_path "")
     list(APPEND qt_files "qt-5.9.9-macosx10.10-x86_64-arm64.tar.xz")
     set(qt_subdir "qt-5.9.9-macosx10.10-x86_64-arm64")
   else ()
-    list(APPEND qt_files "qt-5.15.2-macosx10.13-x86_64-arm64.tar.xz")
-    set(qt_subdir "qt-5.15.2-macosx10.13-x86_64-arm64")
+    # This URL is only visible inside of Kitware's network.
+    # Please use your own Qt Account to obtain these files.
+    set(qt_url_root "https://www.paraview.org/files/dependencies/internal/qt")
+    set(qt_url_path "mac_x64/desktop/qt6_693/qt6_693/qt.qt6.693.clang_64")
+    list(APPEND qt_files "6.9.3-0-202509261207qtbase-MacOS-MacOS_15-Clang-MacOS-MacOS_15-X86_64-ARM64.7z")
+    set(qt_subdir "qt-extract")
+    set(qt_tar_workdir ".gitlab/${qt_subdir}")
   endif()
-  set(qt_url_root "https://cmake.org/files/dependencies")
-  set(qt_url_path "")
 else()
   message(FATAL_ERROR "Unknown OS to use for Qt")
 endif ()
@@ -109,12 +116,13 @@
   endif ()
 
   # Extract the file.
+  file(MAKE_DIRECTORY "${qt_tar_workdir}")
   execute_process(
     COMMAND
       "${CMAKE_COMMAND}"
       -E tar
-      xf "${qt_file}"
-    WORKING_DIRECTORY ".gitlab"
+      xf "${CMAKE_CURRENT_SOURCE_DIR}/.gitlab/${qt_file}"
+    WORKING_DIRECTORY "${qt_tar_workdir}"
     RESULT_VARIABLE res
     ERROR_VARIABLE err
     ERROR_STRIP_TRAILING_WHITESPACE)
diff --git a/.gitlab/ci/download_qt_hashes.cmake b/.gitlab/ci/download_qt_hashes.cmake
index 1b9cf14..e544807 100644
--- a/.gitlab/ci/download_qt_hashes.cmake
+++ b/.gitlab/ci/download_qt_hashes.cmake
@@ -11,7 +11,7 @@
 set("5.15.1-0-202009071110qtbase-MacOS-MacOS_10_13-Clang-MacOS-MacOS_10_13-X86_64.7z_hash" df2813ce7c6cb4287abd7956cd1cb9d08312e4ac1208b6cb57af4df11b8ebba1)
 
 set("qt-5.9.9-macosx10.10-x86_64-arm64.tar.xz_hash" d4449771afa0bc6a809c14f1e6d939e7732494cf059503ae451e2bfe8fc60cc1)
-set("qt-5.15.2-macosx10.13-x86_64-arm64.tar.xz_hash" 7b9463a01c8beeee5bf8d01c70deff2d08561cd20aaf6f7a2f41cf8b68ce8a6b)
+set("6.9.3-0-202509261207qtbase-MacOS-MacOS_15-Clang-MacOS-MacOS_15-X86_64-ARM64.7z_hash" 805144e619b7c7b0e9c985d929e1f290241d88b884218db3ad7d56bd579d6b4a)
 
 set("qt-5.15.10-win-i386-msvc_v142-1.zip_hash" c158cebc054d3f4f09733772a8a04789e2884912d45782e8c0c5e6a0b2773e92)
 set("qt-5.15.10-win-x86_64-msvc_v142-1.zip_hash" d55c017aef359f6aa8c592b18ba13cc120c749417b55671548970690126cd139)
diff --git a/.gitlab/ci/env_macos_package.sh b/.gitlab/ci/env_macos_package.sh
deleted file mode 100644
index e810f63..0000000
--- a/.gitlab/ci/env_macos_package.sh
+++ /dev/null
@@ -1 +0,0 @@
-. .gitlab/ci/macos-env.sh
diff --git a/.gitlab/ci/macos-env.sh b/.gitlab/ci/macos-env.sh
deleted file mode 100644
index 1b8ad8e..0000000
--- a/.gitlab/ci/macos-env.sh
+++ /dev/null
@@ -1,2 +0,0 @@
-.gitlab/ci/macos.sh
-export SDKROOT="$PWD/.gitlab/MacOSX.sdk"
diff --git a/.gitlab/ci/macos.sh b/.gitlab/ci/macos.sh
deleted file mode 100755
index 7e947a2..0000000
--- a/.gitlab/ci/macos.sh
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/bin/sh
-
-set -e
-
-# This URL is only visible inside of Kitware's network.
-baseurl="https://cmake.org/files/dependencies/internal/macos"
-
-case "$(uname -s)-$(uname -m)" in
-    Darwin-*)
-        shatool="shasum -a 256"
-        sha256sum="427612880d6c40bcef2b0ecb39d92b057ee7a43ec3552fbd4449859991eb1cc6"
-        tarball="MacOSX15.5.sdk.tar.bz2"
-        ;;
-    *)
-        echo "Unrecognized platform $(uname -s)-$(uname -m)"
-        exit 1
-        ;;
-esac
-readonly shatool
-readonly sha256sum
-
-cd .gitlab
-
-echo "$sha256sum  $tarball" > macos.sha256sum
-curl -OL "$baseurl/$tarball"
-$shatool --check macos.sha256sum
-tar xjf "$tarball"
-rm "$tarball" macos.sha256sum
diff --git a/.gitlab/ci/repackage/macos.sh b/.gitlab/ci/repackage/macos.sh
deleted file mode 100755
index 3499001..0000000
--- a/.gitlab/ci/repackage/macos.sh
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/usr/bin/env bash
-
-set -e
-
-sdkPath="$(xcrun --show-sdk-path)"
-sdkVers="$(xcrun --show-sdk-version)"
-
-tar cjf "MacOSX${sdkVers}.sdk.tar.bz2" -C "${sdkPath%/*}" --no-fflags "MacOSX.sdk"
diff --git a/.gitlab/os-linux.yml b/.gitlab/os-linux.yml
index e90a245..5651060 100644
--- a/.gitlab/os-linux.yml
+++ b/.gitlab/os-linux.yml
@@ -532,6 +532,18 @@
         CTEST_NO_WARNINGS_ALLOWED: 1
         CMAKE_GENERATOR: "FASTBuild"
 
+.cuda13.0_aarch64:
+    extends: .cuda
+    image: "kitware/cmake:ci-cuda13.0-aarch64-2025-10-31"
+    variables:
+        CMAKE_ARCH: aarch64
+
+.cuda13.0_aarch64_nvidia:
+    extends: .cuda13.0_aarch64
+    variables:
+        CMAKE_CONFIGURATION: cuda13.0_aarch64_nvidia
+        CTEST_NO_WARNINGS_ALLOWED: 1
+
 ### HIP builds
 
 .hip6.3:
@@ -708,6 +720,13 @@
         - docker
         - linux-aarch64
 
+.linux_aarch64_tags_cuda_arch_75:
+    tags:
+        - cmake
+        - cuda-arch-75
+        - docker
+        - linux-aarch64
+
 ## Linux-specific scripts
 
 .before_script_linux: &before_script_linux
diff --git a/Auxiliary/CMakeLists.txt b/Auxiliary/CMakeLists.txt
index c0aebef..ff6d308 100644
--- a/Auxiliary/CMakeLists.txt
+++ b/Auxiliary/CMakeLists.txt
@@ -1,16 +1,16 @@
 # Install Vim files to a typical system integration directory.
 # Packagers can set CMake_INSTALL_VIMFILES_DIR to control this.
 if(NOT CMake_INSTALL_VIMFILES_DIR)
-  set(CMake_INSTALL_VIMFILES_DIR ${CMAKE_XDGDATA_DIR}/vim/vimfiles)
+  set(CMake_INSTALL_VIMFILES_DIR ${CMake_INSTALL_XDGDATA_DIR}/vim/vimfiles)
 endif()
 install(DIRECTORY vim/indent vim/syntax DESTINATION ${CMake_INSTALL_VIMFILES_DIR})
 
 # Install Emacs files to a typical system integration directory.
 # Packagers can set CMake_INSTALL_EMACS_DIR to control this.
 if(NOT CMake_INSTALL_EMACS_DIR)
-  set(CMake_INSTALL_EMACS_DIR ${CMAKE_XDGDATA_DIR}/emacs/site-lisp)
+  set(CMake_INSTALL_EMACS_DIR ${CMake_INSTALL_XDGDATA_DIR}/emacs/site-lisp)
 endif()
 install(FILES cmake-mode.el DESTINATION ${CMake_INSTALL_EMACS_DIR})
 
-install(FILES cmake.m4 DESTINATION ${CMAKE_XDGDATA_DIR}/aclocal)
+install(FILES cmake.m4 DESTINATION ${CMake_INSTALL_XDGDATA_DIR}/aclocal)
 add_subdirectory (bash-completion)
diff --git a/Auxiliary/bash-completion/CMakeLists.txt b/Auxiliary/bash-completion/CMakeLists.txt
index 93b6ffd..2c9e448 100644
--- a/Auxiliary/bash-completion/CMakeLists.txt
+++ b/Auxiliary/bash-completion/CMakeLists.txt
@@ -15,7 +15,7 @@
     set(CMake_INSTALL_BASH_COMP_DIR "${CMAKE_BASH_COMP_DIR}")
   else()
     # Default.
-    set(CMake_INSTALL_BASH_COMP_DIR ${CMAKE_XDGDATA_DIR}/bash-completion/completions)
+    set(CMake_INSTALL_BASH_COMP_DIR ${CMake_INSTALL_XDGDATA_DIR}/bash-completion/completions)
   endif()
 endif()
 install(FILES cmake cpack ctest DESTINATION ${CMake_INSTALL_BASH_COMP_DIR})
diff --git a/Tests/RunCMake/CXXModules/examples/circular-build-result.txt b/CMP0207-NEW-all-result.txt
similarity index 100%
copy from Tests/RunCMake/CXXModules/examples/circular-build-result.txt
copy to CMP0207-NEW-all-result.txt
diff --git a/CMP0207-NEW-all-stderr.txt b/CMP0207-NEW-all-stderr.txt
new file mode 100644
index 0000000..4df8527
--- /dev/null
+++ b/CMP0207-NEW-all-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Error at cmake_install\.cmake:[0-9]+ \(file\):
+  file Could not resolve runtime dependencies:
+
+    [^
+]*test\.dll$
diff --git a/CMakeCPack.cmake b/CMakeCPack.cmake
index f38fe6d..b0e5848 100644
--- a/CMakeCPack.cmake
+++ b/CMakeCPack.cmake
@@ -177,7 +177,7 @@
     endif()
   endif()
   install(FILES "${CMake_SOURCE_DIR}/Source/QtIFW/cmake.org.html"
-    DESTINATION "${CMAKE_DOC_DIR}"
+    DESTINATION "${CMake_INSTALL_DOC_DIR}"
   )
 endif()
 
@@ -220,7 +220,7 @@
 set(CPACK_PACKAGE_CONTACT "cmake+development@discourse.cmake.org")
 
 if(UNIX)
-  set(CPACK_STRIP_FILES "${CMAKE_BIN_DIR}/ccmake;${CMAKE_BIN_DIR}/cmake;${CMAKE_BIN_DIR}/cpack;${CMAKE_BIN_DIR}/ctest")
+  set(CPACK_STRIP_FILES "${CMake_INSTALL_BIN_DIR}/ccmake;${CMake_INSTALL_BIN_DIR}/cmake;${CMake_INSTALL_BIN_DIR}/cpack;${CMake_INSTALL_BIN_DIR}/ctest")
   set(CPACK_SOURCE_STRIP_FILES "")
   set(CPACK_PACKAGE_EXECUTABLES "ccmake" "CMake")
 endif()
diff --git a/CMakeCPackOptions.cmake.in b/CMakeCPackOptions.cmake.in
index 65f266e..fe7cab2 100644
--- a/CMakeCPackOptions.cmake.in
+++ b/CMakeCPackOptions.cmake.in
@@ -13,7 +13,7 @@
   set(CPACK_PACKAGE_ICON "@CMake_SOURCE_DIR@/Utilities/Release\\CMakeInstall.bmp")
   # tell cpack to create links to the doc files
   set(CPACK_NSIS_MENU_LINKS
-    "@CMAKE_DOC_DIR@/html/index.html" "CMake Documentation"
+    "@CMake_INSTALL_DOC_DIR@/html/index.html" "CMake Documentation"
     "https://cmake.org" "CMake Web Site"
     )
   # Use the icon from cmake-gui for add-remove programs
@@ -241,7 +241,7 @@
     "@CMake_SOURCE_DIR@/Utilities/Release/CMakeLogo.ico"
   )
 
-  set_property(INSTALL "@CMAKE_DOC_DIR@/html/index.html" PROPERTY
+  set_property(INSTALL "@CMake_INSTALL_DOC_DIR@/html/index.html" PROPERTY
     CPACK_START_MENU_SHORTCUTS "CMake Documentation"
   )
 
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 42903e8..5d6d493 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -450,19 +450,6 @@
   # build the utilities
   include(CMakeBuildUtilities)
 
-  if(BUILD_QtDialog)
-    if(APPLE)
-      set(CMAKE_BUNDLE_VERSION
-        "${CMake_VERSION_MAJOR}.${CMake_VERSION_MINOR}.${CMake_VERSION_PATCH}")
-      set(CMAKE_BUNDLE_LOCATION "${CMAKE_INSTALL_PREFIX}")
-      # make sure CMAKE_INSTALL_PREFIX ends in /
-      if(NOT CMAKE_INSTALL_PREFIX MATCHES "/$")
-        string(APPEND CMAKE_INSTALL_PREFIX "/")
-      endif()
-      string(APPEND CMAKE_INSTALL_PREFIX "CMake.app/Contents")
-    endif()
-  endif()
-
   if(UNIX)
     # Install executables with the RPATH set for libraries outside the build tree.
     # This is also suitable for binaries in the build tree.  Avoid re-link on install.
@@ -548,12 +535,12 @@
   install(FILES
     "${CMake_LICENSE_FILE}"
     "${CMake_SOURCE_DIR}/CONTRIBUTORS.rst"
-    DESTINATION ${CMAKE_DOC_DIR})
+    DESTINATION ${CMake_INSTALL_DOC_DIR})
 
   # Install script directories.
   install(
     DIRECTORY Help Modules Templates
-    DESTINATION ${CMAKE_DATA_DIR}
+    DESTINATION ${CMake_INSTALL_DATA_DIR}
     FILE_PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
     DIRECTORY_PERMISSIONS OWNER_READ OWNER_EXECUTE OWNER_WRITE
                           GROUP_READ GROUP_EXECUTE
diff --git a/Help/command/file.rst b/Help/command/file.rst
index 81f2a01..5272590 100644
--- a/Help/command/file.rst
+++ b/Help/command/file.rst
@@ -615,11 +615,12 @@
   emitted.
 
   Specifying ``COPY_ON_ERROR`` enables copying the file as a fallback if
-  creating the link fails.  If the source is a directory, the destination
-  directory will be created if it does not exist, but no files will be copied
-  the from source one.  It can be useful for handling situations such as
+  creating the link fails.  It can be useful for handling situations such as
   ``<original>`` and ``<linkname>`` being on different drives or mount points,
   which would make them unable to support a hard link.
+  If the source is a directory, the destination directory will be created if
+  it does not exist.  Contents of the source directory will be copied to the
+  destination directory unless policy :policy:`CMP0205` is not set to ``NEW``.
 
 .. signature::
   file(CHMOD <files>... <directories>...
@@ -1121,6 +1122,8 @@
 
   The following arguments specify filters for including or excluding libraries
   to be resolved. See below for a full description of how they work.
+  Directory separators in file paths may be matched using forward
+  slashes unless policy :policy:`CMP0207` is not set to ``NEW``.
 
     ``PRE_INCLUDE_REGEXES <regexes>...``
       List of pre-include regexes through which to filter the names of
diff --git a/Help/command/install.rst b/Help/command/install.rst
index f3c4d2f..68caf68 100644
--- a/Help/command/install.rst
+++ b/Help/command/install.rst
@@ -979,7 +979,7 @@
 
     Experimental. Gated by ``CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO``.
 
-  Installs a |CPS|_ file exporting targets for dependent projects:
+  Installs a |CPS|_ ("CPS") file exporting targets for dependent projects:
 
   .. code-block:: cmake
 
@@ -1105,6 +1105,20 @@
   use of ``LOWER_CASE_FILE`` should be consistent between the main package and
   any appendices.
 
+  .. note::
+    Because it is intended to be portable across multiple build tools, CPS
+    may not support all features that are allowed in CMake-script exports.  In
+    particular, support for generator expressions in interface properties is
+    limited at this time to configuration-dependent expressions.
+
+  .. note::
+    This is the recommended way to generate |CPS| package information for a
+    project.  For distributors whose users may require CPS package information
+    when making changes to the project's build files is not practical, the
+    :variable:`CMAKE_INSTALL_EXPORTS_AS_PACKAGE_INFO` variable may be used to
+    generate ``.cps`` files from :command:`install(EXPORT)` calls.  Refer to
+    the variable's documentation for usage and caveats.
+
 .. signature::
   install(RUNTIME_DEPENDENCY_SET <set-name> [...])
 
diff --git a/Help/command/remove_definitions.rst b/Help/command/remove_definitions.rst
index faad16d..74730e5 100644
--- a/Help/command/remove_definitions.rst
+++ b/Help/command/remove_definitions.rst
@@ -1,11 +1,32 @@
 remove_definitions
 ------------------
 
-Remove -D define flags added by :command:`add_definitions`.
+Removes compile definitions added by :command:`add_compile_definitions`, or
+:command:`add_definitions`:
 
 .. code-block:: cmake
 
-  remove_definitions(-DFOO -DBAR ...)
+  remove_definitions([<definitions>...])
 
-Removes flags (added by :command:`add_definitions`) from the compiler
-command line for sources in the current directory and below.
+The arguments are:
+
+``<definitions>...``
+  Zero or more compile definitions.
+
+This command can be also used to remove any flags added by
+:command:`add_definitions`, but it is intended to remove preprocessor
+definitions passed with ``-D``, or ``/D``.
+
+Examples
+^^^^^^^^
+
+In the following example targets of the current directory scope will have
+only ``BAZ`` and ``QUUX`` compile definitions:
+
+.. code-block:: cmake
+
+  add_compile_definitions(FOO BAR BAZ -DQUUX)
+
+  # ...
+
+  remove_definitions(-DFOO -DBAR)
diff --git a/Help/command/try_compile.rst b/Help/command/try_compile.rst
index 181e850..b2fa0f7 100644
--- a/Help/command/try_compile.rst
+++ b/Help/command/try_compile.rst
@@ -320,6 +320,8 @@
 
   * :variable:`CMAKE_CUDA_RUNTIME_LIBRARY`
   * :variable:`CMAKE_ENABLE_EXPORTS`
+  * :variable:`CMAKE_EXECUTABLE_ENABLE_EXPORTS`
+  * :variable:`CMAKE_SHARED_LIBRARY_ENABLE_EXPORTS`
   * :variable:`CMAKE_EXE_LINKER_FLAGS`, unless using CMake versions
     prior to 4.0 without policy :policy:`CMP0056` set to ``NEW``
   * :variable:`CMAKE_LINK_SEARCH_START_STATIC`
diff --git a/Help/cpack_gen/archive.rst b/Help/cpack_gen/archive.rst
index 81da98b..46a377d 100644
--- a/Help/cpack_gen/archive.rst
+++ b/Help/cpack_gen/archive.rst
@@ -100,6 +100,24 @@
   If enabled (``ON``) multiple packages are generated. By default a single package
   containing files of all components is generated.
 
+.. variable:: CPACK_ARCHIVE_UID
+
+  .. versionadded: 4.3
+
+  Set the UID of entries contained in the archive.
+  Specify ``-1`` to use the UID of the current user.
+
+  :Default: ``0`` (see policy :policy:`CMP0206`)
+
+.. variable:: CPACK_ARCHIVE_GID
+
+  .. versionadded: 4.3
+
+  Set the GID of entries contained in the archive.
+  Specify ``-1`` to use the GID of the current user.
+
+  :Default: ``0`` (see policy :policy:`CMP0206`)
+
 Variables used by CPack Archive generator
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
diff --git a/Help/dev/source.rst b/Help/dev/source.rst
index d8de4e1..c36f334 100644
--- a/Help/dev/source.rst
+++ b/Help/dev/source.rst
@@ -111,7 +111,8 @@
     ``cm::shared_lock``
 
   * ``<cm/type_traits>``:
-    ``cm::enable_if_t``
+    ``cm::conditional_t``, ``cm::decay_t``, ``cm::enable_if_t``,
+    ``cm::remove_cv_t``, ``cm::remove_reference_t``
 
   * ``<cm/unordered_map>``:
     ``cm::cbegin``, ``cm::cend``, ``cm::rbegin``, ``cm::rend``,
@@ -169,7 +170,7 @@
 
   * ``<cm/type_traits>``:
     ``cm::bool_constant``, ``cm::invoke_result_t``, ``cm::invoke_result``,
-    ``cm::void_t``
+    ``cm::is_same_v``, ``cm::void_t``
 
   * ``<cm/unordered_map>``:
     ``cm::size``, ``cm::empty``, ``cm::data``
diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst
index 7474197..ae7ad72 100644
--- a/Help/manual/cmake-generator-expressions.7.rst
+++ b/Help/manual/cmake-generator-expressions.7.rst
@@ -115,6 +115,17 @@
     VERBATIM
   )
 
+For tools that expect ``-I``'s value to be a separate argument, use the
+semicolon trick learned earlier:
+
+.. code-block:: cmake
+
+  add_custom_target(run_some_tool
+    COMMAND some_tool "$<LIST:TRANSFORM,$<TARGET_PROPERTY:tgt,INCLUDE_DIRECTORIES>,PREPEND,-I;>"
+    COMMAND_EXPAND_LISTS
+    VERBATIM
+  )
+
 A common mistake is to try to split a generator expression across multiple
 lines with indenting:
 
@@ -273,20 +284,8 @@
 Other more specific comparison types are documented in their own separate
 sections further below.
 
-String Comparisons
-^^^^^^^^^^^^^^^^^^
-
-.. genex:: $<STREQUAL:string1,string2>
-
-  ``1`` if ``string1`` and ``string2`` are equal, else ``0``.
-  The comparison is case-sensitive.  For a case-insensitive comparison,
-  combine with a :ref:`string transforming generator expression
-  <String Transforming Generator Expressions>`.  For example, the following
-  evaluates to ``1`` if ``${foo}`` is any of ``BAR``, ``Bar``, ``bar``, etc.
-
-  .. code-block:: cmake
-
-    $<STREQUAL:$<UPPER_CASE:${foo}>,BAR>
+Numeric Comparisons
+^^^^^^^^^^^^^^^^^^^
 
 .. genex:: $<EQUAL:value1,value2>
 
@@ -319,10 +318,399 @@
 
   ``1`` if ``v1`` is a version greater than or equal to ``v2``, else ``0``.
 
+String Expressions
+------------------
+
+Most of the expressions in this section are closely associated with the
+:command:`string` command, providing the same capabilities, but in
+the form of a generator expression.
+
+In each of the following string-related generator expressions, the ``string``
+must not contain any commas if that generator expression expects something to
+be provided after the ``string``.  For example, the expression
+``$<STRING:FIND,string,value>`` requires a ``value`` after the ``string``.
+Since a comma is used to separate the ``string`` and the ``value``, the
+``string`` cannot itself contain a comma.  This restriction does not apply to
+the :command:`string` command, it is specific to the string-handling generator
+expressions only. The :genex:`$<COMMA>` generator expression can be used to
+specify a comma as part of the arguments of the string-related generator
+expressions.
+
+.. _`String Comparisons Generator Expressions`:
+
+String Comparisons
+^^^^^^^^^^^^^^^^^^
+
+The comparisons are case-sensitive.  For a case-insensitive comparison,
+combine with a :ref:`string transforming generator expression
+<String Transforming Generator Expressions>`.  For example, the following
+evaluates to ``1`` if ``${foo}`` is any of ``BAR``, ``Bar``, ``bar``, etc.
+
+  .. code-block:: cmake
+
+    $<STREQUAL:$<STRING:TOUPPER,${foo}>,BAR>
+
+.. genex:: $<STREQUAL:string1,string2>
+
+  ``1`` if ``string1`` and ``string2`` are lexicographically equal, else ``0``.
+
+.. genex:: $<STRLESS:string1,string2>
+
+  .. versionadded:: 4.3
+
+  ``1`` if ``string1`` is lexicographically less than ``string2``, else ``0``.
+
+.. genex:: $<STRGREATER:string1,string2>
+
+  .. versionadded:: 4.3
+
+  ``1`` if ``string1`` is lexicographically greater than ``string2``, else
+  ``0``.
+
+.. genex:: $<STRLESS_EQUAL:string1,string2>
+
+  .. versionadded:: 4.3
+
+  ``1`` if ``string1`` is lexicographically less than or equal to ``string2``,
+  else ``0``.
+
+.. genex:: $<STRGREATER_EQUAL:string1,string2>
+
+  .. versionadded:: 4.3
+
+  ``1`` if ``string1`` is lexicographically greater than or equal to
+  ``string2``, else ``0``.
+
+.. _`String Queries Generator Expressions`:
+
+String Queries
+^^^^^^^^^^^^^^
+
+.. genex:: $<STRING:LENGTH,string>
+
+  .. versionadded:: 4.3
+
+  The given string's length in bytes. Note that this means, if ``string``
+  contains multi-byte characters, the result will *not* be the number of
+  characters.
+
+.. genex:: $<STRING:SUBSTRING,string,begin,length>
+
+  .. versionadded:: 4.3
+
+  The substring of the given ``string``. If ``length`` is ``-1`` or greater
+  than the ``string`` length the remainder of the string starting at ``begin``
+  will be returned.
+
+  Both ``begin`` and ``length`` are counted in bytes, so care must
+  be exercised if ``string`` could contain multi-byte characters.
+
+.. genex:: $<STRING:FIND,string[,FROM:(BEGIN|END)],substring>
+
+  The position where the given ``substring`` was found in the supplied
+  ``string``. If the ``substring`` is not found, a position of -1 is returned.
+
+  The ``FROM:`` option defines how the search will be done:
+
+  ``BEGIN``
+    The search will start at the beginning of the ``string``. This the default.
+
+  ``END``
+    The search will start from the end of the ``string``.
+
+  The ``$<STRING:FIND>`` generator expression treats all strings as ASCII-only
+  characters. The index returned will also be counted in bytes, so strings
+  containing multi-byte characters may lead to unexpected results.
+
+.. genex:: $<STRING:MATCH,string[,SEEK:(ONCE|ALL)],regular_expression>
+
+  .. versionadded:: 4.3
+
+  Match, in the ``string``, the ``regular_expression``.
+
+  The ``SEEK:`` option specifies the match behavior:
+
+  ``ONCE``
+    Match only the first occurrence. This is the default.
+
+  ``ALL``
+    Match as many times as possible and return the matches as a list.
+
+  See the :ref:`Regular expressions specification <Regex Specification>` for
+  the syntax of the ``regular_expression`` parameter.
+
+.. _`String Generating Generator Expressions`:
+
+String Generations
+^^^^^^^^^^^^^^^^^^
+
+.. genex:: $<STRING:JOIN,glue,input[,input]...>
+
+  .. versionadded:: 4.3
+
+  Join all the ``input`` arguments together using the ``glue`` string.
+
+.. genex:: $<STRING:ASCII,number[,number]...>
+
+  .. versionadded:: 4.3
+
+  Convert all numbers, in the range 1-255, into corresponding ASCII
+  characters. Any number outside this range will raise an error.
+
+.. genex:: $<STRING:TIMESTAMP[,(UTC|format)]...>
+
+  .. versionadded:: 4.3
+
+  Produce a string representation of the current date and/or time.
+
+  If the generator expression is unable to obtain a timestamp, the result will
+  be the empty string ``""``.
+
+  The optional ``UTC`` flag requests the current date/time representation to
+  be in Coordinated Universal Time (UTC) rather than local time.
+
+  If the ``SOURCE_DATE_EPOCH`` environment variable is set, its value will be
+  used instead of the current time.
+  See https://reproducible-builds.org/specs/source-date-epoch/ for details.
+
+  The optional ``<format>`` may contain the following format specifiers:
+
+  ``%%``
+    A literal percent sign (%).
+
+  ``%d``
+    The day of the current month (01-31).
+
+  ``%H``
+    The hour on a 24-hour clock (00-23).
+
+  ``%I``
+    The hour on a 12-hour clock (01-12).
+
+  ``%j``
+    The day of the current year (001-366).
+
+  ``%m``
+    The month of the current year (01-12).
+
+  ``%b``
+    Abbreviated month name (e.g. Oct).
+
+  ``%B``
+    Full month name (e.g. October).
+
+  ``%M``
+    The minute of the current hour (00-59).
+
+  ``%s``
+    Seconds since midnight (UTC) 1-Jan-1970 (UNIX time).
+
+  ``%S``
+    The second of the current minute.  60 represents a leap second. (00-60)
+
+  ``%f``
+    The microsecond of the current second (000000-999999).
+
+  ``%U``
+    The week number of the current year (00-53).
+
+  ``%V``
+    The ISO 8601 week number of the current year (01-53).
+
+  ``%w``
+    The day of the current week. 0 is Sunday. (0-6)
+
+  ``%a``
+    Abbreviated weekday name (e.g. Fri).
+
+  ``%A``
+    Full weekday name (e.g. Friday).
+
+  ``%y``
+    The last two digits of the current year (00-99).
+
+  ``%Y``
+    The current year.
+
+  ``%z``
+    The offset of the time zone from UTC, in hours and minutes,
+    with format ``+hhmm`` or ``-hhmm``.
+
+  ``%Z``
+    The time zone name.
+
+  Unknown format specifiers will be ignored and copied to the output
+  as-is.
+
+  If no explicit ``format`` is given, it will default to:
+
+  * ``%Y-%m-%dT%H:%M:%S`` for local time.
+  * ``%Y-%m-%dT%H:%M:%SZ`` for UTC.
+
+.. genex:: $<STRING:RANDOM[,(LENGTH:length|ALPHABET:alphabet|RANDOM_SEED:seed)]...>
+
+  .. versionadded:: 4.3
+
+  Produce a random string of ASCII characters. The possible options are:
+
+  ``LENGTH:length``
+    Define the length of the string. The default length is 5 characters.
+
+  ``ALPHABET:alphabet``
+    Define the characters used for the generation. The alphabet is always
+    interpreted as holding ASCII characters. The default alphabet is all
+    numbers and upper and lower case letters.
+
+  ``RANDOM_SEED:seed``
+    Specify an integer which will be used to seed the random number generator.
+
+.. genex:: $<STRING:UUID,NAMESPACE:namespace,TYPE:(MD5|SHA1)[,NAME:name][,CASE:(LOWER|UPPER)]>
+
+  .. versionadded:: 4.3
+
+  Create a universally unique identifier (aka GUID) as per RFC4122.
+  A UUID has the format ``xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx``
+  where each ``x`` represents an hexadecimal character.
+
+  The UUID is based on the hash of the combined values of:
+
+  ``NAMESPACE:namespace``
+    ``namespace`` which has to be a valid UUID.
+
+  ``NAME:name``
+    ``name`` is an arbitrary string.
+
+  ``TYPE:``
+    The hash algorithm can be either:
+
+    ``MD5``
+      Version 3 UUID.
+
+    ``SHA1``
+      Version 5 UUID.
+
+  ``CASE:``
+    Specify the case of the hexadecimal characters.
+
+    ``LOWER``
+      Hexadecimal characters are all of lowercase. This is the default.
+
+    ``UPPER``
+      Hexadecimal characters are all of uppercase.
+
 .. _`String Transforming Generator Expressions`:
 
 String Transformations
-----------------------
+^^^^^^^^^^^^^^^^^^^^^^
+
+.. genex:: $<STRING:REPLACE[,(STRING|REGEX)],string,match_string,replace_string>
+
+  .. versionadded:: 4.3
+
+  Replace all occurrences of ``match_string`` in the ``string`` with
+  ``replace_string``.
+
+  The ``match_string`` can be of two different types:
+
+  ``STRING``
+    ``match_string`` is a literal string and match will be done by simple
+    string comparison. This is the default.
+
+  ``REGEX``
+    ``match_string`` is a regular expression. Match this regular_expression as
+    many times as possible and substitute the ``replace_string`` for the match
+    in the ``string``.
+
+    The ``replace_string`` may refer to parenthesis-delimited subexpressions of
+    the match using \\1, \\2, ..., \\9. Note that two backslashes (\\\\1) are
+    required in CMake code to get a backslash through argument parsing.
+
+.. genex:: $<STRING:APPEND,string,input[,input]...>
+
+  .. versionadded:: 4.3
+
+  Append all the ``input`` arguments to the ``string``.
+
+.. genex:: $<STRING:PREPEND,string,input[,input]...>
+
+  .. versionadded:: 4.3
+
+  Prepend all the ``input`` arguments to the ``string``.
+
+.. genex:: $<STRING:TOLOWER,string>
+
+  .. versionadded:: 4.3
+
+  Content of ``string`` converted to lower case.
+
+.. genex:: $<STRING:TOUPPER,string>
+
+  .. versionadded:: 4.3
+
+  Content of ``string`` converted to upper case.
+
+.. genex:: $<STRING:STRIP,SPACES,string>
+
+  .. versionadded:: 4.3
+
+  Remove the specified elements from the ``string``. The possible options are:
+
+  ``SPACES``
+    Remove the leading and trailing spaces of the ``string``.
+
+.. genex:: $<STRING:QUOTE,REGEX,string>
+
+  .. versionadded:: 4.3
+
+  Escape the specified elements of the ``string``. The possible options are:
+
+  ``REGEX``
+    Escape all characters that have special meaning in a regular expressions,
+    such that the ``string`` can be used as part of a regular expression to
+    match the input literally.
+
+.. genex:: $<STRING:HEX,string>
+
+  .. versionadded:: 4.3
+
+  Convert each byte in the ``string`` to its hexadecimal representation.
+  Letters in the result (a through f) are in lowercase.
+
+.. genex:: $<STRING:HASH,string,ALGORITHM:algorithm>
+
+  .. versionadded:: 4.3
+
+  Compute a cryptographic hash of the ``string``. The supported algorithm
+  names, as specified by the ``ALGORITHM:`` option are:
+
+  ``MD5``
+    Message-Digest Algorithm 5, RFC 1321.
+  ``SHA1``
+    US Secure Hash Algorithm 1, RFC 3174.
+  ``SHA224``
+    US Secure Hash Algorithms, RFC 4634.
+  ``SHA256``
+    US Secure Hash Algorithms, RFC 4634.
+  ``SHA384``
+    US Secure Hash Algorithms, RFC 4634.
+  ``SHA512``
+    US Secure Hash Algorithms, RFC 4634.
+  ``SHA3_224``
+    Keccak SHA-3.
+  ``SHA3_256``
+    Keccak SHA-3.
+  ``SHA3_384``
+    Keccak SHA-3.
+  ``SHA3_512``
+    Keccak SHA-3.
+
+.. genex:: $<STRING:MAKE_C_IDENTIFIER,string>
+
+  .. versionadded:: 4.3
+
+  Convert each non-alphanumeric character in the ``string`` to an underscore.
+  If the first character of the ``string`` is a digit, an underscore will also
+  be prepended.
 
 .. genex:: $<LOWER_CASE:string>
 
@@ -332,10 +720,10 @@
 
   Content of ``string`` converted to upper case.
 
-.. genex:: $<MAKE_C_IDENTIFIER:...>
+.. genex:: $<MAKE_C_IDENTIFIER:string>
 
-  Content of ``...`` converted to a C identifier.  The conversion follows the
-  same behavior as :command:`string(MAKE_C_IDENTIFIER)`.
+  Content of ``string`` converted to a C identifier.  The conversion follows
+  the same behavior as :command:`string(MAKE_C_IDENTIFIER)`.
 
 List Expressions
 ----------------
diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst
index a477897..97d74ba 100644
--- a/Help/manual/cmake-policies.7.rst
+++ b/Help/manual/cmake-policies.7.rst
@@ -7,6 +7,8 @@
 
    .. contents::
 
+.. _cmake-policies-intro:
+
 Introduction
 ============
 
@@ -34,10 +36,10 @@
 
 .. code-block:: cmake
 
-  cmake_minimum_required(VERSION 3.10...4.1)
+  cmake_minimum_required(VERSION 3.10...4.2)
 
 This uses the ``<min>...<max>`` syntax to enable the ``NEW`` behaviors
-of policies introduced in CMake 4.1 and earlier while only requiring a
+of policies introduced in CMake 4.2 and earlier while only requiring a
 minimum version of CMake 3.10.  The project is expected to work with
 both the ``OLD`` and ``NEW`` behaviors of policies introduced between
 those versions.
@@ -92,6 +94,16 @@
 
 The following policies are supported.
 
+Policies Introduced by CMake 4.3
+--------------------------------
+
+.. toctree::
+   :maxdepth: 1
+
+   CMP0207: file(GET_RUNTIME_DEPENDENCIES) normalizes paths before matching. </policy/CMP0207>
+   CMP0206: The CPack Archive Generator defaults to UID 0 and GID 0. </policy/CMP0206>
+   CMP0205: file(CREATE_LINK) with COPY_ON_ERROR copies directory content. </policy/CMP0205>
+
 Policies Introduced by CMake 4.2
 --------------------------------
 
diff --git a/Help/manual/cmake-presets.7.rst b/Help/manual/cmake-presets.7.rst
index b0f8e03..02195e1 100644
--- a/Help/manual/cmake-presets.7.rst
+++ b/Help/manual/cmake-presets.7.rst
@@ -285,8 +285,11 @@
   preset is ``hidden``). In version ``3`` or above, this field may be
   omitted.
 
+.. _`CMakePresets installDir`:
+
 ``installDir``
-  An optional string representing the path to the installation directory.
+  An optional string representing the path to the installation directory,
+  which will be used as the :variable:`CMAKE_INSTALL_PREFIX` variable.
   This field supports `macro expansion`_. If a relative path is specified,
   it is calculated relative to the source directory. This is allowed in
   preset files specifying version ``3`` or above.
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index 874820f..e958dbd 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -263,6 +263,7 @@
    /variable/CMAKE_INCLUDE_PATH
    /variable/CMAKE_INSTALL_DEFAULT_COMPONENT_NAME
    /variable/CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS
+   /variable/CMAKE_INSTALL_EXPORTS_AS_PACKAGE_INFO
    /variable/CMAKE_INSTALL_MESSAGE
    /variable/CMAKE_INSTALL_PREFIX
    /variable/CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT
@@ -483,7 +484,6 @@
    /variable/CMAKE_DEPENDS_USE_COMPILER
    /variable/CMAKE_DISABLE_PRECOMPILE_HEADERS
    /variable/CMAKE_DLL_NAME_WITH_SOVERSION
-   /variable/CMAKE_ENABLE_EXPORTS
    /variable/CMAKE_EXECUTABLE_ENABLE_EXPORTS
    /variable/CMAKE_EXE_LINKER_FLAGS
    /variable/CMAKE_EXE_LINKER_FLAGS_CONFIG
@@ -896,6 +896,7 @@
 .. toctree::
    :maxdepth: 1
 
+   /variable/CMAKE_ENABLE_EXPORTS
    /variable/CMAKE_IOS_INSTALL_COMBINED
    /variable/CMAKE_LANG_USING_LINKER_MODE
    /variable/CMAKE_USE_RELATIVE_PATHS
diff --git a/Help/manual/cmake.1.rst b/Help/manual/cmake.1.rst
index 316ba25..437440c 100644
--- a/Help/manual/cmake.1.rst
+++ b/Help/manual/cmake.1.rst
@@ -790,9 +790,13 @@
 .. option:: --preset <preset>, --preset=<preset>
 
   Use a build preset to specify build options. The project binary directory
-  is inferred from the ``configurePreset`` key. The current working directory
-  must contain CMake preset files.
-  See :manual:`preset <cmake-presets(7)>` for more details.
+  is inferred from the ``configurePreset`` key unless a directory is specified
+  after ``--build``. The current working directory must contain CMake preset
+  files. See :manual:`preset <cmake-presets(7)>` for more details.
+
+.. versionchanged:: 4.3
+  ``cmake --build`` now supports specifying a build directory and
+    preset together.
 
 .. option:: --list-presets
 
@@ -919,7 +923,23 @@
 
 .. option:: --prefix <prefix>
 
-  Override the installation prefix, :variable:`CMAKE_INSTALL_PREFIX`.
+  Specifies an alternative installation prefix, temporarily replacing the
+  value of the :variable:`CMAKE_INSTALL_PREFIX` variable at the installation
+  phase.
+
+  The main purpose of this option is to allow installation to occur in an
+  arbitrary location.  This is commonly used in certain installation and
+  packaging workflows.  It is analogous to selecting the installation
+  directory during the installation phase.  For example, on Windows, where
+  a user may choose the destination folder for the project.
+
+  .. note::
+
+    When the project is using the :module:`GNUInstallDirs` module, there are
+    some :ref:`special cases <GNUInstallDirs special cases>` that are
+    evaluated based on the value of the :variable:`CMAKE_INSTALL_PREFIX`
+    variable during the configuration phase.  The results persist even if an
+    alternative prefix is used during installation.
 
 .. option:: --strip
 
diff --git a/Help/manual/presets/schema.json b/Help/manual/presets/schema.json
index 63fbdb7..b5a1f3c 100644
--- a/Help/manual/presets/schema.json
+++ b/Help/manual/presets/schema.json
@@ -572,7 +572,7 @@
           },
           "installDir": {
             "type": "string",
-            "description": "An optional string representing the path to the installation directory. This field supports macro expansion. If a relative path is specified, it is calculated relative to the source directory."
+            "description": "An optional string representing the path to the installation directory, which will be used as the CMAKE_INSTALL_PREFIX variable. This field supports macro expansion. If a relative path is specified, it is calculated relative to the source directory."
           }
         }
       }
diff --git a/Help/policy/CMP0205.rst b/Help/policy/CMP0205.rst
new file mode 100644
index 0000000..b08ef4a
--- /dev/null
+++ b/Help/policy/CMP0205.rst
@@ -0,0 +1,23 @@
+CMP0205
+-------
+
+.. versionadded:: 4.3
+
+:command:`file(CREATE_LINK)` with ``COPY_ON_ERROR`` copies directory content.
+
+The :command:`file(CREATE_LINK)` command's ``COPY_ON_ERROR`` option copies
+the source file to the destination as a fallback if linking it fails.
+If the source is a directory, CMake 4.2 and below create the destination
+directory but do not copy its contents.  CMake 4.3 and above prefer to
+copy the directory contents too.  This policy provides compatibility with
+projects that have not been updated to expect the contents to be copied.
+
+The ``OLD`` behavior for this policy is to create the destination directory
+without copying contents.  The ``NEW`` behavior for this policy to create
+the destination directory and copy contents from the source directory.
+
+.. |INTRODUCED_IN_CMAKE_VERSION| replace:: 4.3
+.. |WARNS_OR_DOES_NOT_WARN| replace:: warns
+.. include:: include/STANDARD_ADVICE.rst
+
+.. include:: include/DEPRECATED.rst
diff --git a/Help/policy/CMP0206.rst b/Help/policy/CMP0206.rst
new file mode 100644
index 0000000..f6ed03d
--- /dev/null
+++ b/Help/policy/CMP0206.rst
@@ -0,0 +1,30 @@
+CMP0206
+-------
+
+.. versionadded:: 4.3
+
+The :cpack_gen:`CPack Archive Generator` defaults to UID 0 and GID 0.
+
+In CMake 4.2 and below, the :cpack_gen:`CPack Archive Generator` always used
+the current user's UID/GID in archive entries.  CMake 4.3 added the
+:variable:`CPACK_ARCHIVE_UID` and :variable:`CPACK_ARCHIVE_GID` variables
+to control them.  If either is set, the default for the other is ``0``.
+If neither is set, CMake 4.3 and above prefer to default both UID and GID
+to ``0`` so that unpacking by ``root`` produces paths owned by ``root``.
+This policy provides compatibility with projects that have not been updated
+to expect the new behavior.
+
+The ``OLD`` behavior for this policy is to produce archive entries with
+the current user's UID/GID by default.
+The ``NEW`` behavior for this policy is to produce archive entries with
+the UID/GID set to 0/0 by default.
+
+.. |INTRODUCED_IN_CMAKE_VERSION| replace:: 4.3
+.. |WARNS_OR_DOES_NOT_WARN| replace:: does *not* warn
+.. include:: include/STANDARD_ADVICE.rst
+
+See documentation of the
+:variable:`CMAKE_POLICY_WARNING_CMP0206 <CMAKE_POLICY_WARNING_CMP<NNNN>>`
+variable to control the warning.
+
+.. include:: include/DEPRECATED.rst
diff --git a/Help/policy/CMP0207.rst b/Help/policy/CMP0207.rst
new file mode 100644
index 0000000..b544bd2
--- /dev/null
+++ b/Help/policy/CMP0207.rst
@@ -0,0 +1,26 @@
+CMP0207
+-------
+
+.. versionadded:: 4.3
+
+:command:`file(GET_RUNTIME_DEPENDENCIES)` normalizes paths before matching.
+
+The :command:`file(GET_RUNTIME_DEPENDENCIES)` and
+:command:`install(RUNTIME_DEPENDENCY_SET)` commands support filtering
+resolved dependencies using regular expressions matching their paths.
+In CMake 4.2 and below, callers were responsible for matching both forward
+and backward slashes as path separators on Windows, e.g., via ``[\/]``.
+CMake 4.3 and above prefer to normalize paths to use forward slashes before
+matching.  This policy provides compaitiblity for projects that may have
+been relying on matching backslashes only.
+
+The ``OLD`` behavior for this policy matches filters against paths that
+may contain any combination of forward and backward slashes on Windows.
+The ``NEW`` behavior for this policy to convert all paths to forward
+slashes before matching filters.
+
+.. |INTRODUCED_IN_CMAKE_VERSION| replace:: 4.3
+.. |WARNS_OR_DOES_NOT_WARN| replace:: warns
+.. include:: include/STANDARD_ADVICE.rst
+
+.. include:: include/DEPRECATED.rst
diff --git a/Help/policy/include/DEPRECATED.rst b/Help/policy/include/DEPRECATED.rst
index f66de55..4cec1bb 100644
--- a/Help/policy/include/DEPRECATED.rst
+++ b/Help/policy/include/DEPRECATED.rst
@@ -1,4 +1,4 @@
 .. note::
   The ``OLD`` behavior of a policy is
-  :manual:`deprecated by definition <cmake-policies(7)>`
+  :ref:`deprecated by definition <cmake-policies-intro>`
   and may be removed in a future version of CMake.
diff --git a/Help/release/dev/0-sample-topic.rst b/Help/release/dev/0-sample-topic.rst
new file mode 100644
index 0000000..e4cc01e
--- /dev/null
+++ b/Help/release/dev/0-sample-topic.rst
@@ -0,0 +1,7 @@
+0-sample-topic
+--------------
+
+* This is a sample release note for the change in a topic.
+  Developers should add similar notes for each topic branch
+  making a noteworthy change.  Each document should be named
+  and titled to match the topic name to avoid merge conflicts.
diff --git a/Help/release/dev/CMAKE_ENABLE_EXPORTS.rst b/Help/release/dev/CMAKE_ENABLE_EXPORTS.rst
new file mode 100644
index 0000000..b455f5c
--- /dev/null
+++ b/Help/release/dev/CMAKE_ENABLE_EXPORTS.rst
@@ -0,0 +1,6 @@
+CMAKE_ENABLE_EXPORTS
+--------------------
+
+* The :variable:`CMAKE_ENABLE_EXPORTS` variable is deprecated in favor of
+  the :variable:`CMAKE_EXECUTABLE_ENABLE_EXPORTS` and
+  :variable:`CMAKE_SHARED_LIBRARY_ENABLE_EXPORTS` variables.
diff --git a/Help/release/dev/GenEx-STRING.rst b/Help/release/dev/GenEx-STRING.rst
new file mode 100644
index 0000000..5df81bf
--- /dev/null
+++ b/Help/release/dev/GenEx-STRING.rst
@@ -0,0 +1,8 @@
+GenEx-STRING
+------------
+
+* :genex:`$<STRING:...>` generator expressions were added for
+  :ref:`query <String Queries Generator Expressions>`,
+  :ref:`generation <String Generating Generator Expressions>`, and
+  :ref:`transformation <String Transforming Generator Expressions>` operations
+  on strings.
diff --git a/Help/release/dev/GenEx-string-comparisons.rst b/Help/release/dev/GenEx-string-comparisons.rst
new file mode 100644
index 0000000..8c00711
--- /dev/null
+++ b/Help/release/dev/GenEx-string-comparisons.rst
@@ -0,0 +1,5 @@
+GenEx-string-comparisons
+------------------------
+
+* CMake gains new :ref:`generator expressions
+  <String Comparisons Generator Expressions>` for string comparisons.
diff --git a/Help/release/dev/UseJava-include-modules.rst b/Help/release/dev/UseJava-include-modules.rst
new file mode 100644
index 0000000..a26e8ee
--- /dev/null
+++ b/Help/release/dev/UseJava-include-modules.rst
@@ -0,0 +1,7 @@
+UseJava-include-modules
+-----------------------
+
+* The :module:`UseJava` module's :command:`add_jar` command now accepts a new
+  option `INCLUDE_MODULES` that adds its arguments to the `--module-path`
+  argument to the Java compiler. This allows building JAR files that use JPMS
+  modules in their build.
diff --git a/Help/release/dev/build-dir-override-presets.rst b/Help/release/dev/build-dir-override-presets.rst
new file mode 100644
index 0000000..60ae9b9
--- /dev/null
+++ b/Help/release/dev/build-dir-override-presets.rst
@@ -0,0 +1,6 @@
+build-dir-override-presets
+--------------------------
+
+* :option:`cmake --build` now supports specifying a build directory and
+  preset together.  The build preset will be used with the explicit
+  build directory substituted.
diff --git a/Help/release/dev/ci-macos-qt.rst b/Help/release/dev/ci-macos-qt.rst
new file mode 100644
index 0000000..fde0b30
--- /dev/null
+++ b/Help/release/dev/ci-macos-qt.rst
@@ -0,0 +1,6 @@
+ci-macos-qt
+-----------
+
+* The precompiled macOS binary provided on ``cmake.org`` for macOS 10.13+
+  now requires macOS 12 or newer for the :manual:`cmake-gui(1)` application.
+  The command-line tools still run on macOS 10.13.
diff --git a/Help/release/dev/cpack-archive-ownership.rst b/Help/release/dev/cpack-archive-ownership.rst
new file mode 100644
index 0000000..2b057fc
--- /dev/null
+++ b/Help/release/dev/cpack-archive-ownership.rst
@@ -0,0 +1,7 @@
+cpack-archive-ownership
+-----------------------
+
+* The :cpack_gen:`CPack Archive Generator` generator gained new
+  :variable:`CPACK_ARCHIVE_UID` and :variable:`CPACK_ARCHIVE_GID`
+  options to specify the UID and GID of archive entries.
+  The default now UID 0 and GID 0.  See policy :policy:`CMP0206`.
diff --git a/Help/release/dev/file-CREATE_LINK-COPY_ON_ERROR-dir.rst b/Help/release/dev/file-CREATE_LINK-COPY_ON_ERROR-dir.rst
new file mode 100644
index 0000000..ac1dca9
--- /dev/null
+++ b/Help/release/dev/file-CREATE_LINK-COPY_ON_ERROR-dir.rst
@@ -0,0 +1,6 @@
+file-CREATE_LINK-COPY_ON_ERROR-dir
+----------------------------------
+
+* The :command:`file(CREATE_LINK)` command's ``COPY_ON_ERROR`` option,
+  when used with a directory, now copies directory content.
+  See policy :policy:`CMP0205`.
diff --git a/Help/release/dev/file-GET_RUNTIME_DEPENDENCIES-matching.rst b/Help/release/dev/file-GET_RUNTIME_DEPENDENCIES-matching.rst
new file mode 100644
index 0000000..9d89558
--- /dev/null
+++ b/Help/release/dev/file-GET_RUNTIME_DEPENDENCIES-matching.rst
@@ -0,0 +1,6 @@
+file-GET_RUNTIME_DEPENDENCIES-matching
+--------------------------------------
+
+* The :command:`file(GET_RUNTIME_DEPENDENCIES)`
+  and :command:`install(RUNTIME_DEPENDENCY_SET)` commands now normalize
+  paths before matching filters.  See policy :policy:`CMP0207`.
diff --git a/Help/release/index.rst b/Help/release/index.rst
index 54190ee..edeab50 100644
--- a/Help/release/index.rst
+++ b/Help/release/index.rst
@@ -7,6 +7,8 @@
   This file should include the adjacent "dev.txt" file
   in development versions but not in release versions.
 
+.. include:: dev.txt
+
 Releases
 ========
 
diff --git a/Help/variable/CMAKE_ENABLE_EXPORTS.rst b/Help/variable/CMAKE_ENABLE_EXPORTS.rst
index da23342..efde96d 100644
--- a/Help/variable/CMAKE_ENABLE_EXPORTS.rst
+++ b/Help/variable/CMAKE_ENABLE_EXPORTS.rst
@@ -3,13 +3,16 @@
 
 .. versionadded:: 3.4
 
+.. deprecated:: 4.3
+  This variable has been deprecated in favor of the
+  :variable:`CMAKE_EXECUTABLE_ENABLE_EXPORTS` and
+  :variable:`CMAKE_SHARED_LIBRARY_ENABLE_EXPORTS` variables,
+  which have been available since CMake 3.27.
+  It is provided for backward compatibility with older CMake code,
+  but should not be used in new projects.
+
 Specify whether executables export symbols for loadable modules.
 
 This variable is used to initialize the :prop_tgt:`ENABLE_EXPORTS` target
 property for executable targets when they are created by calls to the
 :command:`add_executable` command.  See the property documentation for details.
-
-This variable has been superseded by the
-:variable:`CMAKE_EXECUTABLE_ENABLE_EXPORTS` variable.  It is provided for
-backward compatibility with older CMake code, but should not be used in new
-projects.
diff --git a/Help/variable/CMAKE_EXECUTABLE_ENABLE_EXPORTS.rst b/Help/variable/CMAKE_EXECUTABLE_ENABLE_EXPORTS.rst
index aa6dda2..5168555 100644
--- a/Help/variable/CMAKE_EXECUTABLE_ENABLE_EXPORTS.rst
+++ b/Help/variable/CMAKE_EXECUTABLE_ENABLE_EXPORTS.rst
@@ -9,4 +9,9 @@
 property for executable targets when they are created by calls to the
 :command:`add_executable` command.  See the property documentation for details.
 
-This variable supersede the :variable:`CMAKE_ENABLE_EXPORTS` variable.
+This variable supersedes the :variable:`CMAKE_ENABLE_EXPORTS` variable.
+
+See Also
+^^^^^^^^
+
+* The :variable:`CMAKE_SHARED_LIBRARY_ENABLE_EXPORTS` variable.
diff --git a/Help/variable/CMAKE_INSTALL_EXPORTS_AS_PACKAGE_INFO.rst b/Help/variable/CMAKE_INSTALL_EXPORTS_AS_PACKAGE_INFO.rst
new file mode 100644
index 0000000..f5b7b27
--- /dev/null
+++ b/Help/variable/CMAKE_INSTALL_EXPORTS_AS_PACKAGE_INFO.rst
@@ -0,0 +1,122 @@
+CMAKE_INSTALL_EXPORTS_AS_PACKAGE_INFO
+-------------------------------------
+
+.. versionadded:: 4.3
+
+.. note::
+
+   This variable is meaningful only when experimental support has been enabled
+   by the ``CMAKE_EXPERIMENTAL_FIXME`` gate.
+
+A list of directives instructing CMake to install |CPS| package information
+when exported target information is installed via :command:`install(EXPORT)`.
+The value is treated as a list, with each directive having the form
+``<export-name>:<package-name>[/[l][a<appendix-name>][/<destination>]]``.
+Slashes are used to separate different components of the directive.
+
+Note that this feature is intended for package distributors, and should
+**only** be used when editing a project's CMake script is not feasible.
+Developers should use :command:`install(PACKAGE_INFO)` directly.
+
+Additionally, because ``CMAKE_INSTALL_EXPORTS_AS_PACKAGE_INFO`` functions by
+emulating a call to :command:`install(PACKAGE_INFO)`, using it with a project
+that is already calling :command:`install(PACKAGE_INFO)` directly may result
+in conflicting installation directives, which will usually cause the project's
+configure step to fail.
+
+The meaning of the values is as follows:
+
+``<export-name>``
+  Name of the export for which package information should be installed.
+
+``<package-name>``
+  Name of the package for which to generate package information.  This is also
+  the name that users would use in a :command:`find_package` call.
+
+``l``
+  Optional.  Specifies that the name of the package information file on disk
+  should be lower case.  See the ``LOWER_CASE_FILE`` option of
+  :command:`install(PACKAGE_INFO)`.
+
+``a<appendix-name>``
+  Optional.  Specifies that an appendix ``<appendix-name>`` should be created
+  rather than a root package description.  See the ``APPENDIX`` option of
+  :command:`install(PACKAGE_INFO)`.  Note that additional information
+  (see below) cannot be added to appendices.
+
+``<destination>``
+  Optional.  Specifies the destination to which the package information file
+  should be installed.  See the ``DESTINATION`` option of
+  :command:`install(PACKAGE_INFO)`.  Note that the default is a
+  platform-specific location that is appropriate for |CPS| files in most
+  instances, *not* the ``DESTINATION`` of the :command:`install(EXPORT)`
+  which the directive matched.
+
+For non-appendices, CMake will also infer additional information from several
+CMake variables of the form ``<export-name>_EXPORT_PACKAGE_INFO_<var>``.  The
+values of these are first processed as if by :command:`string(CONFIGURE)` with
+the ``@ONLY`` option.  These are optional, and their effect is equivalent to
+passing their value to the ``<var>`` option of the
+:command:`install(PACKAGE_INFO)` command.
+
+The additional variables are:
+
+  * ``<export-name>_EXPORT_PACKAGE_INFO_VERSION``
+  * ``<export-name>_EXPORT_PACKAGE_INFO_COMPAT_VERSION``
+  * ``<export-name>_EXPORT_PACKAGE_INFO_VERSION_SCHEMA``
+  * ``<export-name>_EXPORT_PACKAGE_INFO_LICENSE``
+  * ``<export-name>_EXPORT_PACKAGE_INFO_DEFAULT_LICENSE``
+  * ``<export-name>_EXPORT_PACKAGE_INFO_DEFAULT_CONFIGURATIONS``
+
+Ideally, the version should be set to ``@PROJECT_VERSION@``.  However,
+some projects may not use the ``VERSION`` option of the :command:`project`
+command.
+
+Example
+^^^^^^^
+
+Consider the following (simplified) project:
+
+.. code-block:: cmake
+
+  project(Example VERSION 1.2.3 SPDX_LICENSE "BSD-3-Clause")
+
+  add_library(foo ...)
+  add_library(bar ...)
+
+  install(TARGETS foo EXPORT required-targets)
+  install(TARGETS bar EXPORT optional-targets)
+
+  install(EXPORT required-targets FILE example-targets.cmake ...)
+  install(EXPORT optional-targets FILE example-optional-targets.cmake ...)
+
+In this example, let ``example-targets.cmake`` be a file which is always
+installed, and ``example-optional-targets.cmake`` be a file which is
+optionally installed (e.g. is distributed as part of a separate package which
+depends on the 'base' package).
+
+Now, imagine we are a distributor that wants to make |CPS| package information
+files available to our users, but we do not want to modify the project's build
+files.  We can do this by passing the following arguments to CMake:
+
+.. code-block::
+
+  -DCMAKE_EXPERIMENTAL_FIXME=<elided>
+  -DCMAKE_INSTALL_EXPORTS_AS_PACKAGE_INFO=\
+    required-targets:Example/l;\
+    optional-targets:Example/laoptional
+  -Drequired-targets_EXPORT_PACKAGE_INFO_VERSION=@Example_VERSION@
+  -Drequired-targets_EXPORT_PACKAGE_INFO_LICENSE=@Example_SPDX_LICENSE@
+
+(Whitespace and line continuation characters, added for readability, should
+be removed in real usage. Arguments may need to be quoted to prevent being
+reinterpreted by the command shell.)
+
+This will cause CMake to also create and install the files ``example.cps`` and
+``example-optional.cps`` which describe the ``Example`` package.  We could
+also specify the version and license information using substitutions provided
+by the package build system (e.g. rpm, dpkg) if the project does not provide
+this information via the :command:`project` command.
+
+.. _CPS: https://cps-org.github.io/cps/
+.. |CPS| replace:: Common Package Specification
diff --git a/Help/variable/CMAKE_INSTALL_PREFIX.rst b/Help/variable/CMAKE_INSTALL_PREFIX.rst
index ce7cb8b..340bc35 100644
--- a/Help/variable/CMAKE_INSTALL_PREFIX.rst
+++ b/Help/variable/CMAKE_INSTALL_PREFIX.rst
@@ -45,3 +45,21 @@
 .. code-block:: shell
 
   cmake --install . --prefix /my/install/prefix
+
+.. note::
+
+  When the project is using the :module:`GNUInstallDirs` module, there are
+  some :ref:`special cases <GNUInstallDirs special cases>` that are
+  evaluated based on the value of the :variable:`CMAKE_INSTALL_PREFIX`
+  variable during the configuration phase.  The results persist even
+  if an alternative :option:`--prefix <cmake--install --prefix>` option
+  is used during installation.
+
+See Also
+^^^^^^^^
+
+* The :option:`--install-prefix <cmake --install-prefix>` option.
+* The :genex:`$<INSTALL_PREFIX>` generator expression.
+* The :ref:`installDir <CMakePresets installDir>` field in CMake configure
+  presets.
+* The :variable:`CPACK_PACKAGING_INSTALL_PREFIX` variable.
diff --git a/Help/variable/CMAKE_POLICY_WARNING_CMPNNNN.rst b/Help/variable/CMAKE_POLICY_WARNING_CMPNNNN.rst
index 3a9605f..1197560 100644
--- a/Help/variable/CMAKE_POLICY_WARNING_CMPNNNN.rst
+++ b/Help/variable/CMAKE_POLICY_WARNING_CMPNNNN.rst
@@ -40,6 +40,8 @@
   policy :policy:`CMP0133`.
 * ``CMAKE_POLICY_WARNING_CMP0172`` controls the warning for
   policy :policy:`CMP0172`.
+* ``CMAKE_POLICY_WARNING_CMP0206`` controls the warning for
+  policy :policy:`CMP0206`.
 
 This variable should not be set by a project in CMake code.  Project
 developers running CMake may set this variable in their cache to
diff --git a/Help/variable/CMAKE_SHARED_LIBRARY_ENABLE_EXPORTS.rst b/Help/variable/CMAKE_SHARED_LIBRARY_ENABLE_EXPORTS.rst
index 3e2c6df..07c99e2 100644
--- a/Help/variable/CMAKE_SHARED_LIBRARY_ENABLE_EXPORTS.rst
+++ b/Help/variable/CMAKE_SHARED_LIBRARY_ENABLE_EXPORTS.rst
@@ -8,3 +8,8 @@
 This variable is used to initialize the :prop_tgt:`ENABLE_EXPORTS` target
 property for shared library targets when they are created by calls to the
 :command:`add_library` command.  See the property documentation for details.
+
+See Also
+^^^^^^^^
+
+* The :variable:`CMAKE_EXECUTABLE_ENABLE_EXPORTS` variable.
diff --git a/Modules/CMakeCXXCompiler.cmake.in b/Modules/CMakeCXXCompiler.cmake.in
index 8e2e3d6..677402b 100644
--- a/Modules/CMakeCXXCompiler.cmake.in
+++ b/Modules/CMakeCXXCompiler.cmake.in
@@ -96,5 +96,8 @@
 set(CMAKE_CXX_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "@CMAKE_CXX_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES@")
 set(CMAKE_CXX_COMPILER_CLANG_RESOURCE_DIR "@CMAKE_CXX_COMPILER_CLANG_RESOURCE_DIR@")
 
-set(CMAKE_CXX_COMPILER_IMPORT_STD "")
-@CMAKE_CXX_IMPORT_STD@
+set(CMAKE_CXX_COMPILER_IMPORT_STD "@CMAKE_CXX_COMPILER_IMPORT_STD@")
+set(CMAKE_CXX_COMPILER_IMPORT_STD_ERROR_MESSAGE  "@CMAKE_CXX_COMPILER_IMPORT_STD_ERROR_MESSAGE@")
+if(CMAKE_CXX_STDLIB_MODULES_JSON)
+  set(CMAKE_CXX_STDLIB_MODULES_JSON "@CMAKE_CXX_STDLIB_MODULES_JSON@")
+endif()
diff --git a/Modules/CMakeDetermineCompilerSupport.cmake b/Modules/CMakeDetermineCompilerSupport.cmake
index c22bf07..512a1c4 100644
--- a/Modules/CMakeDetermineCompilerSupport.cmake
+++ b/Modules/CMakeDetermineCompilerSupport.cmake
@@ -105,18 +105,21 @@
       )
     endif()
 
-    # Create targets for use with `import std;` here.
-    set(CMAKE_CXX_IMPORT_STD "")
-    foreach (_cmake_import_std_version IN ITEMS 23 26)
-      if (CMAKE_CXX${_cmake_import_std_version}_COMPILE_FEATURES)
-        set(_cmake_cxx_import_std "")
-        cmake_create_cxx_import_std("${_cmake_import_std_version}" _cmake_cxx_import_std)
-        if (_cmake_cxx_import_std)
-          string(APPEND CMAKE_CXX_IMPORT_STD "### Imported target for C++${_cmake_import_std_version} standard library\n")
-          string(APPEND CMAKE_CXX_IMPORT_STD "${_cmake_cxx_import_std}\n\n")
-        endif ()
-      endif ()
-    endforeach ()
+    # Find the module metadata for import std
+    set(CMAKE_CXX_COMPILER_IMPORT_STD "")
+    cmake_cxx_find_modules_json()
+    foreach(_cmake_import_std_version IN ITEMS 23 26)
+      if(CMAKE_CXX${_cmake_import_std_version}_COMPILE_FEATURES)
+        # Modules JSON covers all versions, otherwise rely on toolchain targets
+        if(CMAKE_CXX_STDLIB_MODULES_JSON OR (TARGET "__CMAKE:CXX${_cmake_import_std_version}"))
+          list(APPEND CMAKE_CXX_COMPILER_IMPORT_STD ${_cmake_import_std_version})
+        endif()
+      endif()
+    endforeach()
+
+    set(CMAKE_CXX_COMPILER_IMPORT_STD ${CMAKE_CXX_COMPILER_IMPORT_STD} PARENT_SCOPE)
+    set(CMAKE_CXX_STDLIB_MODULES_JSON ${CMAKE_CXX_STDLIB_MODULES_JSON} PARENT_SCOPE)
+    set(CMAKE_CXX_COMPILER_IMPORT_STD_ERROR_MESSAGE "${CMAKE_CXX_COMPILER_IMPORT_STD_ERROR_MESSAGE}" PARENT_SCOPE)
 
     set(CMAKE_CXX_COMPILE_FEATURES ${CMAKE_CXX_COMPILE_FEATURES} PARENT_SCOPE)
     set(CMAKE_CXX98_COMPILE_FEATURES ${CMAKE_CXX98_COMPILE_FEATURES} PARENT_SCOPE)
@@ -126,7 +129,6 @@
     set(CMAKE_CXX20_COMPILE_FEATURES ${CMAKE_CXX20_COMPILE_FEATURES} PARENT_SCOPE)
     set(CMAKE_CXX23_COMPILE_FEATURES ${CMAKE_CXX23_COMPILE_FEATURES} PARENT_SCOPE)
     set(CMAKE_CXX26_COMPILE_FEATURES ${CMAKE_CXX26_COMPILE_FEATURES} PARENT_SCOPE)
-    set(CMAKE_CXX_IMPORT_STD ${CMAKE_CXX_IMPORT_STD} PARENT_SCOPE)
 
     message(CHECK_PASS "done")
 
diff --git a/Modules/CPack.cmake b/Modules/CPack.cmake
index 0be4846..9d03959 100644
--- a/Modules/CPack.cmake
+++ b/Modules/CPack.cmake
@@ -936,6 +936,24 @@
 endif()
 unset(_CPack_CMP0161)
 
+# Archive specific variables
+if(NOT DEFINED CPACK_ARCHIVE_UID AND NOT DEFINED CPACK_ARCHIVE_GID)
+  cmake_policy(GET CMP0206 _CPack_CMP0206)
+  if(NOT "x${_CPack_CMP0206}x" STREQUAL "xNEWx")
+    if(NOT "x${_CPack_CMP0206}x" STREQUAL "xOLDx" AND CMAKE_POLICY_WARNING_CMP0206)
+      cmake_policy(GET_WARNING CMP0206 _CMP0206_warning)
+      message(AUTHOR_WARNING
+        "${_CMP0206_warning}\n"
+        "For compatibility, CMake will set archive UID/GID to -1/-1."
+        )
+      unset(_CMP0206_warning)
+    endif()
+    _cpack_set_default(CPACK_ARCHIVE_UID "-1")
+    _cpack_set_default(CPACK_ARCHIVE_GID "-1")
+  endif()
+  unset(_CPack_CMP0206)
+endif()
+
 # set sysroot so SDK tools can be used
 if(CMAKE_OSX_SYSROOT)
   _cpack_set_default(CPACK_OSX_SYSROOT "${_CMAKE_OSX_SYSROOT_PATH}")
diff --git a/Modules/CPackIFWConfigureFile.cmake b/Modules/CPackIFWConfigureFile.cmake
index f92fc10..bed78f9 100644
--- a/Modules/CPackIFWConfigureFile.cmake
+++ b/Modules/CPackIFWConfigureFile.cmake
@@ -7,8 +7,8 @@
 
 .. versionadded:: 3.8
 
-This module defines :command:`configure_file` similar command to
-configure file templates prepared in QtIFW/SDK/Creator style.
+This module provides a command similar to :command:`configure_file` for
+configuring file templates prepared in QtIFW/SDK/Creator style.
 
 Load this module in a CMake project with:
 
@@ -19,21 +19,100 @@
 Commands
 ^^^^^^^^
 
-The module defines the following commands:
+This module provides the following command:
 
 .. command:: cpack_ifw_configure_file
 
-  Copy a file to another location and modify its contents.
+  Copies a file template to output file and substitutes variable values
+  referenced as ``%{VAR}`` or ``%VAR%`` from the input file template
+  content:
 
   .. code-block:: cmake
 
     cpack_ifw_configure_file(<input> <output>)
 
-  Copies an ``<input>`` file to an ``<output>`` file and substitutes variable
-  values referenced as ``%{VAR}`` or ``%VAR%`` in the input file content.
+  ``<input>``
+    Input file template.  If given as a relative path, it is interpreted as
+    relative to the current source directory
+    (:variable:`CMAKE_CURRENT_SOURCE_DIR`).
+
+  ``<output>``
+    Output file.  If given as a relative path, it is interpreted as relative
+    to the current binary directory (:variable:`CMAKE_CURRENT_BINARY_DIR`).
+
+  Qt Installer Framework (QtIFW) uses ``@`` characters for embedding
+  predefined variables (``TargetDir``, ``StartMenuDir``, etc.) in Qt
+  installer scripts:
+
+  .. code-block:: javascript
+    :caption: ``example.qs``
+
+    component.addOperation(
+      "CreateShortcut",
+      "@TargetDir@/example.com.html",
+      "@StartMenuDir@/Example Web Site.lnk"
+    );
+
+  The purpose of this command is to preserve the QtIFW predefined variables
+  containing the ``@`` characters (``@VAR@``), and instead use the ``%``
+  characters for template placeholders (``%VAR%``, ``%{VAR}``) in
+  Qt/IFW/SDK/Creator templates.  The :command:`configure_file` command
+  would otherwise replace all variable references containing the ``@``
+  characters.
+
   Each variable reference will be replaced with the current value of the
   variable, or the empty string if the variable is not defined.
 
+Examples
+^^^^^^^^
+
+In the following example this module is used to create an IFW component
+script from a given template file ``qt.tools.foo.qs.in``, where
+``%FOO_DOC_DIR%`` variable reference will be replaced by the values of
+the ``FOO_DOC_DIR`` CMake variable.
+
+.. code-block:: cmake
+  :caption: ``CMakeLists.txt``
+
+  cmake_minimum_required(VERSION 3.8)
+
+  project(Foo)
+
+  # ...
+
+  include(CPackIFWConfigureFile)
+
+  set(FOO_DOC_DIR "doc/foo")
+
+  cpack_ifw_configure_file(qt.tools.foo.qs.in qt.tools.foo.qs)
+
+.. code-block:: javascript
+  :caption: ``qt.tools.foo.qs.in``
+
+  function Component()
+  {
+  }
+
+  Component.prototype.createOperations = function()
+  {
+    if (installer.value("os") === "win") {
+      component.addOperation(
+        "CreateShortcut",
+        "@TargetDir@/%FOO_DOC_DIR%/example.com.html",
+        "@StartMenuDir@/Example Web Site.lnk"
+      );
+    }
+
+    component.createOperations();
+  }
+
+  // ...
+
+See Also
+^^^^^^^^
+
+* The :cpack_gen:`CPack IFW Generator`.
+* The :module:`CPackIFW` module.
 #]=======================================================================]
 
 if(NOT DEFINED CPackIFWConfigureFile_CMake_INCLUDED)
diff --git a/Modules/Compiler/CMakeCommonCompilerMacros.cmake b/Modules/Compiler/CMakeCommonCompilerMacros.cmake
index 067aa6f..a97fe0f 100644
--- a/Modules/Compiler/CMakeCommonCompilerMacros.cmake
+++ b/Modules/Compiler/CMakeCommonCompilerMacros.cmake
@@ -202,43 +202,21 @@
   _has_compiler_features_hip(98)
 endmacro()
 
-function(cmake_create_cxx_import_std std variable)
-  set(_cmake_supported_import_std_features
-    # Compilers support `import std` in C++20 as an extension. Skip
-    # for now.
-    # 20
-    23
-    26)
-  list(FIND _cmake_supported_import_std_features "${std}" _cmake_supported_import_std_idx)
-  if (_cmake_supported_import_std_idx EQUAL "-1")
-    set("${variable}"
-      "set(CMAKE_CXX${std}_COMPILER_IMPORT_STD_NOT_FOUND_MESSAGE \"Unsupported C++ standard: C++${std}\")\n"
-      PARENT_SCOPE)
-    return ()
-  endif ()
-  # If the target exists, skip. A toolchain file may have provided it.
-  if (TARGET "__CMAKE::CXX${std}")
-    return ()
-  endif ()
+function(cmake_cxx_find_modules_json)
   # The generator must support imported C++ modules.
   if (NOT CMAKE_GENERATOR MATCHES "Ninja")
-    set("${variable}"
-      "set(CMAKE_CXX${std}_COMPILER_IMPORT_STD_NOT_FOUND_MESSAGE \"Unsupported generator: ${CMAKE_GENERATOR}\")\n"
-      PARENT_SCOPE)
+    set(CMAKE_CXX_COMPILER_IMPORT_STD_ERROR_MESSAGE "Unsupported generator: ${CMAKE_GENERATOR}" PARENT_SCOPE)
     return ()
   endif ()
+
   # Check if the compiler understands how to `import std;`.
   include("${CMAKE_ROOT}/Modules/Compiler/${CMAKE_CXX_COMPILER_ID}-CXX-CXXImportStd.cmake" OPTIONAL RESULT_VARIABLE _cmake_import_std_res)
   if (NOT _cmake_import_std_res)
-    set("${variable}"
-      "set(CMAKE_CXX${std}_COMPILER_IMPORT_STD_NOT_FOUND_MESSAGE \"Toolchain does not support discovering `import std` support\")\n"
-      PARENT_SCOPE)
+    set(CMAKE_CXX_COMPILER_IMPORT_STD_ERROR_MESSAGE "Toolchain does not support discovering module metadata" PARENT_SCOPE)
     return ()
   endif ()
-  if (NOT COMMAND _cmake_cxx_import_std)
-    set("${variable}"
-      "set(CMAKE_CXX${std}_COMPILER_IMPORT_STD_NOT_FOUND_MESSAGE \"Toolchain does not provide `import std` discovery command\")\n"
-      PARENT_SCOPE)
+  if (NOT COMMAND _cmake_cxx_find_modules_json)
+    set(CMAKE_CXX_COMPILER_IMPORT_STD_ERROR_MESSAGE "Toolchain does not provide module metadata discovery command" PARENT_SCOPE)
     return ()
   endif ()
 
@@ -249,19 +227,11 @@
     "CxxImportStd"
     _cmake_supported_import_std_experimental)
   if (NOT _cmake_supported_import_std_experimental)
-    set("${variable}"
-      "set(CMAKE_CXX${std}_COMPILER_IMPORT_STD_NOT_FOUND_MESSAGE \"Experimental `import std` support not enabled when detecting toolchain; it must be set before `CXX` is enabled (usually a `project()` call)\")\n"
-      PARENT_SCOPE)
+    set(CMAKE_CXX_COMPILER_IMPORT_STD_ERROR_MESSAGE "Experimental `import std` support not enabled when detecting toolchain; it must be set before `CXX` is enabled (usually a `project()` call)" PARENT_SCOPE)
     return ()
   endif ()
 
-  _cmake_cxx_import_std("${std}" target_definition)
-  string(CONCAT guarded_target_definition
-    "if (NOT TARGET \"__CMAKE::CXX${std}\")\n"
-    "${target_definition}"
-    "endif ()\n"
-    "if (TARGET \"__CMAKE::CXX${std}\")\n"
-    "  list(APPEND CMAKE_CXX_COMPILER_IMPORT_STD \"${std}\")\n"
-    "endif ()\n")
-  set("${variable}" "${guarded_target_definition}" PARENT_SCOPE)
+  _cmake_cxx_find_modules_json()
+  set(CMAKE_CXX_COMPILER_IMPORT_STD_ERROR_MESSAGE "${CMAKE_CXX_COMPILER_IMPORT_STD_ERROR_MESSAGE}" PARENT_SCOPE)
+  set(CMAKE_CXX_STDLIB_MODULES_JSON "${CMAKE_CXX_STDLIB_MODULES_JSON}" PARENT_SCOPE)
 endfunction()
diff --git a/Modules/Compiler/Clang-CXX-CXXImportStd.cmake b/Modules/Compiler/Clang-CXX-CXXImportStd.cmake
index 9061e00..4099a35 100644
--- a/Modules/Compiler/Clang-CXX-CXXImportStd.cmake
+++ b/Modules/Compiler/Clang-CXX-CXXImportStd.cmake
@@ -1,18 +1,14 @@
-function (_cmake_cxx_import_std std variable)
+function (_cmake_cxx_find_modules_json)
   if (CMAKE_CXX_STANDARD_LIBRARY STREQUAL "libc++")
     set(_clang_modules_json_impl "libc++")
   elseif (CMAKE_CXX_STANDARD_LIBRARY STREQUAL "libstdc++")
     set(_clang_modules_json_impl "libstdc++")
   else ()
-    set("${variable}"
-      "set(CMAKE_CXX${std}_COMPILER_IMPORT_STD_NOT_FOUND_MESSAGE \"Only `libc++` and `libstdc++` are supported\")\n"
-      PARENT_SCOPE)
+    set(CMAKE_CXX_COMPILER_IMPORT_STD_ERROR_MESSAGE "Only `libc++` and `libstdc++` are supported" PARENT_SCOPE)
     return ()
   endif ()
 
-  if (CMAKE_CXX_STDLIB_MODULES_JSON)
-    set(_clang_libcxx_modules_json_file "${CMAKE_CXX_STDLIB_MODULES_JSON}")
-  else ()
+  if (NOT DEFINED CMAKE_CXX_STDLIB_MODULES_JSON)
     execute_process(
       COMMAND
         "${CMAKE_CXX_COMPILER}"
@@ -24,19 +20,10 @@
       OUTPUT_STRIP_TRAILING_WHITESPACE
       ERROR_STRIP_TRAILING_WHITESPACE)
     if (_clang_libcxx_modules_json_file_res)
-      set("${variable}"
-        "set(CMAKE_CXX${std}_COMPILER_IMPORT_STD_NOT_FOUND_MESSAGE \"Could not find `${_clang_modules_json_impl}.modules.json` resource\")\n"
-        PARENT_SCOPE)
+      set(CMAKE_CXX_COMPILER_IMPORT_STD_ERROR_MESSAGE "Could not find `${_clang_modules_json_impl}.modules.json` resource" PARENT_SCOPE)
       return ()
     endif ()
-  endif ()
-
-  # Without this file, we do not have modules installed.
-  if (NOT EXISTS "${_clang_libcxx_modules_json_file}")
-    set("${variable}"
-      "set(CMAKE_CXX${std}_COMPILER_IMPORT_STD_NOT_FOUND_MESSAGE \"`${_clang_modules_json_impl}.modules.json` resource does not exist\")\n"
-      PARENT_SCOPE)
-    return ()
+    set(CMAKE_CXX_STDLIB_MODULES_JSON "${_clang_libcxx_modules_json_file}" PARENT_SCOPE)
   endif ()
 
   if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "18.1.2" AND
@@ -44,145 +31,7 @@
     # The original PR had a key spelling mismatch internally. Do not support it
     # and instead require a release known to have the fix.
     # https://github.com/llvm/llvm-project/pull/83036
-    set("${variable}"
-      "set(CMAKE_CXX${std}_COMPILER_IMPORT_STD_NOT_FOUND_MESSAGE \"LLVM 18.1.2 is required for `${_clang_modules_json_impl}.modules.json` format fix\")\n"
-      PARENT_SCOPE)
+    set(CMAKE_CXX_COMPILER_IMPORT_STD_ERROR_MESSAGE "LLVM 18.1.2 is required for `${_clang_modules_json_impl}.modules.json` format fix" PARENT_SCOPE)
     return ()
   endif ()
-
-  file(READ "${_clang_libcxx_modules_json_file}" _clang_libcxx_modules_json)
-  string(JSON _clang_modules_json_version GET "${_clang_libcxx_modules_json}" "version")
-  string(JSON _clang_modules_json_revision GET "${_clang_libcxx_modules_json}" "revision")
-  # Require version 1.
-  if (NOT _clang_modules_json_version EQUAL "1")
-    set("${variable}"
-      "set(CMAKE_CXX${std}_COMPILER_IMPORT_STD_NOT_FOUND_MESSAGE \"`libc++.modules.json` version ${_clang_modules_json_version}.${_clang_modules_json_revision} is not recognized\")\n"
-      PARENT_SCOPE)
-    return ()
-  endif ()
-
-  string(JSON _clang_modules_json_nmodules LENGTH "${_clang_libcxx_modules_json}" "modules")
-  # Don't declare the target without any modules.
-  if (NOT _clang_modules_json_nmodules)
-    set("${variable}"
-      "set(CMAKE_CXX${std}_COMPILER_IMPORT_STD_NOT_FOUND_MESSAGE \"`libc++.modules.json` does not list any available modules\")\n"
-      PARENT_SCOPE)
-    return ()
-  endif ()
-
-  # Declare the target.
-  set(_clang_libcxx_target "")
-  # Clang 18 does not provide the module initializer for the `std` modules.
-  # Create a static library to hold these. Hope that Clang 19 can provide this,
-  # but never run the code.
-  string(APPEND _clang_libcxx_target
-    "add_library(__cmake_cxx${std} STATIC)\n")
-  string(APPEND _clang_libcxx_target
-    "target_sources(__cmake_cxx${std} INTERFACE \"$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,STATIC_LIBRARY>:$<TARGET_OBJECTS:__cmake_cxx${std}>>\")\n")
-  string(APPEND _clang_libcxx_target
-    "set_property(TARGET __cmake_cxx${std} PROPERTY EXCLUDE_FROM_ALL 1)\n")
-  string(APPEND _clang_libcxx_target
-    "set_property(TARGET __cmake_cxx${std} PROPERTY CXX_SCAN_FOR_MODULES 1)\n")
-  string(APPEND _clang_libcxx_target
-    "set_property(TARGET __cmake_cxx${std} PROPERTY CXX_MODULE_STD 0)\n")
-  string(APPEND _clang_libcxx_target
-    "target_compile_features(__cmake_cxx${std} PUBLIC cxx_std_${std})\n")
-
-  set(_clang_modules_is_stdlib 0)
-  set(_clang_modules_include_dirs_list "")
-  set(_clang_modules_module_paths "")
-  get_filename_component(_clang_modules_dir "${_clang_libcxx_modules_json_file}" DIRECTORY)
-
-  # Add module sources.
-  math(EXPR _clang_modules_json_nmodules_range "${_clang_modules_json_nmodules} - 1")
-  foreach (_clang_modules_json_modules_idx RANGE 0 "${_clang_modules_json_nmodules_range}")
-    string(JSON _clang_modules_json_module GET "${_clang_libcxx_modules_json}" "modules" "${_clang_modules_json_modules_idx}")
-
-    string(JSON _clang_modules_json_module_source GET "${_clang_modules_json_module}" "source-path")
-    string(JSON _clang_modules_json_module_is_stdlib GET "${_clang_modules_json_module}" "is-std-library")
-    string(JSON _clang_modules_json_module_local_arguments ERROR_VARIABLE _clang_modules_json_module_local_arguments_error GET "${_clang_modules_json_module}" "local-arguments")
-    string(JSON _clang_modules_json_module_nsystem_include_directories ERROR_VARIABLE _clang_modules_json_module_nsystem_include_directories_error LENGTH "${_clang_modules_json_module_local_arguments}" "system-include-directories")
-
-    if (_clang_modules_json_module_local_arguments_error)
-      set(_clang_modules_json_module_local_arguments "")
-    endif ()
-    if (_clang_modules_json_module_nsystem_include_directories_error)
-      set(_clang_modules_json_module_nsystem_include_directories 0)
-    endif ()
-    if (NOT IS_ABSOLUTE "${_clang_modules_json_module_source}")
-      string(PREPEND _clang_modules_json_module_source "${_clang_modules_dir}/")
-    endif ()
-    list(APPEND _clang_modules_module_paths
-      "${_clang_modules_json_module_source}")
-
-    if (_clang_modules_json_module_is_stdlib)
-      set(_clang_modules_is_stdlib 1)
-    endif ()
-
-    if (_clang_modules_json_module_nsystem_include_directories)
-      math(EXPR _clang_modules_json_module_nsystem_include_directories_range "${_clang_modules_json_module_nsystem_include_directories} - 1")
-      foreach (_clang_modules_json_modules_system_include_directories_idx RANGE 0 "${_clang_modules_json_module_nsystem_include_directories_range}")
-        string(JSON _clang_modules_json_module_system_include_directory GET "${_clang_modules_json_module_local_arguments}" "system-include-directories" "${_clang_modules_json_modules_system_include_directories_idx}")
-
-        if (NOT IS_ABSOLUTE "${_clang_modules_json_module_system_include_directory}")
-          string(PREPEND _clang_modules_json_module_system_include_directory "${_clang_modules_dir}/")
-        endif ()
-        list(APPEND _clang_modules_include_dirs_list
-          "${_clang_modules_json_module_system_include_directory}")
-      endforeach ()
-    endif ()
-  endforeach ()
-
-  # Split the paths into basedirs and module paths.
-  set(_clang_modules_base_dirs_list "")
-  set(_clang_modules_files "")
-  foreach (_clang_modules_module_path IN LISTS _clang_modules_module_paths)
-    get_filename_component(_clang_module_dir "${_clang_modules_module_path}" DIRECTORY)
-
-    list(APPEND _clang_modules_base_dirs_list
-      "${_clang_module_dir}")
-    string(APPEND _clang_modules_files
-      " \"${_clang_modules_module_path}\"")
-  endforeach ()
-  list(REMOVE_DUPLICATES _clang_modules_base_dirs_list)
-  set(_clang_modules_base_dirs "")
-  foreach (_clang_modules_base_dir IN LISTS _clang_modules_base_dirs_list)
-    string(APPEND _clang_modules_base_dirs
-      " \"${_clang_modules_base_dir}\"")
-  endforeach ()
-
-  # If we have a standard library module, suppress warnings about reserved
-  # module names.
-  if (_clang_modules_is_stdlib)
-    string(APPEND _clang_libcxx_target
-      "target_compile_options(__cmake_cxx${std} PRIVATE -Wno-reserved-module-identifier)\n")
-  endif ()
-
-  # Set up include directories.
-  list(REMOVE_DUPLICATES _clang_modules_include_dirs_list)
-  set(_clang_modules_include_dirs "")
-  foreach (_clang_modules_include_dir IN LISTS _clang_modules_include_dirs_list)
-    string(APPEND _clang_modules_include_dirs
-      " \"${_clang_modules_include_dir}\"")
-  endforeach ()
-  string(APPEND _clang_libcxx_target
-    "target_include_directories(__cmake_cxx${std} PRIVATE ${_clang_modules_include_dirs})\n")
-
-  # Create the file set for the modules.
-  string(APPEND _clang_libcxx_target
-    "target_sources(__cmake_cxx${std}
-  PUBLIC
-  FILE_SET std TYPE CXX_MODULES
-    BASE_DIRS ${_clang_modules_base_dirs}
-    FILES ${_clang_modules_files})\n")
-
-  # Wrap the `__cmake_cxx${std}` target in a check.
-  string(PREPEND _clang_libcxx_target
-    "if (NOT TARGET \"__cmake_cxx${std}\")\n")
-  string(APPEND _clang_libcxx_target
-    "endif ()\n")
-  string(APPEND _clang_libcxx_target
-    "add_library(__CMAKE::CXX${std} ALIAS __cmake_cxx${std})\n")
-
-  set("${variable}" "${_clang_libcxx_target}" PARENT_SCOPE)
 endfunction ()
diff --git a/Modules/Compiler/GNU-CXX-CXXImportStd.cmake b/Modules/Compiler/GNU-CXX-CXXImportStd.cmake
index 834e999..08d6273 100644
--- a/Modules/Compiler/GNU-CXX-CXXImportStd.cmake
+++ b/Modules/Compiler/GNU-CXX-CXXImportStd.cmake
@@ -1,14 +1,10 @@
-function (_cmake_cxx_import_std std variable)
+function (_cmake_cxx_find_modules_json)
   if (NOT CMAKE_CXX_STANDARD_LIBRARY STREQUAL "libstdc++")
-    set("${variable}"
-      "set(CMAKE_CXX${std}_COMPILER_IMPORT_STD_NOT_FOUND_MESSAGE \"Only `libstdc++` is supported\")\n"
-      PARENT_SCOPE)
+    set(CMAKE_CXX_COMPILER_IMPORT_STD_ERROR_MESSAGE "Only `libstdc++` is supported" PARENT_SCOPE)
     return ()
   endif ()
 
-  if (CMAKE_CXX_STDLIB_MODULES_JSON)
-    set(_gnu_libstdcxx_modules_json_file "${CMAKE_CXX_STDLIB_MODULES_JSON}")
-  else ()
+  if (NOT DEFINED CMAKE_CXX_STDLIB_MODULES_JSON)
     execute_process(
       COMMAND
         "${CMAKE_CXX_COMPILER}"
@@ -20,119 +16,9 @@
       OUTPUT_STRIP_TRAILING_WHITESPACE
       ERROR_STRIP_TRAILING_WHITESPACE)
     if (_gnu_libstdcxx_modules_json_file_res)
-      set("${variable}"
-        "set(CMAKE_CXX${std}_COMPILER_IMPORT_STD_NOT_FOUND_MESSAGE \"Could not find `libstdc++.modules.json` resource\")\n"
-        PARENT_SCOPE)
+      set(CMAKE_CXX_COMPILER_IMPORT_STD_ERROR_MESSAGE "Could not find `libstdc++.modules.json` resource" PARENT_SCOPE)
       return ()
     endif ()
+    set(CMAKE_CXX_STDLIB_MODULES_JSON "${_gnu_libstdcxx_modules_json_file}" PARENT_SCOPE)
   endif ()
-
-  # Without this file, we do not have modules installed.
-  if (NOT EXISTS "${_gnu_libstdcxx_modules_json_file}")
-    set("${variable}"
-      "set(CMAKE_CXX${std}_COMPILER_IMPORT_STD_NOT_FOUND_MESSAGE \"`libstdc++.modules.json` resource does not exist\")\n"
-      PARENT_SCOPE)
-    return ()
-  endif ()
-
-  file(READ "${_gnu_libstdcxx_modules_json_file}" _gnu_libstdcxx_modules_json)
-  string(JSON _gnu_modules_json_version GET "${_gnu_libstdcxx_modules_json}" "version")
-  string(JSON _gnu_modules_json_revision GET "${_gnu_libstdcxx_modules_json}" "revision")
-  # Require version 1.
-  if (NOT _gnu_modules_json_version EQUAL "1")
-    set("${variable}"
-      "set(CMAKE_CXX${std}_COMPILER_IMPORT_STD_NOT_FOUND_MESSAGE \"`libstdc++.modules.json` version ${_gnu_modules_json_version}.${_gnu_modules_json_revision} is not recognized\")\n"
-      PARENT_SCOPE)
-    return ()
-  endif ()
-
-  string(JSON _gnu_modules_json_nmodules LENGTH "${_gnu_libstdcxx_modules_json}" "modules")
-  # Don't declare the target without any modules.
-  if (NOT _gnu_modules_json_nmodules)
-    set("${variable}"
-      "set(CMAKE_CXX${std}_COMPILER_IMPORT_STD_NOT_FOUND_MESSAGE \"`libstdc++.modules.json` does not list any available modules\")\n"
-      PARENT_SCOPE)
-    return ()
-  endif ()
-
-  # Declare the target.
-  set(_gnu_libstdcxx_target "")
-  string(APPEND _gnu_libstdcxx_target
-    "add_library(__CMAKE::CXX${std} IMPORTED INTERFACE)\n")
-  string(APPEND _gnu_libstdcxx_target
-    "target_compile_features(__CMAKE::CXX${std} INTERFACE cxx_std_${std})\n")
-
-  set(_gnu_modules_is_stdlib 0)
-  set(_gnu_modules_include_dirs_list "")
-  set(_gnu_modules_module_paths "")
-  get_filename_component(_gnu_modules_dir "${_gnu_libstdcxx_modules_json_file}" DIRECTORY)
-
-  # Add module sources.
-  math(EXPR _gnu_modules_json_nmodules_range "${_gnu_modules_json_nmodules} - 1")
-  foreach (_gnu_modules_json_modules_idx RANGE 0 "${_gnu_modules_json_nmodules_range}")
-    string(JSON _gnu_modules_json_module GET "${_gnu_libstdcxx_modules_json}" "modules" "${_gnu_modules_json_modules_idx}")
-
-    string(JSON _gnu_modules_json_module_source GET "${_gnu_modules_json_module}" "source-path")
-    string(JSON _gnu_modules_json_module_is_stdlib GET "${_gnu_modules_json_module}" "is-std-library")
-    string(JSON _gnu_modules_json_module_local_arguments ERROR_VARIABLE _gnu_modules_json_module_local_arguments_error GET "${_gnu_modules_json_module}" "local-arguments")
-    string(JSON _gnu_modules_json_module_nsystem_include_directories ERROR_VARIABLE _gnu_modules_json_module_nsystem_include_directories_error LENGTH "${_gnu_modules_json_module_local_arguments}" "system-include-directories")
-
-    if (_gnu_modules_json_module_local_arguments_error STREQUAL "NOTFOUND")
-      set(_gnu_modules_json_module_local_arguments "")
-    endif ()
-    if (_gnu_modules_json_module_nsystem_include_directories_error STREQUAL "NOTFOUND")
-      set(_gnu_modules_json_module_nsystem_include_directories 0)
-    endif ()
-
-    if (NOT IS_ABSOLUTE "${_gnu_modules_json_module_source}")
-      string(PREPEND _gnu_modules_json_module_source "${_gnu_modules_dir}/")
-    endif ()
-    list(APPEND _gnu_modules_module_paths
-      "${_gnu_modules_json_module_source}")
-
-    if (_gnu_modules_json_module_is_stdlib)
-      set(_gnu_modules_is_stdlib 1)
-    endif ()
-
-    if (_gnu_modules_json_module_nsystem_include_directories)
-      math(EXPR _gnu_modules_json_module_nsystem_include_directories_range "${_gnu_modules_json_module_nsystem_include_directories} - 1")
-      foreach (_gnu_modules_json_modules_system_include_directories_idx RANGE 0 "${_gnu_modules_json_module_nsystem_include_directories_range}")
-        string(JSON _gnu_modules_json_module_system_include_directory GET "${_gnu_modules_json_module_local_arguments}" "system-include-directories" "${_gnu_modules_json_modules_system_include_directories_idx}")
-
-        if (NOT IS_ABSOLUTE "${_gnu_modules_json_module_system_include_directory}")
-          string(PREPEND _gnu_modules_json_module_system_include_directory "${_gnu_modules_dir}/")
-        endif ()
-        list(APPEND _gnu_modules_include_dirs_list
-          "${_gnu_modules_json_module_system_include_directory}")
-      endforeach ()
-    endif ()
-  endforeach ()
-
-  # Split the paths into basedirs and module paths.
-  set(_gnu_modules_base_dirs_list "")
-  set(_gnu_modules_files "")
-  foreach (_gnu_modules_module_path IN LISTS _gnu_modules_module_paths)
-    get_filename_component(_gnu_module_dir "${_gnu_modules_module_path}" DIRECTORY)
-
-    list(APPEND _gnu_modules_base_dirs_list
-      "${_gnu_module_dir}")
-    string(APPEND _gnu_modules_files
-      " \"${_gnu_modules_module_path}\"")
-  endforeach ()
-  list(REMOVE_DUPLICATES _gnu_modules_base_dirs_list)
-  set(_gnu_modules_base_dirs "")
-  foreach (_gnu_modules_base_dir IN LISTS _gnu_modules_base_dirs_list)
-    string(APPEND _gnu_modules_base_dirs
-      " \"${_gnu_modules_base_dir}\"")
-  endforeach ()
-
-  # Create the file set for the modules.
-  string(APPEND _gnu_libstdcxx_target
-    "target_sources(__CMAKE::CXX${std}
-  INTERFACE
-  FILE_SET std TYPE CXX_MODULES
-    BASE_DIRS ${_gnu_modules_base_dirs}
-    FILES ${_gnu_modules_files})\n")
-
-  set("${variable}" "${_gnu_libstdcxx_target}" PARENT_SCOPE)
 endfunction ()
diff --git a/Modules/Compiler/MSVC-CXX-CXXImportStd.cmake b/Modules/Compiler/MSVC-CXX-CXXImportStd.cmake
index ff01263..733b31b 100644
--- a/Modules/Compiler/MSVC-CXX-CXXImportStd.cmake
+++ b/Modules/Compiler/MSVC-CXX-CXXImportStd.cmake
@@ -1,119 +1,104 @@
-function (_cmake_cxx_import_std std variable)
-  if (CMAKE_CXX_STDLIB_MODULES_JSON)
-    set(_msvc_modules_json_file "${CMAKE_CXX_STDLIB_MODULES_JSON}")
-  else ()
-    find_file(_msvc_modules_json_file
-      NAME modules.json
-      HINTS
-        "$ENV{VCToolsInstallDir}/modules"
-      PATHS
-        "$ENV{INCLUDE}"
-        "${CMAKE_CXX_COMPILER}/../../.."
-        "${CMAKE_CXX_COMPILER}/../.."    # msvc-wine layout
-      PATH_SUFFIXES
-        ../modules
-      NO_CACHE)
-    # Without this file, we do not have modules installed.
-    if (NOT EXISTS "${_msvc_modules_json_file}")
-      set("${variable}"
-        "set(CMAKE_CXX${std}_COMPILER_IMPORT_STD_NOT_FOUND_MESSAGE \"Could not find `modules.json` resource\")\n"
-        PARENT_SCOPE)
-      return ()
-    endif ()
+function (_cmake_cxx_find_modules_json)
+  if (DEFINED CMAKE_CXX_STDLIB_MODULES_JSON)
+    return ()
+  endif ()
+
+  find_file(_msvc_modules_json_file
+    NAME modules.json
+    HINTS
+      "$ENV{VCToolsInstallDir}/modules"
+    PATHS
+      "$ENV{INCLUDE}"
+      "${CMAKE_CXX_COMPILER}/../../.."
+      "${CMAKE_CXX_COMPILER}/../.."    # msvc-wine layout
+    PATH_SUFFIXES
+      ../modules
+    NO_CACHE)
+
+  # Without this file, we do not have modules installed.
+  if (NOT EXISTS "${_msvc_modules_json_file}")
+    set(CMAKE_CXX_COMPILER_IMPORT_STD_ERROR_MESSAGE "Could not find `modules.json` resource" PARENT_SCOPE)
+    return ()
   endif ()
 
   file(READ "${_msvc_modules_json_file}" _msvc_modules_json)
+  string(JSON _msvc_json_modules ERROR_VARIABLE _msvc_json_err GET "${_msvc_modules_json}" "modules")
+
+  # This is probably a conforming module metadata file, use it as is
+  if (_msvc_json_modules)
+    set(CMAKE_CXX_STDLIB_MODULES_JSON "${_msvc_modules_json_file}" PARENT_SCOPE)
+    return ()
+  endif ()
+
+  # Otherwise it's a Microsoft STL-style modules.json, check if we recognize it
   string(JSON _msvc_json_version GET "${_msvc_modules_json}" "version")
   string(JSON _msvc_json_revision GET "${_msvc_modules_json}" "revision")
   # Require version 1.
   if (NOT _msvc_json_version EQUAL "1")
-    set("${variable}"
-      "set(CMAKE_CXX${std}_COMPILER_IMPORT_STD_NOT_FOUND_MESSAGE \"`modules.json` version ${_msvc_json_version}.${_msvc_json_revision} is not recognized\")\n"
-      PARENT_SCOPE)
+    set(CMAKE_CXX_COMPILER_IMPORT_STD_ERROR_MESSAGE "`modules.json` version ${_msvc_json_version}.${_msvc_json_revision} is not recognized" PARENT_SCOPE)
     return ()
   endif ()
 
   string(JSON _msvc_json_library GET "${_msvc_modules_json}" "library")
   # Bail if we don't understand the library.
   if (NOT _msvc_json_library STREQUAL "microsoft/STL")
-    set("${variable}"
-      "set(CMAKE_CXX${std}_COMPILER_IMPORT_STD_NOT_FOUND_MESSAGE \"`modules.json` library `${_msvc_json_library}` is not recognized\")\n"
-      PARENT_SCOPE)
+    set(CMAKE_CXX_COMPILER_IMPORT_STD_ERROR_MESSAGE "`modules.json` library `${_msvc_json_library}` is not recognized" PARENT_SCOPE)
     return ()
   endif ()
 
-  string(JSON _msvc_json_nmodules LENGTH "${_msvc_modules_json}" "module-sources")
-  # Don't declare the target without any modules.
-  if (NOT _msvc_json_nmodules)
-    set("${variable}"
-      "set(CMAKE_CXX${std}_COMPILER_IMPORT_STD_NOT_FOUND_MESSAGE \"`modules.json` does not list any available modules\")\n"
-      PARENT_SCOPE)
+  string(JSON _msvc_json_sources_len LENGTH "${_msvc_modules_json}" "module-sources")
+  # Bail if there aren't any sources
+  if (NOT _msvc_json_sources_len)
+    set(CMAKE_CXX_COMPILER_IMPORT_STD_ERROR_MESSAGE "`modules.json` does not list any available sources" PARENT_SCOPE)
     return ()
   endif ()
 
-  # Declare the target.
-  set(_msvc_std_target "")
-  string(APPEND _msvc_std_target
-    "add_library(__cmake_cxx${std} STATIC)\n")
-  string(APPEND _msvc_std_target
-    "target_sources(__cmake_cxx${std} INTERFACE \"$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,STATIC_LIBRARY>:$<TARGET_OBJECTS:__cmake_cxx${std}>>\")\n")
-  string(APPEND _msvc_std_target
-    "set_property(TARGET __cmake_cxx${std} PROPERTY EXCLUDE_FROM_ALL 1)\n")
-  string(APPEND _msvc_std_target
-    "set_property(TARGET __cmake_cxx${std} PROPERTY CXX_SCAN_FOR_MODULES 1)\n")
-  string(APPEND _msvc_std_target
-    "set_property(TARGET __cmake_cxx${std} PROPERTY CXX_MODULE_STD 0)\n")
-  string(APPEND _msvc_std_target
-    "target_compile_features(__cmake_cxx${std} PUBLIC cxx_std_${std})\n")
+  set(_msvc_module_metadata [=[{
+    "version": 1,
+    "revision": 1,
+    "modules": []
+  }]=])
 
-  set(_msvc_modules_module_paths "")
-  get_filename_component(_msvc_modules_dir "${_msvc_modules_json_file}" DIRECTORY)
+  cmake_path(GET _msvc_modules_json_file PARENT_PATH _msvc_base_dir)
+  math(EXPR _msvc_json_sources_len "${_msvc_json_sources_len}-1")
+  foreach (idx RANGE ${_msvc_json_sources_len})
+    string(JSON _msvc_source GET "${_msvc_modules_json}" "module-sources" ${idx})
 
-  # Add module sources.
-  math(EXPR _msvc_modules_json_nmodules_range "${_msvc_json_nmodules} - 1")
-  foreach (_msvc_modules_json_modules_idx RANGE 0 "${_msvc_modules_json_nmodules_range}")
-    string(JSON _msvc_modules_json_module_source GET "${_msvc_modules_json}" "module-sources" "${_msvc_modules_json_modules_idx}")
-
-    if (NOT IS_ABSOLUTE "${_msvc_modules_json_module_source}")
-      string(PREPEND _msvc_modules_json_module_source "${_msvc_modules_dir}/")
+    set(_msvc_path ${_msvc_source})
+    cmake_path(IS_RELATIVE _msvc_path _msvc_is_rel)
+    if (_msvc_is_rel)
+      cmake_path(ABSOLUTE_PATH _msvc_path BASE_DIRECTORY "${_msvc_base_dir}")
     endif ()
-    list(APPEND _msvc_modules_module_paths
-      "${_msvc_modules_json_module_source}")
-  endforeach ()
 
-  # Split the paths into basedirs and module paths.
-  set(_msvc_modules_base_dirs_list "")
-  set(_msvc_modules_files "")
-  foreach (_msvc_modules_module_path IN LISTS _msvc_modules_module_paths)
-    get_filename_component(_msvc_module_dir "${_msvc_modules_module_path}" DIRECTORY)
+    if (_msvc_source MATCHES "std.ixx")
+      string(JSON _msvc_module_metadata
+        SET "${_msvc_module_metadata}" "modules" ${idx}
+        "{
+            \"logical-name\": \"std\",
+            \"source-path\": \"${_msvc_path}\",
+            \"is-std-library\": true
+        }"
+      )
+    elseif (_msvc_source MATCHES "std.compat.ixx")
+      string(JSON _msvc_module_metadata
+        SET "${_msvc_module_metadata}" "modules" ${idx}
+        "{
+            \"logical-name\": \"std.compat\",
+            \"source-path\": \"${_msvc_path}\",
+            \"is-std-library\": true
+        }"
+      )
+    endif ()
+  endforeach()
 
-    list(APPEND _msvc_modules_base_dirs_list
-      "${_msvc_module_dir}")
-    string(APPEND _msvc_modules_files
-      " \"${_msvc_modules_module_path}\"")
-  endforeach ()
-  list(REMOVE_DUPLICATES _msvc_modules_base_dirs_list)
-  set(_msvc_modules_base_dirs "")
-  foreach (_msvc_modules_base_dir IN LISTS _msvc_modules_base_dirs_list)
-    string(APPEND _msvc_modules_base_dirs
-      " \"${_msvc_modules_base_dir}\"")
-  endforeach ()
+  string(JSON _msvc_module_metadata_modules_len LENGTH ${_msvc_module_metadata} "modules")
 
-  # Create the file set for the modules.
-  string(APPEND _msvc_std_target
-    "target_sources(__cmake_cxx${std}
-  PUBLIC
-  FILE_SET std TYPE CXX_MODULES
-    BASE_DIRS ${_msvc_modules_base_dirs}
-    FILES ${_msvc_modules_files})\n")
+  # Bail if we didn't recognize any of the modules
+  if (NOT _msvc_module_metadata_modules_len)
+    set(CMAKE_CXX_COMPILER_IMPORT_STD_ERROR_MESSAGE "`modules.json` did not contain any recognized sources (std.ixx, std.compat.ixx)" PARENT_SCOPE)
+    return ()
+  endif ()
 
-  # Wrap the `__cmake_cxx${std}` target in a check.
-  string(PREPEND _msvc_std_target
-    "if (NOT TARGET \"__cmake_cxx${std}\")\n")
-  string(APPEND _msvc_std_target
-    "endif ()\n")
-  string(APPEND _msvc_std_target
-    "add_library(__CMAKE::CXX${std} ALIAS __cmake_cxx${std})\n")
-
-  set("${variable}" "${_msvc_std_target}" PARENT_SCOPE)
+  file(WRITE "${CMAKE_PLATFORM_INFO_DIR}/msvcstl.modules.json" "${_msvc_module_metadata}")
+  set(CMAKE_CXX_STDLIB_MODULES_JSON "${CMAKE_PLATFORM_INFO_DIR}/msvcstl.modules.json" PARENT_SCOPE)
 endfunction ()
diff --git a/Modules/FindMatlab.cmake b/Modules/FindMatlab.cmake
index 8acc6f3..231700a 100644
--- a/Modules/FindMatlab.cmake
+++ b/Modules/FindMatlab.cmake
@@ -5,308 +5,767 @@
 FindMatlab
 ----------
 
-Finds Matlab or Matlab Compiler Runtime (MCR) and provides Matlab tools,
+Finds MATLAB or MATLAB Compiler Runtime (MCR) and provides its tools,
 libraries and compilers to CMake:
 
 .. code-block:: cmake
 
-  find_package(Matlab [<version>] [COMPONENTS <components>...] [...])
+  find_package(Matlab [<version>] [COMPONENTS <components>...] [REGISTRY_VIEW <view>] [...])
 
-This package primary purpose is to find the libraries associated with Matlab
-or the MCR in order to be able to build Matlab extensions (mex files). It
-can also be used:
+The primary purpose of this module is to find the libraries associated with
+MATLAB or the MCR in order to be able to build MATLAB extensions (MEX files).
+It can also be used:
 
-* to run specific commands in Matlab in case Matlab is available
-* for declaring Matlab unit test
-* to retrieve various information from Matlab (mex extensions, versions and
+* to run specific commands in MATLAB in case MATLAB is available
+* for declaring MATLAB unit tests
+* to retrieve various information from MATLAB (MEX extensions, versions and
   release queries, ...)
 
 .. versionadded:: 3.12
-  Added Matlab Compiler Runtime (MCR) support.
-
-The module supports the following components:
-
-* ``ENG_LIBRARY`` and ``MAT_LIBRARY``: respectively the ``ENG`` and ``MAT``
-  libraries of Matlab
-* ``MAIN_PROGRAM`` the Matlab binary program. Note that this component is not
-  available on the MCR version, and will yield an error if the MCR is found
-  instead of the regular Matlab installation.
-* ``MEX_COMPILER`` the MEX compiler.
-* ``MCC_COMPILER`` the MCC compiler, included with the Matlab Compiler add-on.
-* ``SIMULINK`` the Simulink environment.
-
-.. versionadded:: 3.7
-  Added the ``MAT_LIBRARY`` component.
-
-.. versionadded:: 3.13
-  Added the ``ENGINE_LIBRARY``, ``DATAARRAY_LIBRARY`` and ``MCC_COMPILER``
-  components.
-
-.. versionchanged:: 3.14
-  Removed the ``MX_LIBRARY``, ``ENGINE_LIBRARY`` and ``DATAARRAY_LIBRARY``
-  components.  These libraries are found unconditionally.
+  MATLAB Compiler Runtime (MCR) support.
 
 .. versionadded:: 3.30
-  Added support for specifying a version range to :command:`find_package` and
-  added support for specifying ``REGISTRY_VIEW`` to :command:`find_package`,
+  Support for specifying a version range to :command:`find_package`,
+  support for specifying ``REGISTRY_VIEW`` argument to
+  :command:`find_package`,
   :command:`matlab_extract_all_installed_versions_from_registry` and
-  :command:`matlab_get_all_valid_matlab_roots_from_registry`. The default
-  behavior remained unchanged, by using the registry view ``TARGET``.
+  :command:`matlab_get_all_valid_matlab_roots_from_registry` commands.
+  The default behavior remained unchanged, by using the registry view
+  ``TARGET``.
 
 .. note::
 
-  The version given to the :command:`find_package` directive is the Matlab
-  **version**, which should not be confused with the Matlab *release* name
-  (e.g. `R2023b`).
-  The :command:`matlab_get_version_from_release_name` and
-  :command:`matlab_get_release_name_from_version` provide a mapping
-  between the release name and the version.
+  The version given to the :command:`find_package` argument is the MATLAB
+  *version*, which should not be confused with the MATLAB *release name*
+  (e.g. ``R2023b``).  The :command:`matlab_get_version_from_release_name`
+  and :command:`matlab_get_release_name_from_version` commands provide a
+  mapping between the release name and the version.
 
-The variable :variable:`Matlab_ROOT_DIR` may be specified in order to give
-the path of the desired Matlab version. Otherwise, the behavior is platform
-specific:
+Components
+^^^^^^^^^^
 
-* Windows: The installed versions of Matlab/MCR are retrieved from the
-  Windows registry. The ``REGISTRY_VIEW`` argument may optionally be specified
-  to manually control whether 32bit or 64bit versions shall be searched for.
-* macOS: The installed versions of Matlab/MCR are given by the MATLAB
-  default installation paths under ``$HOME/Applications`` and ``/Applications``.
-  If no such application is found, it falls back to the one that might be
-  accessible from the ``PATH``.
-* Unix: The desired Matlab should be accessible from the ``PATH``. This does
-  not work for MCR installation and :variable:`Matlab_ROOT_DIR` should be
-  specified on this platform.
+This module supports optional components which can be specified using the
+:command:`find_package` command:
 
-Additional information is provided when :variable:`MATLAB_FIND_DEBUG` is set.
-When a Matlab/MCR installation is found automatically and the ``MATLAB_VERSION``
-is not given, the version is queried from Matlab directly (on Windows this
-may pop up a Matlab window) or from the MCR installation.
+.. code-block:: cmake
 
-The mapping of the release names and the version of Matlab is performed by
-defining pairs (name, version).  The variable
-:variable:`MATLAB_ADDITIONAL_VERSIONS` may be provided before the call to
-the :command:`find_package` in order to handle additional versions.
+  find_package(Matlab [COMPONENTS <components>...])
 
-A Matlab scripts can be added to the set of tests using the
-:command:`matlab_add_unit_test`. By default, the Matlab unit test framework
-will be used (>= 2013a) to run this script, but regular ``.m`` files
-returning an exit code can be used as well (0 indicating a success).
+Supported components include:
 
-Module Input Variables
-^^^^^^^^^^^^^^^^^^^^^^
+``ENG_LIBRARY``
+  .. versionadded:: 3.3
 
-Users or projects may set the following variables to configure the module
-behavior:
+  Finds the ``ENG`` library of MATLAB.
 
-:variable:`Matlab_ROOT <<PackageName>_ROOT>`
-  .. versionadded:: 3.25
+``MAT_LIBRARY``
+  .. versionadded:: 3.7
 
-  Default value for :variable:`Matlab_ROOT_DIR`, the root of the Matlab
-  installation.
+  Finds the ``MAT`` library of MATLAB.
 
-:variable:`Matlab_ROOT_DIR`
-  The root of the Matlab installation.
+``MAIN_PROGRAM``
+  .. versionadded:: 3.3
 
-:variable:`MATLAB_FIND_DEBUG`
-  outputs debug information
+  Finds the MATLAB binary program.  Note that this component is not
+  available on the MCR version, and will yield an error if the MCR is found
+  instead of the regular MATLAB installation.
 
-:variable:`MATLAB_ADDITIONAL_VERSIONS`
-  additional versions of Matlab for the automatic retrieval of the installed
-  versions.
+``MEX_COMPILER``
+  .. versionadded:: 3.3
+
+  Finds the MEX compiler.
+
+``MCC_COMPILER``
+  .. versionadded:: 3.13
+
+  Finds the MCC compiler, included with the MATLAB Compiler add-on.
+
+``SIMULINK``
+  .. versionadded:: 3.3
+
+  Finds the Simulink environment.
+
+Implicitly Found Components
+"""""""""""""""""""""""""""
+
+The following components are always found unconditionally, without needing
+to be specified explicitly:
+
+``MX_LIBRARY``
+  .. versionchanged:: 3.14
+    This component has been removed and is now always found unconditionally.
+
+  .. versionadded:: 3.3
+
+  Finds the MATLAB mx library.
+
+``ENGINE_LIBRARY``
+  .. versionchanged:: 3.14
+    This component has been removed and is now always found unconditionally.
+
+  .. versionadded:: 3.13
+
+  Finds the MATLAB engine library.
+
+``DATAARRAY_LIBRARY``
+  .. versionchanged:: 3.14
+    This component has been removed and is now always found unconditionally.
+
+  .. versionadded:: 3.13
+
+  Finds the C++ MATLAB data array library.
+
+If no components are specified, the module looks for the ``MX_LIBRARY``,
+``ENGINE_LIBRARY``, and ``DATAARRAY_LIBRARY`` by default.
 
 Imported Targets
 ^^^^^^^^^^^^^^^^
 
-.. versionadded:: 3.22
-
-This module defines the following :prop_tgt:`IMPORTED` targets:
+This module provides the following :ref:`Imported Targets`:
 
 ``Matlab::mex``
-  The ``mex`` library, always available for MATLAB installations. Available for
-  MCR installations if provided by MCR.
+  .. versionadded:: 3.22
+
+  Target encapsulating the ``mex`` library usage requirements, always
+  available for MATLAB installations.  Available for MCR installations if
+  provided by MCR.
 
 ``Matlab::mx``
-  The mx library of Matlab (arrays), always available for MATLAB installations.
-  Available for MCR installations if provided by MCR.
+  .. versionadded:: 3.22
+
+  Target encapsulating the usage requirements of the mx library of MATLAB
+  (arrays), always available for MATLAB installations.  Available for MCR
+  installations if provided by MCR.
 
 ``Matlab::eng``
-  Matlab engine library. Available only if the ``ENG_LIBRARY`` component
-  is requested.
+  .. versionadded:: 3.22
+
+  Target encapsulating the MATLAB engine library usage requirements.
+  Available only if the ``ENG_LIBRARY`` component is requested.
 
 ``Matlab::mat``
-  Matlab matrix library. Available only if the ``MAT_LIBRARY`` component
-  is requested.
+  .. versionadded:: 3.22
+
+  Target encapsulating the MATLAB matrix library usage requirements.
+  Available only if the ``MAT_LIBRARY`` component is requested.
 
 ``Matlab::MatlabEngine``
-  Matlab C++ engine library, always available for MATLAB R2018a and newer.
-  Available for MCR installations if provided by MCR.
+  .. versionadded:: 3.22
+
+  Target encapsulating the MATLAB C++ engine library usage requirements,
+  always available for MATLAB R2018a and newer.  Available for MCR
+  installations if provided by MCR.
 
 ``Matlab::MatlabDataArray``
-  Matlab C++ data array library, always available for MATLAB R2018a and newer.
-  Available for MCR installations if provided by MCR.
+  .. versionadded:: 3.22
 
-Variables defined by the module
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+  Target encapsulating the MATLAB C++ data array library usage requirements,
+  always available for MATLAB R2018a and newer.  Available for MCR
+  installations if provided by MCR.
 
-Result variables
-""""""""""""""""
+Result Variables
+^^^^^^^^^^^^^^^^
+
+This module defines the following variables:
 
 ``Matlab_FOUND``
   .. versionadded:: 3.3
 
-  Boolean indicating whether the (requested version of) Matlab installation
-  was found.  All variables below are defined if Matlab is found.
+  Boolean indicating whether the (requested version of) MATLAB installation
+  was found.  All variables below are defined if MATLAB is found.
 
 ``Matlab_VERSION``
   .. versionadded:: 3.27
 
-  the numerical version (e.g. 23.2.0) of Matlab found. Not to be confused with
-  Matlab release name (e.g. R2023b) that can be obtained with
-  :command:`matlab_get_release_name_from_version`.
+  The numerical version (e.g. ``23.2.0``) of MATLAB found.  Not to be
+  confused with MATLAB release name (e.g. ``R2023b``) that can be obtained
+  with :command:`matlab_get_release_name_from_version`.
+
+  When a MATLAB/MCR installation is found automatically and the
+  ``Matlab_VERSION`` is not given, the version is queried from MATLAB
+  directly (on Windows this may pop up a MATLAB window) or from the MCR
+  installation.
+
 ``Matlab_ROOT_DIR``
-  the final root of the Matlab installation determined by the FindMatlab
-  module.
+  .. versionadded:: 3.3
+
+  The final root of the MATLAB installation determined by this module.
+
 ``Matlab_MAIN_PROGRAM``
-  the Matlab binary program. Available only if the component ``MAIN_PROGRAM``
-  is given in the :command:`find_package` directive.
+  .. versionadded:: 3.3
+
+  The MATLAB binary program.  Available only if the component ``MAIN_PROGRAM``
+  is given in the :command:`find_package` argument.
+
 ``Matlab_INCLUDE_DIRS``
- the path of the Matlab libraries headers
+  .. versionadded:: 3.3
+
+  The path of the MATLAB libraries headers.
+
 ``Matlab_MEX_LIBRARY``
-  library for mex, always available for MATLAB installations. Available for MCR
-  installations if provided by MCR.
+  Library for MEX, always available for MATLAB installations.  Available
+  for MCR installations if provided by MCR.
+
 ``Matlab_MX_LIBRARY``
-  mx library of Matlab (arrays), always available for MATLAB installations.
-  Available for MCR installations if provided by MCR.
+  The mx library of MATLAB (arrays), always available for MATLAB
+  installations.  Available for MCR installations if provided by MCR.
+
 ``Matlab_ENG_LIBRARY``
-  Matlab engine library. Available only if the component ``ENG_LIBRARY``
+  MATLAB engine library.  Available only if the component ``ENG_LIBRARY``
   is requested.
+
 ``Matlab_MAT_LIBRARY``
-  Matlab matrix library. Available only if the component ``MAT_LIBRARY``
+  .. versionadded:: 3.7
+
+  Matlab matrix library.  Available only if the component ``MAT_LIBRARY``
   is requested.
+
 ``Matlab_ENGINE_LIBRARY``
   .. versionadded:: 3.13
 
   Matlab C++ engine library, always available for MATLAB R2018a and newer.
   Available for MCR installations if provided by MCR.
+
 ``Matlab_DATAARRAY_LIBRARY``
   .. versionadded:: 3.13
 
-  Matlab C++ data array library, always available for MATLAB R2018a and newer.
-  Available for MCR installations if provided by MCR.
+  Matlab C++ data array library, always available for MATLAB R2018a and
+  newer.  Available for MCR installations if provided by MCR.
+
 ``Matlab_LIBRARIES``
-  the whole set of libraries of Matlab
+  The whole set of libraries of MATLAB.
+
 ``Matlab_MEX_COMPILER``
-  the mex compiler of Matlab. Currently not used.
-  Available only if the component ``MEX_COMPILER`` is requested.
+  .. versionadded:: 3.3
+
+  The MEX compiler of MATLAB.  Currently not used.  Available only if the
+  component ``MEX_COMPILER`` is requested.
+
 ``Matlab_MCC_COMPILER``
   .. versionadded:: 3.13
 
-  the mcc compiler of Matlab. Included with the Matlab Compiler add-on.
+  The mcc compiler of MATLAB.  Included with the MATLAB Compiler add-on.
   Available only if the component ``MCC_COMPILER`` is requested.
 
-Cached variables
-""""""""""""""""
+Cache Variables
+^^^^^^^^^^^^^^^
+
+The following cache variables may also be set:
 
 ``Matlab_MEX_EXTENSION``
-  the extension of the mex files for the current platform (given by Matlab).
+  .. versionadded:: 3.3
+
+  The extension of the MEX files for the current platform (given by MATLAB).
+
 ``Matlab_ROOT_DIR``
-  the location of the root of the Matlab installation found. If this value
+  .. versionadded:: 3.3
+
+  The location of the root of the MATLAB installation found.  If this value
   is changed by the user, the result variables are recomputed.
 
-Provided commands
-^^^^^^^^^^^^^^^^^
+Input Variables
+^^^^^^^^^^^^^^^
 
-:command:`matlab_get_version_from_release_name`
-  returns the version from the Matlab release name
-:command:`matlab_get_release_name_from_version`
-  returns the release name from the Matlab version
-:command:`matlab_add_mex`
-  adds a target compiling a MEX file.
-:command:`matlab_add_unit_test`
-  adds a Matlab unit test file as a test to the project.
-:command:`matlab_extract_all_installed_versions_from_registry`
-  parses the registry for all Matlab versions. Available on Windows only.
-  The part of the registry parsed is dependent on the host processor
-:command:`matlab_get_all_valid_matlab_roots_from_registry`
-  returns all the possible Matlab or MCR paths, according to a previously
-  given list. Only the existing/accessible paths are kept. This is mainly
-  useful for the searching all possible Matlab installation.
-:command:`matlab_get_mex_suffix`
-  returns the suffix to be used for the mex files
-  (platform/architecture dependent)
-:command:`matlab_get_version_from_matlab_run`
-  returns the version of Matlab/MCR, given the full directory of the Matlab/MCR
-  installation path.
+Users or projects may set the following variables to configure the module
+behavior before calling ``find_package(Matlab)``:
 
+:variable:`Matlab_ROOT <<PackageName>_ROOT>`
+  .. versionadded:: 3.25
 
-Known issues
-^^^^^^^^^^^^
+  Default value for the ``Matlab_ROOT_DIR`` variable, the root of the
+  MATLAB installation.
 
-**Symbol clash in a MEX target**
-  By default, every symbols inside a MEX
-  file defined with the command :command:`matlab_add_mex` have hidden
-  visibility, except for the entry point. This is the default behavior of
-  the MEX compiler, which lowers the risk of symbol collision between the
-  libraries shipped with Matlab, and the libraries to which the MEX file is
-  linking to. This is also the default on Windows platforms.
+``Matlab_ROOT_DIR``
+  .. versionadded:: 3.3
 
-  However, this is not sufficient in certain case, where for instance your
-  MEX file is linking against libraries that are already loaded by Matlab,
-  even if those libraries have different SONAMES.
-  A possible solution is to hide the symbols of the libraries to which the
-  MEX target is linking to. This can be achieved in GNU GCC compilers with
-  the linker option ``-Wl,--exclude-libs,ALL``.
+  The root folder of the MATLAB installation.  If set before the call to
+  :command:`find_package`, the module will look for the components in that
+  path.  If not set, then an automatic search of MATLAB will be performed.
+  If set, it should point to a valid version of MATLAB.
 
-**Tests using GPU resources**
-  in case your MEX file is using the GPU and
-  in order to be able to run unit tests on this MEX file, the GPU resources
-  should be properly released by Matlab. A possible solution is to make
-  Matlab aware of the use of the GPU resources in the session, which can be
-  performed by a command such as ``D = gpuDevice()`` at the beginning of
-  the test script (or via a fixture).
+  This variable may be specified in order to give the path of the desired
+  MATLAB version.  Otherwise, the behavior is platform specific:
 
+  * Windows: The installed versions of MATLAB/MCR are retrieved from the
+    Windows registry.  The ``REGISTRY_VIEW`` argument may optionally be
+    specified to manually control whether 32bit or 64bit versions shall be
+    searched for.
+  * macOS: The installed versions of MATLAB/MCR are given by the MATLAB
+    default installation paths under ``$HOME/Applications`` and
+    ``/Applications``.  If no such application is found, it falls back to
+    the one that might be accessible from the ``PATH``.
+  * Unix: The desired MATLAB should be accessible from the ``PATH``.  This
+    does not work for MCR installation and ``Matlab_ROOT_DIR`` should be
+    specified on this platform.
 
-Reference
-^^^^^^^^^
+``MATLAB_FIND_DEBUG``
+  .. versionadded:: 3.3
 
-.. variable:: Matlab_ROOT_DIR
+  If set to a boolean true, additional debug information is outputted to
+  the console, such as the lookup of MATLAB and the intermediate
+  configuration steps.
 
-   The root folder of the Matlab installation. If set before the call to
-   :command:`find_package`, the module will look for the components in that
-   path. If not set, then an automatic search of Matlab
-   will be performed. If set, it should point to a valid version of Matlab.
+``MATLAB_ADDITIONAL_VERSIONS``
+  .. versionadded:: 3.3
 
-.. variable:: MATLAB_FIND_DEBUG
+  If set, it specifies additional versions of MATLAB for the automatic
+  retrieval of the installed versions that may be handled and looked for.
 
-   If set, the lookup of Matlab and the intermediate configuration steps are
-   outputted to the console.
-
-.. variable:: MATLAB_ADDITIONAL_VERSIONS
-
-  If set, specifies additional versions of Matlab that may be looked for.
-  The variable should be a list of strings, organized by pairs of release
-  name and versions, such as follows:
+  The mapping of the release names and the version of MATLAB is performed
+  by defining pairs (name, version).  The variable should be a list of
+  strings, organized by pairs of release name and versions, such as
+  follows:
 
   .. code-block:: cmake
 
-    set(MATLAB_ADDITIONAL_VERSIONS
+    set(
+      MATLAB_ADDITIONAL_VERSIONS
         "release_name1=corresponding_version1"
         "release_name2=corresponding_version2"
-        ...
-        )
+        # ...
+    )
+
+    find_package(Matlab)
 
   Example:
 
   .. code-block:: cmake
 
-    set(MATLAB_ADDITIONAL_VERSIONS
+    set(
+      MATLAB_ADDITIONAL_VERSIONS
         "R2013b=8.2"
         "R2013a=8.1"
-        "R2012b=8.0")
+        "R2012b=8.0"
+        # ...
+    )
 
-  The order of entries in this list matters when several versions of
-  Matlab are installed. The priority is set according to the ordering in
-  this list.
+    find_package(Matlab)
+
+  The order of entries in this list matters when several versions of MATLAB
+  are installed.  The priority is set according to the ordering in this
+  list.
+
+Commands
+^^^^^^^^
+
+This module provides the following commands:
+
+* :command:`matlab_get_version_from_release_name`
+* :command:`matlab_get_release_name_from_version`
+* :command:`matlab_get_version_from_matlab_run`
+* :command:`matlab_extract_all_installed_versions_from_registry`
+* :command:`matlab_get_all_valid_matlab_roots_from_registry`
+* :command:`matlab_add_mex`
+* :command:`matlab_get_mex_suffix`
+* :command:`matlab_add_unit_test`
+
+.. command:: matlab_get_version_from_release_name
+
+  .. versionadded:: 3.3
+
+  Returns the version of MATLAB from a release name:
+
+  .. code-block:: cmake
+
+    matlab_get_version_from_release_name(<release-name> <version-var>)
+
+  The arguments are:
+
+  ``<release-name>``
+    Input release name string (e.g. ``R2023b``).
+
+  ``<version-var>``
+    The name of the variable in which to store the version of MATLAB.  The
+    output result is e.g. ``23.2.0``.
+
+  .. note::
+
+    This command provides correct versions mappings for MATLAB but not MCR.
+
+.. command:: matlab_get_release_name_from_version
+
+  .. versionadded:: 3.3
+
+  Returns the release name from the version of MATLAB:
+
+  .. code-block:: cmake
+
+    matlab_get_release_name_from_version(<version> <release-name-var>)
+
+  The arguments are:
+
+  ``<version>``
+    Input MATLAB version string (e.g. ``23.2.0``).
+
+  ``<release-name-var>``
+    The name of the variable in which to store the MATLAB release name.  The
+    output result is e.g. ``R2023b``.
+
+  .. note::
+
+    This command provides correct version mappings for MATLAB but not MCR.
+
+.. command:: matlab_get_version_from_matlab_run
+
+  .. versionadded:: 3.3
+
+  Runs the specified MATLAB program and extracts the version of MATLAB/MCR,
+  given the full directory of the MATLAB/MCR installation path:
+
+  .. code-block:: cmake
+
+    matlab_get_version_from_matlab_run(<matlab-binary> <matlab-versions-var>)
+
+  The arguments are:
+
+  ``<matlab-binary>``
+    The path to the ``matlab`` binary executable.
+
+  ``<matlab-versions-var>``
+    The name of the variable in which a list of extracted MATLAB versions
+    are stored.
+
+  If the path provided for the MATLAB installation points to an MCR
+  installation, the version is extracted from the installed files.
+
+.. command:: matlab_extract_all_installed_versions_from_registry
+
+  .. versionadded:: 3.3
+
+  Parses the Windows registry and finds all installed MATLAB versions:
+
+  .. signature::
+    matlab_extract_all_installed_versions_from_registry(<versions-var>
+      [REGISTRY_VIEW <view>])
+    :target: matlab_extract_all_installed_versions_from_registry-keyword
+
+  The arguments are:
+
+  ``<versions-var>``
+    The name of the variable in which to store the list of all MATLAB
+    versions found.
+
+  ``REGISTRY_VIEW <view>``
+    .. versionadded:: 3.30
+
+    Optional registry view argument that provides a more precise interface
+    on how to interact with the Windows Registry.  The argument is passed
+    (or omitted) to :command:`cmake_host_system_information` without
+    further checks or modification.  For example, ``<view>`` value can be
+    one of ``64``, ``32``, ``64_32``, ``32_64``, ``HOST``, ``TARGET``,
+    ``BOTH``.
+
+  The old signature is:
+
+  .. signature::
+    matlab_extract_all_installed_versions_from_registry(<win64> <versions-var>)
+    :target: matlab_extract_all_installed_versions_from_registry-positional
+
+  The arguments are:
+
+  ``<win64>``
+    Boolean whether to search for the 64-bit version of MATLAB.  If set
+    to boolean true, 64-bit registry view will be searched.  If set to
+    boolean false, 32-bit registry view will be searched.  For finer
+    control, use the above signature.
+
+  ``<versions-var>``
+    The name of the variable in which to store the list of all MATLAB
+    versions found.
+
+  This command is available on Windows only.  The part of the registry
+  parsed is dependent on the host processor.
+
+  The returned list contains all versions under
+  ``HKLM\SOFTWARE\Mathworks\MATLAB``,
+  ``HKLM\SOFTWARE\Mathworks\MATLAB Runtime`` and
+  ``HKLM\SOFTWARE\Mathworks\MATLAB Compiler Runtime`` or an empty list in
+  case an error occurred (or nothing found).
+
+  .. note::
+
+    Only the versions are provided.  No check is made over the existence of
+    the installation referenced in the registry.
+
+.. command:: matlab_get_all_valid_matlab_roots_from_registry
+
+  .. versionadded:: 3.3
+
+  Returns all the possible MATLAB or MCR paths, according to a previously
+  given list:
+
+  .. code-block:: cmake
+
+    matlab_get_all_valid_matlab_roots_from_registry(
+      <matlab-versions>
+      <matlab-roots-var>
+      [REGISTRY_VIEW <view>]
+    )
+
+  This command populates the MATLAB root with valid versions of MATLAB or
+  MATLAB Runtime (MCR) and is mainly useful for the searching of all
+  possible MATLAB installations.  Only the existing/accessible paths are
+  kept.
+
+  The arguments are:
+
+  ``<matlab-versions>``
+    A :ref:`semicolon-separated list <CMake Language Lists>` of each of the
+    MATLAB or MCR installations.  Specify it as a single string value.
+
+  ``<matlab-roots-var>``
+    The name of the variable in which to store a list of locations of each
+    of the MATLAB or MCR installations.
+
+    The value of this variable is organized in triplets
+    ``(type,version_number,matlab_root_path)``, where ``type`` indicates
+    either ``MATLAB`` or ``MCR``.
+
+  ``REGISTRY_VIEW <view>``
+    .. versionadded:: 3.30
+
+    Optional registry view argument that provides a more precise interface
+    on how to interact with the Windows Registry.  The argument is passed
+    (or omitted) to :command:`cmake_host_system_information` without
+    further checks or modification.  For example, ``<view>`` value can be
+    one of ``64``, ``32``, ``64_32``, ``32_64``, ``HOST``, ``TARGET``,
+    ``BOTH``.
+
+.. command:: matlab_add_mex
+
+  .. versionadded:: 3.3
+
+  Adds a target that compiles MATLAB MEX target file:
+
+  .. code-block:: cmake
+
+    matlab_add_mex(
+      NAME <name>
+      [EXECUTABLE | MODULE | SHARED]
+      SRC <sources>...
+      [OUTPUT_NAME <output-name>]
+      [DOCUMENTATION <file>]
+      [LINK_TO <targets>...]
+      [R2017b | R2018a]
+      [EXCLUDE_FROM_ALL]
+      [NO_IMPLICIT_LINK_TO_MATLAB_LIBRARIES]
+      [...]
+    )
+
+  This commands compiles the given sources with the current tool-chain in
+  order to produce a MEX file.  The final name of the produced output may
+  be specified, as well as additional link libraries, and a documentation
+  entry for the MEX file.  Remaining arguments of the call are passed to
+  the :command:`add_library` or :command:`add_executable` command.
+
+  The arguments are:
+
+  ``NAME <name>``
+    The name of the target.
+
+  ``SRC <sources>...``
+    One or more source files to be compiled.
+
+  ``LINK_TO <targets>...``
+    A list of additional link dependencies.  The target links to ``libmex``
+    and ``libmx`` by default, unless the
+    ``NO_IMPLICIT_LINK_TO_MATLAB_LIBRARIES`` option is passed.
+
+  ``OUTPUT_NAME <output-name>``
+    If given, overrides the default name.  The default name is the name of
+    the target without any prefix and with ``Matlab_MEX_EXTENSION`` suffix.
+
+  ``DOCUMENTATION <file>``
+    If given, the ``<file>`` will be considered as being the documentation
+    file for the MEX file.  This file is copied into the same folder without
+    any processing, with the same name as the final MEX file, and with
+    extension ``.m``.  In that case, typing ``help <name>`` in MATLAB
+    prints the documentation contained in this file.
+
+    The documentation file is not processed and should be in the following
+    format:
+
+    .. code-block:: matlab
+
+      % This is the documentation
+      function ret = mex_target_output_name(input1)
+
+  ``R2017b`` or ``R2018a``
+    .. versionadded:: 3.14
+
+    May be given to specify the version of the C API
+    to use: ``R2017b`` specifies the traditional (separate complex) C API,
+    and corresponds to the ``-R2017b`` flag for the ``mex`` command.
+    ``R2018a`` specifies the new interleaved complex C API, and corresponds
+    to the ``-R2018a`` flag for the ``mex`` command.  Ignored for MATLAB
+    versions prior to R2018a.  Defaults to ``R2017b``.
+
+  ``MODULE`` or ``SHARED``
+    .. versionadded:: 3.7
+
+    May be given to specify the type of library to be created.
+
+  ``EXECUTABLE``
+    .. versionadded:: 3.7
+
+    May be given to create an executable instead of a library.  If no type
+    is given explicitly, the default type is ``SHARED``.
+
+  ``EXCLUDE_FROM_ALL``
+    This option has the same meaning as the :prop_tgt:`EXCLUDE_FROM_ALL`
+    target property and is forwarded to the :command:`add_library`, or
+    :command:`add_executable` command.
+
+  ``NO_IMPLICIT_LINK_TO_MATLAB_LIBRARIES``
+    .. versionadded:: 3.24
+
+    This option permits to disable the automatic linking of MATLAB
+    libraries, so that only the libraries that are actually required can be
+    linked via the ``LINK_TO`` option.
+
+.. command:: matlab_get_mex_suffix
+
+  .. versionadded:: 3.3
+
+  Returns the extension to be used for the MEX files (the suffix):
+
+  .. code-block:: cmake
+
+    matlab_get_mex_suffix(<matlab-root> <mex-suffix-var>)
+
+  The arguments are:
+
+  ``<matlab-root>``
+    The root of MATLAB/MCR installation.  For example, the value of the
+    ``Matlab_ROOT_DIR`` variable.
+
+  ``<mex-suffix-var>``
+    The name of the variable in which the suffix will be returned.
+
+  This command is platform and architecture dependent.  It should not be
+  called before the appropriate MATLAB root has been found.
+
+.. command:: matlab_add_unit_test
+
+  .. versionadded:: 3.3
+
+  Adds a MATLAB unit test file to the project's test set of CMake/CTest:
+
+  .. code-block:: cmake
+
+    matlab_add_unit_test(
+      NAME <name>
+      UNITTEST_FILE <matlab-file-containing-unittest.m>
+      [CUSTOM_TEST_COMMAND <matlab-command-to-run-as-test>]
+      [UNITTEST_PRECOMMAND <matlab-command-to-run>]
+      [TIMEOUT <timeout>]
+      [ADDITIONAL_PATH <paths>...]
+      [MATLAB_ADDITIONAL_STARTUP_OPTIONS <options>...]
+      [TEST_ARGS <args>...]
+      [NO_UNITTEST_FRAMEWORK]
+      [WORKING_DIRECTORY <dir>]
+    )
+
+  By default, the MATLAB unit test framework will be used (>= 2013a) to run
+  the added MATLAB script, but regular ``.m`` files returning an exit code
+  can be used as well (0 indicating a success).
+
+  This command requires the component ``MAIN_PROGRAM`` and hence is not
+  available for an MCR installation.
+
+  The unit test uses the MATLAB unittest framework (default, available
+  starting MATLAB 2013b+) except if the option ``NO_UNITTEST_FRAMEWORK``
+  is given.
+
+  The command expects one MATLAB test script file to be given.
+  In the case ``NO_UNITTEST_FRAMEWORK`` is given, the unittest script file
+  should contain the script to be run, plus an exit command with the exit
+  value.  This exit value will be passed to the ctest framework (0 success,
+  non 0 failure).  Additional arguments accepted by :command:`add_test` can
+  be passed through ``TEST_ARGS`` (e.g. ``CONFIGURATIONS <config> ...``).
+
+  The arguments are:
+
+  ``NAME <name>``
+    The name of the unittest in ctest.
+
+  ``UNITTEST_FILE <matlab-file-containing-unittest.m>``
+    The MATLAB unittest file.  Its path will be automatically added to the
+    MATLAB path.
+
+  ``CUSTOM_TEST_COMMAND <matlab-command-to-run-as-test>``
+    MATLAB script command to run as the test.
+    If this is not set, then the following is run:
+    ``runtests('matlab_file_name'), exit(max([ans(1,:).Failed]))`` where
+    ``matlab_file_name`` is the ``UNITTEST_FILE`` without the extension.
+
+  ``UNITTEST_PRECOMMAND <matlab-command-to-run>``
+    MATLAB script command to be ran before the file
+    containing the test (e.g. GPU device initialization based on CMake
+    variables).
+
+  ``TIMEOUT <timeout>``
+    The test timeout in seconds.  Defaults to 180 seconds as the
+    MATLAB unit test may hang.
+
+  ``ADDITIONAL_PATH <paths>...``
+    A list of paths to add to the MATLAB path prior to running the unit
+    test.
+
+  ``MATLAB_ADDITIONAL_STARTUP_OPTIONS <options>``
+    A list of additional option in order to run MATLAB from the command
+    line.  The ``-nosplash``, ``-nodesktop``, and ``-nodisplay`` options
+    are always added automatically.
+
+  ``TEST_ARGS <args>...``
+    Additional options provided to the add_test command.  These
+    options are added to the default options (e.g. ``CONFIGURATIONS Release``).
+
+  ``NO_UNITTEST_FRAMEWORK``
+    When set, indicates that the test should not
+    use the unittest framework of MATLAB (available for versions >= R2013a).
+
+  ``WORKING_DIRECTORY <dir>``
+    This will be the working directory for the test.  If specified it will
+    also be the output directory used for the log file of the test run.
+    If not specified the temporary directory ``${CMAKE_BINARY_DIR}/Matlab``
+    will be used as the working directory and the log location.
+
+Known Issues
+^^^^^^^^^^^^
+
+**Symbol clash in a MEX target**
+  By default, every symbol inside a MEX
+  file defined with the command :command:`matlab_add_mex` have hidden
+  visibility, except for the entry point.  This is the default behavior of
+  the MEX compiler, which lowers the risk of symbol collision between the
+  libraries shipped with MATLAB, and the libraries to which the MEX file is
+  linking to.  This is also the default on Windows platforms.
+
+  However, this is not sufficient in certain case, where for instance the
+  MEX file is linking against libraries that are already loaded by MATLAB,
+  even if those libraries have different SONAMES.
+  A possible solution is to hide the symbols of the libraries to which the
+  MEX target is linking to.  This can be achieved in GNU GCC compilers with
+  the linker option ``-Wl,--exclude-libs,ALL``.
+
+**Tests using GPU resources**
+  In case the MEX file is using the GPU and in order to be able to run unit
+  tests on this MEX file, the GPU resources should be properly released by
+  MATLAB.  A possible solution is to make MATLAB aware of the use of the
+  GPU resources in the session, which can be performed by a command, such
+  as ``D = gpuDevice()``, at the beginning of the test script (or via a
+  fixture).
+
+Examples
+^^^^^^^^
+
+Finding MATLAB and linking imported target to a project target:
+
+.. code-block:: cmake
+
+  find_package(Matlab)
+  target_link_libraries(example PRIVATE Matlab::mx)
 #]=======================================================================]
 
 cmake_policy(PUSH)
@@ -370,23 +829,7 @@
 
 file(MAKE_DIRECTORY "${_matlab_temporary_folder}")
 
-#[=======================================================================[.rst:
-.. command:: matlab_get_version_from_release_name
-
-  .. code-block:: cmake
-
-    matlab_get_version_from_release_name(release version)
-
-  * Input: ``release`` is the release name (e.g. R2023b)
-  * Output: ``version`` is the version of Matlab (e.g. 23.2.0)
-
-  Returns the version of Matlab from a release name
-
-  .. note::
-
-    This command provides correct versions mappings for Matlab but not MCR.
-
-#]=======================================================================]
+# Public.
 macro(matlab_get_version_from_release_name release_name version_name)
 
   string(REGEX MATCHALL "${release_name}=([0-9]+\\.[0-9]+)" _matched ${MATLAB_VERSIONS_MAPPING})
@@ -401,24 +844,7 @@
 
 endmacro()
 
-
-#[=======================================================================[.rst:
-.. command:: matlab_get_release_name_from_version
-
-  .. code-block:: cmake
-
-    matlab_get_release_name_from_version(version release_name)
-
-  * Input: ``version`` is the version of Matlab (e.g. 23.2.0)
-  * Output: ``release_name`` is the release name (R2023b)
-
-  Returns the release name from the version of Matlab
-
-  .. note::
-
-    This command provides correct version mappings for Matlab but not MCR.
-
-#]=======================================================================]
+# Public.
 function(matlab_get_release_name_from_version version release_name)
 
   # only the major.minor version is used
@@ -435,7 +861,6 @@
 
 endfunction()
 
-
 # extracts all the supported release names (R2022b...) of Matlab
 # internal use
 macro(matlab_get_supported_releases list_releases)
@@ -451,8 +876,6 @@
   unset(_var)
 endmacro()
 
-
-
 # extracts all the supported versions of Matlab
 # internal use
 macro(matlab_get_supported_versions list_versions)
@@ -468,47 +891,7 @@
   unset(_var)
 endmacro()
 
-
-#[=======================================================================[.rst:
-.. command:: matlab_extract_all_installed_versions_from_registry
-
-  This function parses the Windows registry and finds the Matlab versions that
-  are installed. The found versions are stored in a given ``<versions-var>``.
-
-  .. signature::
-    matlab_extract_all_installed_versions_from_registry(<versions-var>
-      [REGISTRY_VIEW view])
-    :target: matlab_extract_all_installed_versions_from_registry-keyword
-
-    .. versionadded:: 3.30
-
-    * Output: ``<versions-var>`` is a list of all the versions of Matlab found
-    * Input: ``REGISTRY_VIEW`` Optional registry view to use for registry
-      interaction. The argument is passed (or omitted) to
-      :command:`cmake_host_system_information` without further checks or
-      modification.
-
-  .. signature::
-    matlab_extract_all_installed_versions_from_registry(<win64> <versions-var>)
-    :target: matlab_extract_all_installed_versions_from_registry-positional
-
-    * Input: ``win64`` is a boolean to search for the 64 bit version of
-      Matlab. Set to ``ON`` to use the 64bit registry view or ``OFF`` to use the
-      32bit registry view. If finer control is needed, see signature above.
-    * Output: ``<versions-var>`` is a list of all the versions of Matlab found
-
-  The returned list contains all versions under
-  ``HKLM\SOFTWARE\Mathworks\MATLAB``,
-  ``HKLM\SOFTWARE\Mathworks\MATLAB Runtime`` and
-  ``HKLM\SOFTWARE\Mathworks\MATLAB Compiler Runtime`` or an empty list in
-  case an error occurred (or nothing found).
-
-  .. note::
-
-    Only the versions are provided. No check is made over the existence of the
-    installation referenced in the registry,
-
-#]=======================================================================]
+# Public.
 function(matlab_extract_all_installed_versions_from_registry win64_or_matlab_versions)
 
   if(NOT CMAKE_HOST_WIN32)
@@ -562,8 +945,6 @@
 
 endfunction()
 
-
-
 # (internal)
 macro(extract_matlab_versions_from_registry_brute_force matlab_versions)
   # get the supported versions
@@ -579,32 +960,7 @@
   set(${matlab_versions} ${matlab_supported_versions})
 endmacro()
 
-
-#[=======================================================================[.rst:
-.. command:: matlab_get_all_valid_matlab_roots_from_registry
-
-  Populates the Matlab root with valid versions of Matlab or
-  Matlab Runtime (MCR).
-  The returned matlab_roots is organized in triplets
-  ``(type,version_number,matlab_root_path)``, where ``type``
-  indicates either ``MATLAB`` or ``MCR``.
-
-  .. code-block:: cmake
-
-    matlab_get_all_valid_matlab_roots_from_registry(matlab_versions matlab_roots [REGISTRY_VIEW view])
-
-  * Input: ``matlab_versions`` of each of the Matlab or MCR installations
-  * Output: ``matlab_roots`` location of each of the Matlab or MCR installations
-  * Input: ``REGISTRY_VIEW`` Optional registry view to use for registry
-    interaction. The argument is passed (or omitted) to
-    :command:`cmake_host_system_information` without further checks or
-    modification.
-
-  .. versionadded:: 3.30
-    The optional ``REGISTRY_VIEW`` argument was added to provide a more precise
-    interface on how to interact with the Windows Registry.
-
-#]=======================================================================]
+# Public.
 function(matlab_get_all_valid_matlab_roots_from_registry matlab_versions matlab_roots)
 
   # The matlab_versions comes either from
@@ -672,20 +1028,7 @@
   set(${matlab_roots} ${_matlab_roots_list} PARENT_SCOPE)
 endfunction()
 
-#[=======================================================================[.rst:
-.. command:: matlab_get_mex_suffix
-
-  Returns the extension of the mex files (the suffixes).
-  This function should not be called before the appropriate Matlab root has
-  been found.
-
-  .. code-block:: cmake
-
-    matlab_get_mex_suffix(matlab_root mex_suffix)
-
-  * Input: ``matlab_root`` root of Matlab/MCR install e.g. ``Matlab_ROOT_DIR``
-  * Output: ``mex_suffix`` variable name in which the suffix will be returned.
-#]=======================================================================]
+# Public.
 function(matlab_get_mex_suffix matlab_root mex_suffix)
 
   # find_program does not consider script suffix .bat for Matlab mexext.bat on Windows
@@ -761,21 +1104,7 @@
   set(${mex_suffix} ${_matlab_mex_extension} PARENT_SCOPE)
 endfunction()
 
-
-#[=======================================================================[.rst:
-.. command:: matlab_get_version_from_matlab_run
-
-  This function runs Matlab program specified on arguments and extracts its
-  version. If the path provided for the Matlab installation points to an MCR
-  installation, the version is extracted from the installed files.
-
-  .. code-block:: cmake
-
-    matlab_get_version_from_matlab_run(matlab_binary_path matlab_list_versions)
-
-  * Input: ``matlab_binary_path`` path of the `matlab` binary executable
-  * Output: ``matlab_list_versions`` the version extracted from Matlab
-#]=======================================================================]
+# Public.
 function(matlab_get_version_from_matlab_run matlab_binary_program matlab_list_versions)
 
   set(${matlab_list_versions} "" PARENT_SCOPE)
@@ -926,77 +1255,7 @@
 
 endfunction()
 
-#[=======================================================================[.rst:
-.. command:: matlab_add_unit_test
-
-  Adds a Matlab unit test to the test set of cmake/ctest.
-  This command requires the component ``MAIN_PROGRAM`` and hence is not
-  available for an MCR installation.
-
-  The unit test uses the Matlab unittest framework (default, available
-  starting Matlab 2013b+) except if the option ``NO_UNITTEST_FRAMEWORK``
-  is given.
-
-  The function expects one Matlab test script file to be given.
-  In the case ``NO_UNITTEST_FRAMEWORK`` is given, the unittest script file
-  should contain the script to be run, plus an exit command with the exit
-  value. This exit value will be passed to the ctest framework (0 success,
-  non 0 failure). Additional arguments accepted by :command:`add_test` can be
-  passed through ``TEST_ARGS`` (eg. ``CONFIGURATION <config> ...``).
-
-  .. code-block:: cmake
-
-    matlab_add_unit_test(
-        NAME <name>
-        UNITTEST_FILE matlab_file_containing_unittest.m
-        [CUSTOM_TEST_COMMAND matlab_command_to_run_as_test]
-        [UNITTEST_PRECOMMAND matlab_command_to_run]
-        [TIMEOUT timeout]
-        [ADDITIONAL_PATH path1 [path2 ...]]
-        [MATLAB_ADDITIONAL_STARTUP_OPTIONS option1 [option2 ...]]
-        [TEST_ARGS arg1 [arg2 ...]]
-        [NO_UNITTEST_FRAMEWORK]
-        )
-
-  Function Parameters:
-
-  ``NAME``
-    name of the unittest in ctest.
-  ``UNITTEST_FILE``
-    the matlab unittest file. Its path will be automatically
-    added to the Matlab path.
-  ``CUSTOM_TEST_COMMAND``
-    Matlab script command to run as the test.
-    If this is not set, then the following is run:
-    ``runtests('matlab_file_name'), exit(max([ans(1,:).Failed]))``
-    where ``matlab_file_name`` is the ``UNITTEST_FILE`` without the extension.
-  ``UNITTEST_PRECOMMAND``
-    Matlab script command to be ran before the file
-    containing the test (eg. GPU device initialization based on CMake
-    variables).
-  ``TIMEOUT``
-    the test timeout in seconds. Defaults to 180 seconds as the
-    Matlab unit test may hang.
-  ``ADDITIONAL_PATH``
-    a list of paths to add to the Matlab path prior to
-    running the unit test.
-  ``MATLAB_ADDITIONAL_STARTUP_OPTIONS``
-    a list of additional option in order
-    to run Matlab from the command line.
-    ``-nosplash -nodesktop -nodisplay`` are always added.
-  ``TEST_ARGS``
-    Additional options provided to the add_test command. These
-    options are added to the default options (eg. "CONFIGURATIONS Release")
-  ``NO_UNITTEST_FRAMEWORK``
-    when set, indicates that the test should not
-    use the unittest framework of Matlab (available for versions >= R2013a).
-  ``WORKING_DIRECTORY``
-    This will be the working directory for the test. If specified it will
-    also be the output directory used for the log file of the test run.
-    If not specified the temporary directory ``${CMAKE_BINARY_DIR}/Matlab`` will
-    be used as the working directory and the log location.
-
-#]=======================================================================]
+# Public.
 function(matlab_add_unit_test)
 
   if(NOT Matlab_MAIN_PROGRAM)
@@ -1049,93 +1308,7 @@
            )
 endfunction()
 
-
-#[=======================================================================[.rst:
-.. command:: matlab_add_mex
-
-  Adds a Matlab MEX target.
-  This commands compiles the given sources with the current tool-chain in
-  order to produce a MEX file. The final name of the produced output may be
-  specified, as well as additional link libraries, and a documentation entry
-  for the MEX file. Remaining arguments of the call are passed to the
-  :command:`add_library` or :command:`add_executable` command.
-
-  .. code-block:: cmake
-
-     matlab_add_mex(
-         NAME <name>
-         [EXECUTABLE | MODULE | SHARED]
-         SRC src1 [src2 ...]
-         [OUTPUT_NAME output_name]
-         [DOCUMENTATION file.txt]
-         [LINK_TO target1 target2 ...]
-         [R2017b | R2018a]
-         [EXCLUDE_FROM_ALL]
-         [NO_IMPLICIT_LINK_TO_MATLAB_LIBRARIES]
-         [...]
-     )
-
-  Function Parameters:
-
-  ``NAME``
-    name of the target.
-  ``SRC``
-    list of source files.
-  ``LINK_TO``
-    a list of additional link dependencies.  The target links to ``libmex``
-    and ``libmx`` by default, unless the
-    ``NO_IMPLICIT_LINK_TO_MATLAB_LIBRARIES`` option is passed.
-  ``OUTPUT_NAME``
-    if given, overrides the default name. The default name is
-    the name of the target without any prefix and
-    with ``Matlab_MEX_EXTENSION`` suffix.
-  ``DOCUMENTATION``
-    if given, the file ``file.txt`` will be considered as
-    being the documentation file for the MEX file. This file is copied into
-    the same folder without any processing, with the same name as the final
-    mex file, and with extension `.m`. In that case, typing ``help <name>``
-    in Matlab prints the documentation contained in this file.
-  ``R2017b`` or ``R2018a``
-    .. versionadded:: 3.14
-
-    May be given to specify the version of the C API
-    to use: ``R2017b`` specifies the traditional (separate complex) C API,
-    and corresponds to the ``-R2017b`` flag for the `mex` command. ``R2018a``
-    specifies the new interleaved complex C API, and corresponds to the
-    ``-R2018a`` flag for the `mex` command. Ignored if MATLAB version prior
-    to R2018a. Defaults to ``R2017b``.
-
-  ``MODULE`` or ``SHARED``
-    .. versionadded:: 3.7
-
-    May be given to specify the type of library to be
-    created.
-
-  ``EXECUTABLE``
-    .. versionadded:: 3.7
-
-    May be given to create an executable instead of
-    a library. If no type is given explicitly, the type is ``SHARED``.
-  ``EXCLUDE_FROM_ALL``
-    This option has the same meaning as for :prop_tgt:`EXCLUDE_FROM_ALL` and
-    is forwarded to :command:`add_library` or :command:`add_executable`
-    commands.
-  ``NO_IMPLICIT_LINK_TO_MATLAB_LIBRARIES``
-    .. versionadded:: 3.24
-
-    This option permits to disable the automatic linking of MATLAB
-    libraries, so that only the libraries that are actually required can be
-    linked via the ``LINK_TO`` option.
-
-  The documentation file is not processed and should be in the following
-  format:
-
-  ::
-
-    % This is the documentation
-    function ret = mex_target_output_name(input1)
-
-#]=======================================================================]
+# Public.
 function(matlab_add_mex)
 
   set(options EXECUTABLE MODULE SHARED R2017b R2018a EXCLUDE_FROM_ALL NO_IMPLICIT_LINK_TO_MATLAB_LIBRARIES)
@@ -1331,7 +1504,6 @@
 
 endfunction()
 
-
 # (internal)
 # Used to get the version of matlab, using caching. This basically transforms the
 # output of the root list, with possible unknown version, to a version
@@ -1477,7 +1649,6 @@
 
 endfunction()
 
-
 function(_Matlab_VersionInfoXML matlab_root _version)
 
   set(_ver "unknown")
@@ -1496,7 +1667,6 @@
 
 endfunction()
 
-
 # Utility function for finding Matlab or MCR on Win32
 function(_Matlab_find_instances_win32 matlab_roots)
   # On WIN32, we look for Matlab installation in the registry
@@ -1819,7 +1989,6 @@
 endif()
 
 
-
 set(MATLAB_INCLUDE_DIR_TO_LOOK ${Matlab_ROOT_DIR}/extern/include)
 if(CMAKE_SIZEOF_VOID_P EQUAL 4)
   set(_matlab_current_suffix ${_matlab_bin_suffix_32bits})
@@ -1851,8 +2020,6 @@
   message(STATUS "[MATLAB] _matlab_lib_prefix_for_search = ${_matlab_lib_prefix_for_search} | _matlab_lib_dir_for_search = ${_matlab_lib_dir_for_search}")
 endif()
 
-
-
 # internal
 # This small stub around find_library is to prevent any pollution of CMAKE_FIND_LIBRARY_PREFIXES in the global scope.
 # This is the function to be used below instead of the find_library directives.
diff --git a/Modules/FindOpenGL.cmake b/Modules/FindOpenGL.cmake
index da01072..ceae29b 100644
--- a/Modules/FindOpenGL.cmake
+++ b/Modules/FindOpenGL.cmake
@@ -240,7 +240,9 @@
       correspond to GLVND libraries).
 
   ``LEGACY``
-    Prefer to use the legacy libGL library, if available.
+    Prefer to use the legacy libGL library, if available. This makes
+    ``OPENGL_opengl_LIBRARY`` and ``OPENGL_glx_LIBRARY``
+    point to ``OPENGL_gl_LIBRARY``.
 
 .. _`Linux Specific`:
 
@@ -255,12 +257,10 @@
 ``OpenGL::GLX`` or ``OpenGL::EGL``.
 
 Projects may use the ``OpenGL::GL`` target (or ``OPENGL_LIBRARIES`` variable)
-to use legacy GL interfaces.  These will use the legacy GL library located
-by ``OPENGL_gl_LIBRARY``, if available.  If ``OPENGL_gl_LIBRARY`` is empty or
-not found and GLVND is available, the ``OpenGL::GL`` target will use GLVND
-``OpenGL::OpenGL`` and ``OpenGL::GLX`` (and the ``OPENGL_LIBRARIES``
-variable will use the corresponding libraries).  Thus, for non-EGL-based
-Linux targets, the ``OpenGL::GL`` target is most portable.
+to use legacy GL interfaces.  Depending on ``OpenGL_GL_PREFERENCE``, these
+will either use the legacy GL library or the GLVND ``OpenGL::OpenGL`` and
+``OpenGL::GLX``.  Thus, for non-EGL-based Linux targets,
+the ``OpenGL::GL`` target is most portable.
 
 The ``OpenGL_GL_PREFERENCE`` variable may be set to specify the preferred way
 to provide legacy GL interfaces in case multiple choices are available.
@@ -529,6 +529,12 @@
     list(APPEND _OpenGL_CACHE_VARS OPENGL_gl_LIBRARY)
   endif()
 
+  # When preferring legacy, linking OpenGL and GLX should behave the same as linking legacy GL.
+  if(OpenGL_GL_PREFERENCE STREQUAL "LEGACY")
+    set(OpenGL_glx_LIBRARY "${OPENGL_gl_LIBRARY}")
+    set(OpenGL_opengl_LIBRARY "${OPENGL_gl_LIBRARY}")
+  endif()
+
   if(_OpenGL_GL_POLICY_WARN AND OPENGL_gl_LIBRARY AND OPENGL_opengl_LIBRARY AND OPENGL_glx_LIBRARY)
     cmake_policy(GET_WARNING CMP0072 _cmp0072_warning)
     message(AUTHOR_WARNING
diff --git a/Modules/GNUInstallDirs.cmake b/Modules/GNUInstallDirs.cmake
index f677c27..c2aa29a 100644
--- a/Modules/GNUInstallDirs.cmake
+++ b/Modules/GNUInstallDirs.cmake
@@ -86,6 +86,15 @@
 
   On Debian, this may be ``lib/<multiarch-tuple>`` when
   :variable:`CMAKE_INSTALL_PREFIX` is ``/usr``.
+
+  .. note::
+
+    When an alternative installation prefix is specified with the
+    :option:`--prefix <cmake--install --prefix>` option at install time,
+    the special case with multi-architecture tuple is evaluated based on
+    the configuration-time :variable:`CMAKE_INSTALL_PREFIX`, not on the
+    alternative prefix value.
+
 ``INCLUDEDIR``
   C header files (``include``)
 ``OLDINCLUDEDIR``
@@ -94,6 +103,12 @@
   read-only architecture-independent data root (``share``)
 ``DATADIR``
   read-only architecture-independent data (``DATAROOTDIR``)
+
+  The ``DATADIR`` and ``DATAROOTDIR`` are treated separately so that
+  ``DATADIR`` can be customized for project-specific data files, while
+  ``DATAROOTDIR`` remains unchanged for standard architecture-independent
+  locations ``INFODIR``, ``LOCALEDIR``, ``MANDIR``, and ``DOCDIR``.
+
 ``INFODIR``
   info documentation (``DATAROOTDIR/info``)
 ``LOCALEDIR``
@@ -168,6 +183,13 @@
     absolute paths ``/etc/opt/...``, ``/var/opt/...`` and
     ``/var/run/opt/...`` respectively. See policy :policy:`CMP0192`.
 
+.. note::
+
+  When an alternative installation prefix is specified with the
+  :option:`--prefix <cmake--install --prefix>` option at install time,
+  these special cases are evaluated based on the configuration-time
+  :variable:`CMAKE_INSTALL_PREFIX`, not on the alternative prefix value.
+
 .. _`Filesystem Hierarchy Standard`: https://refspecs.linuxfoundation.org/FHS_3.0/fhs/index.html
 
 Commands
diff --git a/Modules/GoogleTest.cmake b/Modules/GoogleTest.cmake
index 2fded3f..5f4eaf8 100644
--- a/Modules/GoogleTest.cmake
+++ b/Modules/GoogleTest.cmake
@@ -332,7 +332,7 @@
 
 # Save project's policies
 block(SCOPE_FOR POLICIES)
-cmake_policy(VERSION 3.30)
+cmake_policy(VERSION 4.2)
 
 #------------------------------------------------------------------------------
 function(gtest_add_tests)
diff --git a/Modules/GoogleTestAddTests.cmake b/Modules/GoogleTestAddTests.cmake
index 940cea0..b12a336 100644
--- a/Modules/GoogleTestAddTests.cmake
+++ b/Modules/GoogleTestAddTests.cmake
@@ -1,8 +1,7 @@
 # Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
 # file LICENSE.rst or https://cmake.org/licensing for details.
 
-cmake_minimum_required(VERSION 3.30)
-cmake_policy(SET CMP0174 NEW)   # TODO: Remove this when we can update the above to 3.31
+cmake_minimum_required(VERSION 4.2)
 
 function(add_command name test_name)
   set(args "")
@@ -383,6 +382,7 @@
       "Error running test executable.\n"
       "  Path: '${path}'\n"
       "  Working directory: '${arg_TEST_WORKING_DIR}'\n"
+      "  Timeout: '${arg_TEST_DISCOVERY_TIMEOUT}'\n"
       "  Result: ${result}\n"
       "  Output:\n"
       "    ${output}\n"
diff --git a/Modules/UseJava.cmake b/Modules/UseJava.cmake
index b79d8d2..4192169 100644
--- a/Modules/UseJava.cmake
+++ b/Modules/UseJava.cmake
@@ -53,6 +53,7 @@
             [SOURCES] <source1> [<source2>...] [<resource1>...]
             [RESOURCES NAMESPACE <ns1> <resource1>... [NAMESPACE <nsX> <resourceX>...]... ]
             [INCLUDE_JARS <jar1> [<jar2>...]]
+            [INCLUDE_MODULES <jar1> [<jar2>...]]
             [ENTRY_POINT <entry>]
             [VERSION <version>]
             [MANIFEST <manifest>]
@@ -109,6 +110,13 @@
     jar files listed as sources are ignored (as they have been since the first
     version of this module).
 
+  ``INCLUDE_MODULES``
+    .. versionadded:: 4.3
+
+    The list of jars are added to the module path when building the java sources
+    and also to the dependencies of the target. ``INCLUDE_MODULES`` also
+    accepts other target names created by ``add_jar()``.
+
   ``ENTRY_POINT``
     Defines an entry point in the jar file.
 
@@ -568,6 +576,9 @@
     generated docs. Same behavior as option ``-version`` of ``javadoc`` tool.
 #]=======================================================================]
 
+block(SCOPE_FOR POLICIES)
+cmake_policy(SET CMP0140 NEW) # For return(PROPAGATE ...)
+
 function (__java_copy_file src dest comment)
     add_custom_command(
         OUTPUT  ${dest}
@@ -665,11 +676,42 @@
     set(_UseJava_PATH_SEP ":")
 endif()
 
+function(__java_resolve_jar outvar_path path_or_tgt)
+    if (TARGET "${path_or_tgt}")
+        # Check if this is a target created by add_jar
+        get_target_property(jarpath "${path_or_tgt}" JAR_FILE)
+        set("${outvar_path}" "${jarpath}")
+        if (NOT jarpath) # Some other target that we do not know how to use as a JAR
+            message(SEND_ERROR "target ${path_or_tgt} is not a jar")
+        endif ()
+    else () # Interpreted as the path to an external JAR
+        set("${outvar_path}" "${path_or_tgt}")
+    endif ()
+    return(PROPAGATE "${outvar_path}")
+endfunction()
+
+# Helper that processes a list of add_jar-created targets or paths to external
+# JAR files and:
+# - appends each item (target name or JAR path) to the list in outvar_depsraw.
+# - appends the resolved JAR path to the list in outvar_depsresolved.
+# If any item cannot be resolved, because it is a target name that was not
+# created by add_jar, a SEND_ERROR message is raised.
+function(__java_build_deplists outvar_depsraw outvar_depsresolved jars_or_targets_lst)
+    foreach(item IN LISTS "${jars_or_targets_lst}")
+        __java_resolve_jar(res_path "${item}")
+        if (res_path) # We would get a falsy value in the error case
+            list(APPEND "${outvar_depsraw}" "${item}") # Keep the original name (possibly a target) here
+            list(APPEND "${outvar_depsresolved}" "${res_path}")
+        endif ()
+    endforeach()
+    return(PROPAGATE "${outvar_depsraw}" "${outvar_depsresolved}")
+endfunction()
+
 function(add_jar _TARGET_NAME)
 
     set(options)  # currently there are no zero value args (aka: options)
     set(oneValueArgs "ENTRY_POINT;MANIFEST;OUTPUT_DIR;;OUTPUT_NAME;VERSION" )
-    set(multiValueArgs "GENERATE_NATIVE_HEADERS;INCLUDE_JARS;RESOURCES;SOURCES" )
+    set(multiValueArgs "GENERATE_NATIVE_HEADERS;INCLUDE_JARS;INCLUDE_MODULES;RESOURCES;SOURCES" )
 
     cmake_parse_arguments(PARSE_ARGV 1 _add_jar
                     "${options}"
@@ -803,6 +845,7 @@
     set(_JAVA_COMPILE_FILELISTS)
     set(_JAVA_DEPENDS)
     set(_JAVA_COMPILE_DEPENDS)
+    set(_JAVA_COMPILE_MODDEPENDS)
     set(_JAVA_RESOURCE_FILES)
     set(_JAVA_RESOURCE_FILES_RELATIVE)
     foreach(_JAVA_SOURCE_FILE IN LISTS _JAVA_SOURCE_FILES)
@@ -838,7 +881,8 @@
             # Ignored for backward compatibility
 
         elseif (_JAVA_EXT STREQUAL "")
-            list(APPEND CMAKE_JAVA_INCLUDE_PATH ${JAVA_JAR_TARGET_${_JAVA_SOURCE_FILE}} ${JAVA_JAR_TARGET_${_JAVA_SOURCE_FILE}_CLASSPATH})
+            # XXX: this was not being used after setting!
+            # list(APPEND CMAKE_JAVA_INCLUDE_PATH ${JAVA_JAR_TARGET_${_JAVA_SOURCE_FILE}} ${JAVA_JAR_TARGET_${_JAVA_SOURCE_FILE}_CLASSPATH})
             list(APPEND _JAVA_DEPENDS ${JAVA_JAR_TARGET_${_JAVA_SOURCE_FILE}})
 
         else ()
@@ -857,24 +901,21 @@
                                         _JAVA_RESOURCE_FILES_RELATIVE)
     endif()
 
-    foreach(_JAVA_INCLUDE_JAR IN LISTS _add_jar_INCLUDE_JARS)
-        if (TARGET ${_JAVA_INCLUDE_JAR})
-            get_target_property(_JAVA_JAR_PATH ${_JAVA_INCLUDE_JAR} JAR_FILE)
-            if (_JAVA_JAR_PATH)
-                string(APPEND CMAKE_JAVA_INCLUDE_PATH_FINAL "${_UseJava_PATH_SEP}${_JAVA_JAR_PATH}")
-                list(APPEND CMAKE_JAVA_INCLUDE_PATH ${_JAVA_JAR_PATH})
-                list(APPEND _JAVA_DEPENDS ${_JAVA_INCLUDE_JAR})
-                list(APPEND _JAVA_COMPILE_DEPENDS ${_JAVA_JAR_PATH})
-            else ()
-                message(SEND_ERROR "add_jar: INCLUDE_JARS target ${_JAVA_INCLUDE_JAR} is not a jar")
-            endif ()
-        else ()
-            string(APPEND CMAKE_JAVA_INCLUDE_PATH_FINAL "${_UseJava_PATH_SEP}${_JAVA_INCLUDE_JAR}")
-            list(APPEND CMAKE_JAVA_INCLUDE_PATH "${_JAVA_INCLUDE_JAR}")
-            list(APPEND _JAVA_DEPENDS "${_JAVA_INCLUDE_JAR}")
-            list(APPEND _JAVA_COMPILE_DEPENDS "${_JAVA_INCLUDE_JAR}")
-        endif ()
-    endforeach()
+    # Build dependency lists and arguments for JARs in the classpath
+    __java_build_deplists(_JAVA_DEPENDS _JAVA_COMPILE_DEPENDS _add_jar_INCLUDE_JARS)
+    foreach (resolved_cp_item IN LISTS _JAVA_COMPILE_DEPENDS)
+        string(APPEND CMAKE_JAVA_INCLUDE_PATH_FINAL "${_UseJava_PATH_SEP}${resolved_cp_item}")
+    endforeach ()
+    # Build dependency lists and arguments for JARs in the modulepath
+    set(javac_mp_args)
+    if (_add_jar_INCLUDE_MODULES)
+        if (Java_VERSION VERSION_LESS 9)
+            message(SEND_ERROR "INCLUDE_MODULES requires Java 9+")
+        endif()
+        __java_build_deplists(_JAVA_DEPENDS _JAVA_COMPILE_MODDEPENDS _add_jar_INCLUDE_MODULES)
+        list(JOIN _JAVA_COMPILE_MODDEPENDS "${_UseJava_PATH_SEP}" javac_mp_args)
+        set(javac_mp_args "--module-path [[${javac_mp_args}]]")
+    endif()
 
     if (_JAVA_COMPILE_FILES OR _JAVA_COMPILE_FILELISTS)
         set (_JAVA_SOURCES_FILELISTS)
@@ -899,33 +940,41 @@
 
         cmake_language(GET_MESSAGE_LOG_LEVEL _LOG_LEVEL)
         # Compile the java files and create a list of class files
-        add_custom_command(
-            # NOTE: this command generates an artificial dependency file
-            OUTPUT ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_compiled_${_TARGET_NAME}
+        # NOTE: this command generates an artificial dependency file
+        set(stamp_file "${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_compiled_${_TARGET_NAME}")
+        add_custom_command(OUTPUT "${stamp_file}"
             COMMAND ${CMAKE_COMMAND}
                 -DCMAKE_JAVA_CLASS_OUTPUT_PATH=${CMAKE_JAVA_CLASS_OUTPUT_PATH}
                 -DCMAKE_JAR_CLASSES_PREFIX=${CMAKE_JAR_CLASSES_PREFIX}
                 -P ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/UseJava/ClearClassFiles.cmake
                 --log-level ${_LOG_LEVEL}
-            COMMAND ${Java_JAVAC_EXECUTABLE}
-                ${CMAKE_JAVA_COMPILE_FLAGS}
-                -classpath "${CMAKE_JAVA_INCLUDE_PATH_FINAL}"
-                -d ${CMAKE_JAVA_CLASS_OUTPUT_PATH}
-                ${_GENERATE_NATIVE_HEADERS}
-                ${_JAVA_SOURCES_FILELISTS}
-            COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_compiled_${_TARGET_NAME}
-            DEPENDS ${_JAVA_COMPILE_FILES} ${_JAVA_COMPILE_FILELISTS} ${_JAVA_COMPILE_DEPENDS} ${_JAVA_SOURCES_FILE}
+            DEPENDS ${_JAVA_COMPILE_FILES} ${_JAVA_COMPILE_FILELISTS} ${_JAVA_COMPILE_DEPENDS} ${_JAVA_COMPILE_MODDEPENDS} ${_JAVA_SOURCES_FILE}
             WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
             COMMENT "Building Java objects for ${_TARGET_NAME}.jar"
             VERBATIM
         )
+        cmake_language(EVAL CODE "
+            add_custom_command(OUTPUT [[${stamp_file}]]
+                APPEND COMMAND [[${Java_JAVAC_EXECUTABLE}]]
+                    \${CMAKE_JAVA_COMPILE_FLAGS}
+                    -classpath [[${CMAKE_JAVA_INCLUDE_PATH_FINAL}]]
+                    ${javac_mp_args}
+                    -d [[${CMAKE_JAVA_CLASS_OUTPUT_PATH}]]
+                    \${_GENERATE_NATIVE_HEADERS}
+                    \${_JAVA_SOURCES_FILELISTS}
+            )
+        ")
+        add_custom_command(OUTPUT "${stamp_file}"
+            APPEND COMMAND ${CMAKE_COMMAND} -E touch "${stamp_file}"
+        )
+
         add_custom_command(
             OUTPUT ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_class_filelist
             COMMAND ${CMAKE_COMMAND}
                 -DCMAKE_JAVA_CLASS_OUTPUT_PATH=${CMAKE_JAVA_CLASS_OUTPUT_PATH}
                 -DCMAKE_JAR_CLASSES_PREFIX=${CMAKE_JAR_CLASSES_PREFIX}
                 -P ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/UseJava/ClassFilelist.cmake
-            DEPENDS ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_compiled_${_TARGET_NAME}
+            DEPENDS "${stamp_file}"
             WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
             VERBATIM
         )
@@ -1725,3 +1774,5 @@
             DESTINATION ${_install_jar_exports_DESTINATION}
             ${_COMPONENT})
 endfunction()
+
+endblock()
diff --git a/Packaging/QtSDK/qt.tools.cmake.xx.qs.in b/Packaging/QtSDK/qt.tools.cmake.xx.qs.in
index b449581..42e49af 100644
--- a/Packaging/QtSDK/qt.tools.cmake.xx.qs.in
+++ b/Packaging/QtSDK/qt.tools.cmake.xx.qs.in
@@ -16,7 +16,7 @@
 Component.prototype.reactOnTargetDirChange = function(key, value)
 {
     if (key == "TargetDir") {
-        var path = value + "/%CMAKE_BIN_DIR%";
+        var path = value + "/%CMake_INSTALL_BIN_DIR%";
         installer.setValue("CMAKE%CMake_VERSION_MAJOR%%CMake_VERSION_MINOR%_BIN_DIR", path.replace(/\\/g, "/"));
     }
 }
diff --git a/Source/CMakeInstallDestinations.cmake b/Source/CMakeInstallDestinations.cmake
index e82bec3..c97e1f8 100644
--- a/Source/CMakeInstallDestinations.cmake
+++ b/Source/CMakeInstallDestinations.cmake
@@ -35,25 +35,36 @@
   )
 mark_as_advanced(CMake_INSTALL_INFIX)
 
+if(APPLE AND BUILD_QtDialog)
+  set(CMake_INSTALL_APP_DIR "CMake.app/Contents")
+  set(CMake_INSTALL_APP_DIR_SLASH "${CMake_INSTALL_APP_DIR}/")
+else()
+  set(CMake_INSTALL_APP_DIR ".")
+  set(CMake_INSTALL_APP_DIR_SLASH "")
+endif()
+
 foreach(v
-    CMAKE_BIN_DIR
-    CMAKE_DATA_DIR
-    CMAKE_DOC_DIR
-    CMAKE_INFO_DIR
-    CMAKE_MAN_DIR
-    CMAKE_XDGDATA_DIR
+    BIN
+    DATA
+    DOC
+    INFO
+    MAN
+    XDGDATA
     )
   # Populate the cache with empty values so we know when the user sets them.
-  set(${v} "" CACHE STRING "")
-  set_property(CACHE ${v} PROPERTY HELPSTRING
-    "Location under install prefix for ${${v}_DESC} (default \"${${v}_DEFAULT}\")"
+  set(CMAKE_${v}_DIR "" CACHE STRING "")
+  set_property(CACHE CMAKE_${v}_DIR PROPERTY HELPSTRING
+    "Location under install prefix for ${CMAKE_${v}_DIR_DESC} (default \"${CMAKE_${v}_DIR_DEFAULT}\")"
     )
-  set_property(CACHE ${v} PROPERTY ADVANCED 1)
+  set_property(CACHE CMAKE_${v}_DIR PROPERTY ADVANCED 1)
 
   # Use the default when the user did not set this variable.
-  if(NOT ${v})
-    set(${v} "${CMake_INSTALL_INFIX}${${v}_DEFAULT}")
+  if(NOT CMAKE_${v}_DIR)
+    set(CMAKE_${v}_DIR "${CMake_INSTALL_INFIX}${CMAKE_${v}_DIR_DEFAULT}")
   endif()
   # Remove leading slash to treat as relative to install prefix.
-  string(REGEX REPLACE "^/" "" ${v} "${${v}}")
+  string(REGEX REPLACE "^/" "" CMAKE_${v}_DIR "${CMAKE_${v}_DIR}")
+
+  # Install under a base path within the prefix.
+  set(CMake_INSTALL_${v}_DIR "${CMake_INSTALL_APP_DIR_SLASH}${CMAKE_${v}_DIR}")
 endforeach()
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index 44f87db..1aacabc 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -135,6 +135,8 @@
   cmCMakePresetsGraphReadJSONPackagePresets.cxx
   cmCMakePresetsGraphReadJSONTestPresets.cxx
   cmCMakePresetsGraphReadJSONWorkflowPresets.cxx
+  cmCMakeString.hxx
+  cmCMakeString.cxx
   cmCommandLineArgument.h
   cmCommonTargetGenerator.cxx
   cmCommonTargetGenerator.h
@@ -163,6 +165,8 @@
   cmCustomCommandTypes.h
   cmCxxModuleMapper.cxx
   cmCxxModuleMapper.h
+  cmCxxModuleMetadata.cxx
+  cmCxxModuleMetadata.h
   cmCxxModuleUsageEffects.cxx
   cmCxxModuleUsageEffects.h
   cmDefinitions.cxx
@@ -701,6 +705,8 @@
   cmRemoveDefinitionsCommand.h
   cmReturnCommand.cxx
   cmReturnCommand.h
+  cmSbomObject.h
+  cmSbomSerializer.h
   cmSearchPath.cxx
   cmSearchPath.h
   cmSeparateArgumentsCommand.cxx
@@ -721,9 +727,10 @@
   cmSiteNameCommand.h
   cmSourceGroupCommand.cxx
   cmSourceGroupCommand.h
-  cmSPDXSerializer.cxx
-  cmSPDXSerializer.h
-  cmSPDXTypes.def
+  cmSpdx.cxx
+  cmSpdx.h
+  cmSpdxSerializer.cxx
+  cmSpdxSerializer.h
   cmString.cxx
   cmString.hxx
   cmStringReplaceHelper.cxx
@@ -1412,7 +1419,7 @@
 
 foreach(_tool IN LISTS _tools)
   CMake_OPTIONAL_COMPONENT(${_tool})
-  install(TARGETS ${_tool} DESTINATION ${CMAKE_BIN_DIR} ${COMPONENT})
+  install(TARGETS ${_tool} DESTINATION ${CMake_INSTALL_BIN_DIR} ${COMPONENT})
 endforeach()
 
 # Unset temporary variables
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 09d2a91..b157474 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,7 +1,7 @@
 # CMake version number components.
 set(CMake_VERSION_MAJOR 4)
 set(CMake_VERSION_MINOR 2)
-set(CMake_VERSION_PATCH 0)
+set(CMake_VERSION_PATCH 20251122)
 #set(CMake_VERSION_RC 0)
 set(CMake_VERSION_IS_DIRTY 0)
 
diff --git a/Source/CPack/cmCPackArchiveGenerator.cxx b/Source/CPack/cmCPackArchiveGenerator.cxx
index ac09918..994f2b9 100644
--- a/Source/CPack/cmCPackArchiveGenerator.cxx
+++ b/Source/CPack/cmCPackArchiveGenerator.cxx
@@ -233,7 +233,7 @@
   cmValue newExtensionValue = this->GetOption("CPACK_ARCHIVE_FILE_EXTENSION");
   if (!newExtensionValue.IsEmpty()) {
     std::string newExtension = *newExtensionValue;
-    if (!cmHasLiteralPrefix(newExtension, ".")) {
+    if (!cmHasPrefix(newExtension, '.')) {
       newExtension = cmStrCat('.', newExtension);
     }
     cmCPackLogger(cmCPackLog::LOG_DEBUG,
@@ -318,6 +318,9 @@
   }                                                                           \
   cmArchiveWrite archive(gf, this->Compress, this->ArchiveFormat, 0,          \
                          this->GetThreadCount());                             \
+  if (this->UID >= 0 && this->GID >= 0) {                                     \
+    archive.SetUIDAndGID(this->UID, this->GID);                               \
+  }                                                                           \
   do {                                                                        \
     if (!archive.Open()) {                                                    \
       cmCPackLogger(cmCPackLog::LOG_ERROR,                                    \
@@ -436,6 +439,19 @@
   cmCPackLogger(cmCPackLog::LOG_DEBUG,
                 "Toplevel: " << this->toplevel << std::endl);
 
+  if (cmValue UIDoption = this->GetOptionIfSet("CPACK_ARCHIVE_UID")) {
+    long u;
+    if (cmStrToLong(*UIDoption, &u)) {
+      this->UID = static_cast<int>(u);
+    }
+  }
+  if (cmValue GIDoption = this->GetOptionIfSet("CPACK_ARCHIVE_GID")) {
+    long g;
+    if (cmStrToLong(*GIDoption, &g)) {
+      this->GID = static_cast<int>(g);
+    }
+  }
+
   if (this->WantsComponentInstallation()) {
     // CASE 1 : COMPONENT ALL-IN-ONE package
     // If ALL COMPONENTS in ONE package has been requested
diff --git a/Source/CPack/cmCPackArchiveGenerator.h b/Source/CPack/cmCPackArchiveGenerator.h
index fb56842..f2c4163 100644
--- a/Source/CPack/cmCPackArchiveGenerator.h
+++ b/Source/CPack/cmCPackArchiveGenerator.h
@@ -97,4 +97,6 @@
   cmArchiveWrite::Compress Compress;
   std::string ArchiveFormat;
   std::string OutputExtension;
+  int UID = 0;
+  int GID = 0;
 };
diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx
index efe15c2..f9fed6d 100644
--- a/Source/CPack/cmCPackGenerator.cxx
+++ b/Source/CPack/cmCPackGenerator.cxx
@@ -760,9 +760,7 @@
                   "-   Install component: " << component << std::endl);
   }
 
-  cmake cm(cmake::RoleScript, cmState::CPack);
-  cm.SetHomeDirectory("");
-  cm.SetHomeOutputDirectory("");
+  cmake cm(cmState::Role::CPack);
   cm.GetCurrentSnapshot().SetDefaultDefinitions();
   cm.AddCMakePaths();
   cm.SetProgressCallback([this](std::string const& msg, float prog) {
@@ -836,7 +834,7 @@
     // Make sure that DESTDIR + CPACK_INSTALL_PREFIX directory
     // exists:
     //
-    if (cmHasLiteralPrefix(dir, "/")) {
+    if (cmHasPrefix(dir, '/')) {
       dir = tempInstallDirectory + dir;
     } else {
       dir = tempInstallDirectory + "/" + dir;
diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx
index d3ac1bf..3a79367 100644
--- a/Source/CPack/cpack.cxx
+++ b/Source/CPack/cpack.cxx
@@ -225,9 +225,7 @@
                      } },
   };
 
-  cmake cminst(cmake::RoleScript, cmState::CPack);
-  cminst.SetHomeDirectory("");
-  cminst.SetHomeOutputDirectory("");
+  cmake cminst(cmState::Role::CPack);
   cminst.SetProgressCallback(cpackProgressCallback);
   cminst.GetCurrentSnapshot().SetDefaultDefinitions();
   cmGlobalGenerator cmgg(&cminst);
diff --git a/Source/CTest/cmCTestBuildAndTest.cxx b/Source/CTest/cmCTestBuildAndTest.cxx
index def87dc..378f7d2 100644
--- a/Source/CTest/cmCTestBuildAndTest.cxx
+++ b/Source/CTest/cmCTestBuildAndTest.cxx
@@ -179,9 +179,7 @@
     return 1;
   }
 
-  cmake cm(cmake::RoleProject, cmState::Project);
-  cm.SetHomeDirectory("");
-  cm.SetHomeOutputDirectory("");
+  cmake cm(cmState::Role::Project);
   cmCTestBuildAndTestCaptureRAII captureRAII(cm);
   static_cast<void>(captureRAII);
 
diff --git a/Source/CTest/cmCTestLaunch.cxx b/Source/CTest/cmCTestLaunch.cxx
index 1e65450..4c0671a 100644
--- a/Source/CTest/cmCTestLaunch.cxx
+++ b/Source/CTest/cmCTestLaunch.cxx
@@ -408,9 +408,7 @@
 
 void cmCTestLaunch::LoadConfig()
 {
-  cmake cm(cmake::RoleScript, cmState::CTest);
-  cm.SetHomeDirectory("");
-  cm.SetHomeOutputDirectory("");
+  cmake cm(cmState::Role::CTest);
   cm.GetCurrentSnapshot().SetDefaultDefinitions();
   cmGlobalGenerator gg(&cm);
   cmMakefile mf(&gg, cm.GetCurrentSnapshot());
diff --git a/Source/CTest/cmCTestScriptHandler.cxx b/Source/CTest/cmCTestScriptHandler.cxx
index bed2bb7..a3f7365 100644
--- a/Source/CTest/cmCTestScriptHandler.cxx
+++ b/Source/CTest/cmCTestScriptHandler.cxx
@@ -172,13 +172,9 @@
 void cmCTestScriptHandler::CreateCMake()
 {
   // create a cmake instance to read the configuration script
-  this->CMake = cm::make_unique<cmake>(cmake::RoleScript, cmState::CTest);
-  this->CMake->SetHomeDirectory("");
-  this->CMake->SetHomeOutputDirectory("");
+  this->CMake = cm::make_unique<cmake>(cmState::Role::CTest);
   this->CMake->GetCurrentSnapshot().SetDefaultDefinitions();
   this->CMake->AddCMakePaths();
-  this->CMake->SetWorkingMode(cmake::SCRIPT_MODE,
-                              cmake::CommandFailureAction::EXIT_CODE);
   this->GlobalGenerator =
     cm::make_unique<cmGlobalGenerator>(this->CMake.get());
 
diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx
index d0045d1..bd88d63 100644
--- a/Source/CTest/cmCTestTestHandler.cxx
+++ b/Source/CTest/cmCTestTestHandler.cxx
@@ -1754,9 +1754,7 @@
   }
   cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                      "Constructing a list of tests" << std::endl, this->Quiet);
-  cmake cm(cmake::RoleScript, cmState::CTest);
-  cm.SetHomeDirectory("");
-  cm.SetHomeOutputDirectory("");
+  cmake cm(cmState::Role::CTest);
   cm.GetCurrentSnapshot().SetDefaultDefinitions();
   cmGlobalGenerator gg(&cm);
   cmMakefile mf(&gg, cm.GetCurrentSnapshot());
@@ -2202,7 +2200,7 @@
 
             // Ensure we have complete triples otherwise the data is corrupt.
             if (triples.size() % 3 == 0) {
-              cmState state(cmState::Unknown);
+              cmState state(cmState::Role::Internal);
               rt.Backtrace = cmListFileBacktrace();
 
               // the first entry represents the top of the trace so we need to
diff --git a/Source/CTest/cmParseGTMCoverage.cxx b/Source/CTest/cmParseGTMCoverage.cxx
index c7b2092..c11be30 100644
--- a/Source/CTest/cmParseGTMCoverage.cxx
+++ b/Source/CTest/cmParseGTMCoverage.cxx
@@ -85,7 +85,7 @@
     }
     // Find the full path to the file
     bool found = this->FindMumpsFile(routine, filepath);
-    if (!found && cmHasLiteralSuffix(routine, "%")) {
+    if (!found && cmHasSuffix(routine, '%')) {
       routine.erase(0, 1);
       found = this->FindMumpsFile(routine, filepath);
     }
diff --git a/Source/CursesDialog/CMakeLists.txt b/Source/CursesDialog/CMakeLists.txt
index bd2aee3..b53baf6 100644
--- a/Source/CursesDialog/CMakeLists.txt
+++ b/Source/CursesDialog/CMakeLists.txt
@@ -60,4 +60,4 @@
 endif()
 
 CMake_OPTIONAL_COMPONENT(ccmake)
-install(TARGETS ccmake DESTINATION ${CMAKE_BIN_DIR} ${COMPONENT})
+install(TARGETS ccmake DESTINATION ${CMake_INSTALL_BIN_DIR} ${COMPONENT})
diff --git a/Source/CursesDialog/ccmake.cxx b/Source/CursesDialog/ccmake.cxx
index 6de688e..a88e3fb 100644
--- a/Source/CursesDialog/ccmake.cxx
+++ b/Source/CursesDialog/ccmake.cxx
@@ -75,9 +75,7 @@
   cmDocumentation doc;
   doc.addCMakeStandardDocSections();
   if (doc.CheckOptions(argc, argv)) {
-    cmake hcm(cmake::RoleInternal, cmState::Help);
-    hcm.SetHomeDirectory("");
-    hcm.SetHomeOutputDirectory("");
+    cmake hcm(cmState::Role::Help);
     hcm.AddCMakePaths();
     auto generators = hcm.GetGeneratorsDocumentation();
     doc.SetName("ccmake");
diff --git a/Source/CursesDialog/cmCursesMainForm.cxx b/Source/CursesDialog/cmCursesMainForm.cxx
index 8ca456d..6678550 100644
--- a/Source/CursesDialog/cmCursesMainForm.cxx
+++ b/Source/CursesDialog/cmCursesMainForm.cxx
@@ -39,8 +39,7 @@
     "Welcome to ccmake, curses based user interface for CMake.");
   this->HelpMessage.emplace_back();
   this->HelpMessage.emplace_back(s_ConstHelpMessage);
-  this->CMakeInstance =
-    cm::make_unique<cmake>(cmake::RoleProject, cmState::Project);
+  this->CMakeInstance = cm::make_unique<cmake>(cmState::Role::Project);
   this->CMakeInstance->SetCMakeEditCommand(
     cmSystemTools::GetCMakeCursesCommand());
 
diff --git a/Source/Modules/CMakeBuildUtilities.cmake b/Source/Modules/CMakeBuildUtilities.cmake
index da67819..555d836 100644
--- a/Source/Modules/CMakeBuildUtilities.cmake
+++ b/Source/Modules/CMakeBuildUtilities.cmake
@@ -22,7 +22,7 @@
 set(KWSYS_USE_Process 1)
 set(KWSYS_USE_CommandLineArguments 1)
 set(KWSYS_HEADER_ROOT ${CMake_BINARY_DIR}/Source)
-set(KWSYS_INSTALL_DOC_DIR "${CMAKE_DOC_DIR}")
+set(KWSYS_INSTALL_DOC_DIR "${CMake_INSTALL_DOC_DIR}")
 if(CMake_NO_CXX_STANDARD)
   set(KWSYS_CXX_STANDARD "")
 endif()
@@ -297,6 +297,7 @@
   set(ENABLE_TEST OFF)
   set(ENABLE_COVERAGE OFF)
   set(ENABLE_INSTALL OFF)
+  set(MSVC_USE_STATIC_CRT OFF)
   set(POSIX_REGEX_LIB "" CACHE INTERNAL "libarchive: No POSIX regular expression support")
   set(ENABLE_SAFESEH "" CACHE INTERNAL "libarchive: No /SAFESEH linker flag")
   set(WINDOWS_VERSION "WIN7" CACHE INTERNAL "libarchive: Set Windows version to use (Windows only)")
diff --git a/Source/QtDialog/CMakeLists.txt b/Source/QtDialog/CMakeLists.txt
index 7f9e7f0..b6eb31a 100644
--- a/Source/QtDialog/CMakeLists.txt
+++ b/Source/QtDialog/CMakeLists.txt
@@ -1,6 +1,10 @@
 # Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
 # file LICENSE.rst or https://cmake.org/licensing for details.
 
+if(CMake_GUI_OSX_DEPLOYMENT_TARGET)
+  set(CMAKE_OSX_DEPLOYMENT_TARGET "${CMake_GUI_OSX_DEPLOYMENT_TARGET}")
+endif()
+
 project(QtDialog)
 CMake_OPTIONAL_COMPONENT(cmake-gui)
 set(QT_COMPONENTS
@@ -69,7 +73,7 @@
 endif()
 
 # We need to install platform plugin and add qt.conf for Qt5 on Mac and Windows.
-if(CMake_INSTALL_DEPENDENCIES AND (APPLE OR WIN32))
+if(CMake_INSTALL_DEPENDENCIES AND (APPLE OR WIN32) AND NOT COMMAND qt_generate_deploy_app_script)
   function(_qt_get_plugin_name_with_version target out_var)
       string(REGEX REPLACE "^Qt::(.+)" "Qt${CMake_QT_MAJOR_VERSION}::\\1"
              qt_plugin_with_version "${target}")
@@ -97,7 +101,7 @@
       elseif(WIN32)
         set(_qt_plugin_dir "plugins")
       endif()
-      set(_qt_plugin_dest "${_qt_plugin_dir}/${_qt_plugin_type}")
+      set(_qt_plugin_dest "${CMake_INSTALL_APP_DIR_SLASH}${_qt_plugin_dir}/${_qt_plugin_type}")
       install(FILES "${_qt_plugin_path}"
         DESTINATION "${_qt_plugin_dest}"
         ${COMPONENT})
@@ -105,45 +109,27 @@
         "${${_qt_plugins_var}};\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${_qt_plugin_dest}/${_qt_plugin_file}")
     endif()
   endmacro()
-  macro(install_qt_plugins _comps _plugins_var)
-    foreach(_qt_comp IN LISTS ${_comps})
-      if(CMake_QT_MAJOR_VERSION VERSION_LESS 6)
-        set(_qt_module_plugins ${Qt${CMake_QT_MAJOR_VERSION}${_qt_comp}_PLUGINS})
-      else()
-        get_target_property(_qt_module_plugins Qt${CMake_QT_MAJOR_VERSION}::${_qt_comp} QT_PLUGINS)
-      endif()
-      foreach(_qt_plugin IN LISTS _qt_module_plugins)
-        if(CMake_QT_MAJOR_VERSION VERSION_GREATER_EQUAL 6)
-          # Qt6 provides the plugins as individual packages that need to be found.
-          find_package(Qt${CMake_QT_MAJOR_VERSION}${_qt_plugin} QUIET
-            PATHS ${Qt${CMake_QT_MAJOR_VERSION}${_qt_comp}_DIR})
-        endif()
-        install_qt_plugin("${_qt_plugin}" "${_plugins_var}")
-      endforeach()
-    endforeach()
-  endmacro()
   if(APPLE)
-    if(CMake_QT_MAJOR_VERSION VERSION_EQUAL 5)
-      install_qt_plugin("Qt5::QCocoaIntegrationPlugin" QT_PLUGINS)
-      if(TARGET Qt5::QMacStylePlugin)
-        install_qt_plugin("Qt5::QMacStylePlugin" QT_PLUGINS)
-      endif()
-    else()
-      # FIXME: Minimize plugins for Qt6.
-      install_qt_plugins(QT_COMPONENTS QT_PLUGINS)
+    if(CMake_QT_MAJOR_VERSION VERSION_GREATER_EQUAL 6)
+      # Qt6 provides the plugins as individual packages that need to be found.
+      find_package(Qt${CMake_QT_MAJOR_VERSION}QCocoaIntegrationPlugin QUIET PATHS ${Qt${CMake_QT_MAJOR_VERSION}Gui_DIR})
+      find_package(Qt${CMake_QT_MAJOR_VERSION}QMacStylePlugin QUIET PATHS ${Qt${CMake_QT_MAJOR_VERSION}Widgets_DIR})
+    endif()
+    install_qt_plugin("Qt${CMake_QT_MAJOR_VERSION}::QCocoaIntegrationPlugin" QT_PLUGINS)
+    if(TARGET Qt${CMake_QT_MAJOR_VERSION}::QMacStylePlugin)
+      install_qt_plugin("Qt${CMake_QT_MAJOR_VERSION}::QMacStylePlugin" QT_PLUGINS)
     endif()
     file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
       "[Paths]\nPlugins = ${_qt_plugin_dir}\n")
     install(FILES "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
-      DESTINATION "${CMAKE_INSTALL_PREFIX}/Resources"
+      DESTINATION "${CMake_INSTALL_APP_DIR_SLASH}Resources"
       ${COMPONENT})
   elseif(WIN32 AND NOT CMake_QT_STATIC_QWindowsIntegrationPlugin_LIBRARIES)
-    if(CMake_QT_MAJOR_VERSION VERSION_EQUAL 5)
-      install_qt_plugin("Qt5::QWindowsIntegrationPlugin" QT_PLUGINS)
-    else()
-      # FIXME: Minimize plugins for Qt6.
-      install_qt_plugins(QT_COMPONENTS QT_PLUGINS)
+    if(CMake_QT_MAJOR_VERSION VERSION_GREATER_EQUAL 6)
+      # Qt6 provides the plugins as individual packages that need to be found.
+      find_package(Qt${CMake_QT_MAJOR_VERSION}QWindowsIntegrationPlugin QUIET PATHS ${Qt${CMake_QT_MAJOR_VERSION}Gui_DIR})
     endif()
+    install_qt_plugin("Qt${CMake_QT_MAJOR_VERSION}::QWindowsIntegrationPlugin" QT_PLUGINS)
     file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
       "[Paths]\nPlugins = ../${_qt_plugin_dir}\n")
     install(FILES "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
@@ -152,12 +138,6 @@
   endif()
 endif()
 
-get_property(_Qt_Core_LOCATION TARGET Qt${CMake_QT_MAJOR_VERSION}::Core PROPERTY LOCATION)
-get_filename_component(Qt_BIN_DIR "${_Qt_Core_LOCATION}" PATH)
-if(APPLE)
-  get_filename_component(Qt_BIN_DIR "${Qt_BIN_DIR}" PATH)
-endif()
-
 set(CMAKE_INCLUDE_CURRENT_DIR ON)
 
 add_library(
@@ -250,7 +230,7 @@
 
 if(USE_LGPL)
   install(FILES ${CMake_SOURCE_DIR}/Licenses/LGPLv${USE_LGPL}.txt
-    DESTINATION ${CMAKE_DATA_DIR}/Licenses
+    DESTINATION ${CMake_INSTALL_DATA_DIR}/Licenses
     ${COMPONENT})
   set_property(SOURCE CMakeSetupDialog.cxx
     PROPERTY COMPILE_DEFINITIONS USE_LGPL="${USE_LGPL}")
@@ -311,8 +291,8 @@
   set_target_properties(cmake-gui PROPERTIES
     OUTPUT_NAME CMake
     MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/Info.plist.in"
-    MACOSX_BUNDLE_SHORT_VERSION_STRING "${CMAKE_BUNDLE_VERSION}"
-    # TBD: MACOSX_BUNDLE_BUNDLE_VERSION "${CMAKE_BUNDLE_VERSION}"
+    MACOSX_BUNDLE_SHORT_VERSION_STRING "${CMake_VERSION_MAJOR}.${CMake_VERSION_MINOR}.${CMake_VERSION_PATCH}"
+    # TBD: MACOSX_BUNDLE_BUNDLE_VERSION "${CMake_VERSION_MAJOR}.${CMake_VERSION_MINOR}.${CMake_VERSION_PATCH}"
     MACOSX_BUNDLE_COPYRIGHT "${CMake_COPYRIGHT_LINE}"
     MACOSX_BUNDLE_GUI_IDENTIFIER "org.cmake.cmake"
     )
@@ -326,14 +306,14 @@
 endif()
 
 install(TARGETS cmake-gui
-  RUNTIME DESTINATION bin ${COMPONENT}
-  BUNDLE DESTINATION "${CMAKE_BUNDLE_LOCATION}" ${COMPONENT})
+  RUNTIME DESTINATION ${CMake_INSTALL_BIN_DIR} ${COMPONENT}
+  BUNDLE  DESTINATION .                        ${COMPONENT})
 
 if(UNIX AND NOT APPLE)
   foreach(size IN ITEMS 32 128)
     install(
       FILES       "${CMAKE_CURRENT_SOURCE_DIR}/CMakeSetup${size}.png"
-      DESTINATION "${CMAKE_XDGDATA_DIR}/icons/hicolor/${size}x${size}/apps"
+      DESTINATION "${CMake_INSTALL_XDGDATA_DIR}/icons/hicolor/${size}x${size}/apps"
       ${COMPONENT}
       RENAME      "CMakeSetup.png")
   endforeach()
@@ -341,32 +321,48 @@
   # install a desktop file so CMake appears in the application start menu
   # with an icon
   install(FILES cmake-gui.desktop
-    DESTINATION "${CMAKE_XDGDATA_DIR}/applications"
+    DESTINATION "${CMake_INSTALL_XDGDATA_DIR}/applications"
     ${COMPONENT})
   install(FILES cmakecache.xml
-    DESTINATION "${CMAKE_XDGDATA_DIR}/mime/packages"
+    DESTINATION "${CMake_INSTALL_XDGDATA_DIR}/mime/packages"
     ${COMPONENT})
 endif()
 
 if(APPLE)
   install(CODE "
     execute_process(COMMAND ln -s \"../MacOS/CMake\" cmake-gui
-        WORKING_DIRECTORY \$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/bin)
+        WORKING_DIRECTORY \$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${CMake_INSTALL_BIN_DIR})
   " ${COMPONENT})
 endif()
 
 if(CMake_INSTALL_DEPENDENCIES AND (APPLE OR WIN32))
-  # install rules for including 3rd party libs such as Qt
-  # if a system Qt is used (e.g. installed in /usr/lib/), it will not be included in the installation
-  set(fixup_exe "\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/bin/cmake-gui${CMAKE_EXECUTABLE_SUFFIX}")
-  if(APPLE)
-    set(fixup_exe "\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/MacOS/CMake")
+  if(COMMAND qt_generate_deploy_app_script)
+    # Qt libraries are found via @rpath, so point the runtime path at them.
+    set_property(TARGET cmake-gui PROPERTY INSTALL_RPATH "@executable_path/../Frameworks")
+    qt_generate_deploy_app_script(
+      TARGET cmake-gui
+      OUTPUT_SCRIPT qt_deploy_script
+    )
+    install(SCRIPT "${qt_deploy_script}")
+  else()
+    # install rules for including 3rd party libs such as Qt
+    # if a system Qt is used (e.g. installed in /usr/lib/), it will not be included in the installation
+    set(fixup_exe "\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${CMake_INSTALL_BIN_DIR}/cmake-gui${CMAKE_EXECUTABLE_SUFFIX}")
+    if(APPLE)
+      set(fixup_exe "\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${CMake_INSTALL_APP_DIR_SLASH}MacOS/CMake")
+    endif()
+    get_property(_Qt_Core_LOCATION TARGET Qt${CMake_QT_MAJOR_VERSION}::Core PROPERTY LOCATION)
+    if(APPLE AND _Qt_Core_LOCATION MATCHES [[^(.*)/[^/]*\.framework/]])
+      set(Qt_LIB_DIR "${CMAKE_MATCH_1}")
+    else()
+      get_filename_component(Qt_LIB_DIR "${_Qt_Core_LOCATION}" PATH)
+    endif()
+    install(CODE "
+      include(BundleUtilities)
+      set(BU_CHMOD_BUNDLE_ITEMS ON)
+      fixup_bundle(\"${fixup_exe}\" \"${QT_PLUGINS}\" \"${Qt_LIB_DIR};${QT_LIBRARY_DIR};${QT_BINARY_DIR}\")
+    " ${COMPONENT})
   endif()
-  install(CODE "
-    include(BundleUtilities)
-    set(BU_CHMOD_BUNDLE_ITEMS ON)
-    fixup_bundle(\"${fixup_exe}\" \"${QT_PLUGINS}\" \"${Qt_BIN_DIR};${QT_LIBRARY_DIR};${QT_BINARY_DIR}\")
-  " ${COMPONENT})
 endif()
 
 set(CMAKE_PACKAGE_QTGUI TRUE)
diff --git a/Source/QtDialog/CMakeSetup.cxx b/Source/QtDialog/CMakeSetup.cxx
index cf32461..5188359 100644
--- a/Source/QtDialog/CMakeSetup.cxx
+++ b/Source/QtDialog/CMakeSetup.cxx
@@ -82,9 +82,7 @@
   doc.addCMakeStandardDocSections();
   if (argc2 > 1 && doc.CheckOptions(argc2, argv2)) {
     // Construct and print requested documentation.
-    cmake hcm(cmake::RoleInternal, cmState::Help);
-    hcm.SetHomeDirectory("");
-    hcm.SetHomeOutputDirectory("");
+    cmake hcm(cmState::Role::Help);
     hcm.AddCMakePaths();
 
     auto generators = hcm.GetGeneratorsDocumentation();
@@ -289,7 +287,7 @@
 
 static int cmOSXInstall(std::string dir)
 {
-  if (!cmHasLiteralSuffix(dir, "/")) {
+  if (!cmHasSuffix(dir, '/')) {
     dir += "/";
   }
   return (cmOSXInstall(dir, cmSystemTools::GetCMakeCommand()) &&
diff --git a/Source/QtDialog/QCMake.cxx b/Source/QtDialog/QCMake.cxx
index 62b6eb2..cf031b1 100644
--- a/Source/QtDialog/QCMake.cxx
+++ b/Source/QtDialog/QCMake.cxx
@@ -46,8 +46,7 @@
   cmSystemTools::SetStderrCallback(
     [this](std::string const& msg) { this->stderrCallback(msg); });
 
-  this->CMakeInstance =
-    cm::make_unique<cmake>(cmake::RoleProject, cmState::Project);
+  this->CMakeInstance = cm::make_unique<cmake>(cmState::Role::Project);
   this->CMakeInstance->SetCMakeEditCommand(
     cmSystemTools::GetCMakeGUICommand());
   this->CMakeInstance->SetProgressCallback(
diff --git a/Source/QtDialog/QCMakeCacheView.cxx b/Source/QtDialog/QCMakeCacheView.cxx
index 8d4e295..fa2ad3d 100644
--- a/Source/QtDialog/QCMakeCacheView.cxx
+++ b/Source/QtDialog/QCMakeCacheView.cxx
@@ -241,7 +241,10 @@
 
   bool b = this->blockSignals(true);
 
-  this->clear();
+  // Empty the model. Avoid QStandardItemModel::clear(), because that calls
+  // beginResetModel() internally, and we can't nest such calls.
+  this->removeRows(0, this->rowCount());
+
   this->NewPropertyCount = newProps.size();
 
   if (View == FlatView) {
@@ -343,8 +346,6 @@
 
 void QCMakeCacheModel::setViewType(QCMakeCacheModel::ViewType t)
 {
-  this->beginResetModel();
-
   this->View = t;
 
   QCMakePropertyList props = this->properties();
@@ -360,7 +361,6 @@
   this->setProperties(oldProps);
   this->setProperties(props);
   this->blockSignals(b);
-  this->endResetModel();
 }
 
 void QCMakeCacheModel::setPropertyData(QModelIndex const& idx1,
diff --git a/Source/QtDialog/WarningMessagesDialog.cxx b/Source/QtDialog/WarningMessagesDialog.cxx
index a0c72d4..3728693 100644
--- a/Source/QtDialog/WarningMessagesDialog.cxx
+++ b/Source/QtDialog/WarningMessagesDialog.cxx
@@ -26,7 +26,7 @@
 
 void WarningMessagesDialog::setupSignals()
 {
-#if (QT_VERSION >= QT_VERSION_CHECK(6, 7, 0))
+#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0)
   static auto const checkStateChanged = &QCheckBox::checkStateChanged;
 #else
   static auto const checkStateChanged = &QCheckBox::stateChanged;
@@ -59,7 +59,8 @@
     this->deprecatedWarningsAsErrors->isChecked());
 }
 
-void WarningMessagesDialog::doSuppressDeveloperWarningsChanged(int state)
+void WarningMessagesDialog::doSuppressDeveloperWarningsChanged(
+  CheckState state)
 {
   // no warnings implies no errors either
   if (state) {
@@ -67,7 +68,8 @@
   }
 }
 
-void WarningMessagesDialog::doSuppressDeprecatedWarningsChanged(int state)
+void WarningMessagesDialog::doSuppressDeprecatedWarningsChanged(
+  CheckState state)
 {
   // no warnings implies no errors either
   if (state) {
@@ -75,7 +77,8 @@
   }
 }
 
-void WarningMessagesDialog::doDeveloperWarningsAsErrorsChanged(int state)
+void WarningMessagesDialog::doDeveloperWarningsAsErrorsChanged(
+  CheckState state)
 {
   // warnings as errors implies warnings are not suppressed
   if (state) {
@@ -83,7 +86,8 @@
   }
 }
 
-void WarningMessagesDialog::doDeprecatedWarningsAsErrorsChanged(int state)
+void WarningMessagesDialog::doDeprecatedWarningsAsErrorsChanged(
+  CheckState state)
 {
   // warnings as errors implies warnings are not suppressed
   if (state) {
diff --git a/Source/QtDialog/WarningMessagesDialog.h b/Source/QtDialog/WarningMessagesDialog.h
index 0cde8ff..e5f0660 100644
--- a/Source/QtDialog/WarningMessagesDialog.h
+++ b/Source/QtDialog/WarningMessagesDialog.h
@@ -17,6 +17,12 @@
 {
   Q_OBJECT
 
+#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0)
+  using CheckState = Qt::CheckState;
+#else
+  using CheckState = int;
+#endif
+
 public:
   WarningMessagesDialog(QWidget* prnt, QCMake* instance);
 
@@ -30,23 +36,23 @@
    * Handler for checked state changed event of the suppress developer warnings
    * checkbox.
    */
-  void doSuppressDeveloperWarningsChanged(int state);
+  void doSuppressDeveloperWarningsChanged(CheckState state);
   /**
    * Handler for checked state changed event of the suppress deprecated
    * warnings checkbox.
    */
-  void doSuppressDeprecatedWarningsChanged(int state);
+  void doSuppressDeprecatedWarningsChanged(CheckState state);
 
   /**
    * Handler for checked state changed event of the developer warnings as
    * errors checkbox.
    */
-  void doDeveloperWarningsAsErrorsChanged(int state);
+  void doDeveloperWarningsAsErrorsChanged(CheckState state);
   /**
    * Handler for checked state changed event of the deprecated warnings as
    * errors checkbox.
    */
-  void doDeprecatedWarningsAsErrorsChanged(int state);
+  void doDeprecatedWarningsAsErrorsChanged(CheckState state);
 
 private:
   QCMake* cmakeInstance;
diff --git a/Source/QtIFW/CMake.DeveloperReference.HTML.qs.in b/Source/QtIFW/CMake.DeveloperReference.HTML.qs.in
index 8cc5835..4e59ec5 100644
--- a/Source/QtIFW/CMake.DeveloperReference.HTML.qs.in
+++ b/Source/QtIFW/CMake.DeveloperReference.HTML.qs.in
@@ -11,7 +11,7 @@
     if (installer.value("os") === "win") {
 
         component.addOperation("CreateShortcut",
-                               "@TargetDir@/%CMAKE_DOC_DIR%/developer-reference/html/index.html",
+                               "@TargetDir@/%CMake_INSTALL_DOC_DIR%/developer-reference/html/index.html",
                                "@StartMenuDir@/CMake Developer Reference.lnk");
 
     }
diff --git a/Source/QtIFW/CMake.Dialogs.QtGUI.qs.in b/Source/QtIFW/CMake.Dialogs.QtGUI.qs.in
index 71f395a..b40c21f 100644
--- a/Source/QtIFW/CMake.Dialogs.QtGUI.qs.in
+++ b/Source/QtIFW/CMake.Dialogs.QtGUI.qs.in
@@ -11,7 +11,7 @@
     if (installer.value("os") === "win") {
 
         component.addOperation("CreateShortcut",
-                               "@TargetDir@/%CMAKE_BIN_DIR%/cmake-gui.exe",
+                               "@TargetDir@/%CMake_INSTALL_BIN_DIR%/cmake-gui.exe",
                                "@StartMenuDir@/CMake (cmake-gui).lnk");
 
     }
diff --git a/Source/QtIFW/CMake.Documentation.SphinxHTML.qs.in b/Source/QtIFW/CMake.Documentation.SphinxHTML.qs.in
index 54bc14a..14465aa 100644
--- a/Source/QtIFW/CMake.Documentation.SphinxHTML.qs.in
+++ b/Source/QtIFW/CMake.Documentation.SphinxHTML.qs.in
@@ -11,7 +11,7 @@
     if (installer.value("os") === "win") {
 
         component.addOperation("CreateShortcut",
-                               "@TargetDir@/%CMAKE_DOC_DIR%/html/index.html",
+                               "@TargetDir@/%CMake_INSTALL_DOC_DIR%/html/index.html",
                                "@StartMenuDir@/CMake Documentation.lnk");
 
     }
diff --git a/Source/QtIFW/CMake.qs.in b/Source/QtIFW/CMake.qs.in
index 1f3166e..76ffb92 100644
--- a/Source/QtIFW/CMake.qs.in
+++ b/Source/QtIFW/CMake.qs.in
@@ -11,7 +11,7 @@
     if (installer.value("os") === "win") {
 
         component.addOperation("CreateShortcut",
-                               "@TargetDir@/%CMAKE_DOC_DIR%/cmake.org.html",
+                               "@TargetDir@/%CMake_INSTALL_DOC_DIR%/cmake.org.html",
                                "@StartMenuDir@/CMake Web Site.lnk");
 
         component.addOperation("CreateShortcut",
diff --git a/Source/QtIFW/installscript.qs.in b/Source/QtIFW/installscript.qs.in
index 72d49e8..6abf5ba 100644
--- a/Source/QtIFW/installscript.qs.in
+++ b/Source/QtIFW/installscript.qs.in
@@ -14,7 +14,7 @@
 %_CPACK_IFW_SHORTCUT_OPTIONAL%
 
         component.addOperation("CreateShortcut",
-                               "@TargetDir@/%CMAKE_DOC_DIR%/cmake.org.html",
+                               "@TargetDir@/%CMake_INSTALL_DOC_DIR%/cmake.org.html",
                                "@StartMenuDir@/CMake Web Site.lnk");
 
         component.addOperation("CreateShortcut",
diff --git a/Source/cmBinUtilsLinker.cxx b/Source/cmBinUtilsLinker.cxx
index 4cce608..9766f8d 100644
--- a/Source/cmBinUtilsLinker.cxx
+++ b/Source/cmBinUtilsLinker.cxx
@@ -3,7 +3,14 @@
 
 #include "cmBinUtilsLinker.h"
 
+#include <utility>
+
+#include "cmCMakePath.h"
+#include "cmMakefile.h"
+#include "cmMessageType.h"
+#include "cmPolicies.h"
 #include "cmRuntimeDependencyArchive.h"
+#include "cmStringAlgorithms.h"
 
 cmBinUtilsLinker::cmBinUtilsLinker(cmRuntimeDependencyArchive* archive)
   : Archive(archive)
@@ -14,3 +21,29 @@
 {
   this->Archive->SetError(e);
 }
+
+void cmBinUtilsLinker::NormalizePath(std::string& path) const
+{
+  std::string normalizedPath =
+    cmCMakePath(path, cmCMakePath::auto_format).GenericString();
+
+  if (path == normalizedPath) {
+    return;
+  }
+
+  cmPolicies::PolicyStatus policy =
+    this->Archive->GetMakefile()->GetPolicyStatus(cmPolicies::CMP0207);
+  if (policy == cmPolicies::WARN) {
+    this->Archive->GetMakefile()->IssueMessage(
+      MessageType::AUTHOR_WARNING,
+      cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0207),
+               "\n"
+               "Path\n  \"",
+               path,
+               "\"\n"
+               "would be converted to\n  \"",
+               normalizedPath, "\"\n"));
+  } else if (policy == cmPolicies::NEW) {
+    path = std::move(normalizedPath);
+  }
+}
diff --git a/Source/cmBinUtilsLinker.h b/Source/cmBinUtilsLinker.h
index 5b41309..f093860 100644
--- a/Source/cmBinUtilsLinker.h
+++ b/Source/cmBinUtilsLinker.h
@@ -24,4 +24,6 @@
   cmRuntimeDependencyArchive* Archive;
 
   void SetError(std::string const& e);
+
+  void NormalizePath(std::string& path) const;
 };
diff --git a/Source/cmBinUtilsLinuxELFLinker.cxx b/Source/cmBinUtilsLinuxELFLinker.cxx
index cf338a9..e3ea16c 100644
--- a/Source/cmBinUtilsLinuxELFLinker.cxx
+++ b/Source/cmBinUtilsLinuxELFLinker.cxx
@@ -204,6 +204,7 @@
     path = cmStrCat(searchPath, '/', name);
     if (cmSystemTools::PathExists(path) &&
         FileHasArchitecture(path.c_str(), this->Machine)) {
+      this->NormalizePath(path);
       resolved = true;
       return true;
     }
diff --git a/Source/cmBinUtilsMacOSMachOLinker.cxx b/Source/cmBinUtilsMacOSMachOLinker.cxx
index 9867318..97dce1a 100644
--- a/Source/cmBinUtilsMacOSMachOLinker.cxx
+++ b/Source/cmBinUtilsMacOSMachOLinker.cxx
@@ -170,6 +170,7 @@
   } else {
     resolved = true;
     path = name;
+    this->NormalizePath(path);
   }
 
   if (resolved && !cmSystemTools::FileIsFullPath(path)) {
@@ -198,6 +199,7 @@
     return true;
   }
 
+  this->NormalizePath(path);
   resolved = true;
   return true;
 }
@@ -220,6 +222,7 @@
     return true;
   }
 
+  this->NormalizePath(path);
   resolved = true;
   return true;
 }
@@ -252,7 +255,7 @@
       /*
        * paraphrasing @ben.boeckel:
        *  if /b/libB.dylib is supposed to be used,
-       *  /a/libbB.dylib will be found first if it exists. CMake tries to
+       *  /a/libB.dylib will be found first if it exists. CMake tries to
        *  sort rpath directories to avoid this, but sometimes there is no
        *  right answer.
        *
@@ -268,7 +271,9 @@
        *  so as long as this method's resolution guarantees priority
        *  in that manner further checking should not be necessary?
        */
-      path = searchFile;
+      path = std::move(searchFile);
+
+      this->NormalizePath(path);
       resolved = true;
       return true;
     }
diff --git a/Source/cmBinUtilsWindowsPELinker.cxx b/Source/cmBinUtilsWindowsPELinker.cxx
index 70ddaf2..2864e30 100644
--- a/Source/cmBinUtilsWindowsPELinker.cxx
+++ b/Source/cmBinUtilsWindowsPELinker.cxx
@@ -155,6 +155,7 @@
   for (auto const& searchPath : dirs) {
     path = cmStrCat(searchPath, '/', name);
     if (cmSystemTools::PathExists(path)) {
+      this->NormalizePath(path);
       resolved = true;
       return true;
     }
diff --git a/Source/cmCMakeLanguageCommand.cxx b/Source/cmCMakeLanguageCommand.cxx
index a093f8d..2a90065 100644
--- a/Source/cmCMakeLanguageCommand.cxx
+++ b/Source/cmCMakeLanguageCommand.cxx
@@ -397,9 +397,7 @@
       return FatalError(status, "EXIT requires one argument");
     }
 
-    auto workingMode =
-      status.GetMakefile().GetCMakeInstance()->GetWorkingMode();
-    if (workingMode != cmake::SCRIPT_MODE) {
+    if (!status.GetMakefile().GetCMakeInstance()->RoleSupportsExitCode()) {
       return FatalError(status, "EXIT can be used only in SCRIPT mode");
     }
 
@@ -411,9 +409,7 @@
                                  expArgs[expArg], '\"'));
     }
 
-    if (workingMode == cmake::SCRIPT_MODE) {
-      status.SetExitCode(static_cast<int>(retCode));
-    }
+    status.SetExitCode(static_cast<int>(retCode));
     return true;
   }
 
diff --git a/Source/cmCMakeString.cxx b/Source/cmCMakeString.cxx
new file mode 100644
index 0000000..57d5b0e
--- /dev/null
+++ b/Source/cmCMakeString.cxx
@@ -0,0 +1,326 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file LICENSE.rst or https://cmake.org/licensing for details.  */
+
+#include "cmConfigure.h" // IWYU pragma: keep
+
+#include "cmCMakeString.hxx"
+
+#include <cstdio>
+#include <cstdlib>
+#include <memory>
+#include <stdexcept>
+#include <vector>
+
+#include "cmsys/RegularExpression.hxx"
+
+#include "cmCryptoHash.h"
+#include "cmGeneratorExpression.h"
+#include "cmMakefile.h"
+#include "cmPolicies.h"
+#include "cmStringAlgorithms.h"
+#include "cmStringReplaceHelper.h"
+#include "cmSystemTools.h"
+#include "cmTimestamp.h"
+#include "cmUuid.h"
+
+namespace cm {
+bool CMakeString::Compare(CompOperator op, cm::string_view other)
+{
+  switch (op) {
+    case CompOperator::EQUAL:
+      return this->String_ == other;
+    case CompOperator::LESS:
+      return this->String_ < other;
+    case CompOperator::LESS_EQUAL:
+      return this->String_ <= other;
+    case CompOperator::GREATER:
+      return this->String_ > other;
+    case CompOperator::GREATER_EQUAL:
+      return this->String_ >= other;
+    default:
+      return false;
+  }
+}
+
+CMakeString& CMakeString::Replace(std::string const& matchExpression,
+                                  std::string const& replaceExpression,
+                                  Regex regex, cmMakefile* makefile)
+{
+  if (regex == Regex::Yes) {
+    if (makefile) {
+      makefile->ClearMatches();
+    }
+
+    cmStringReplaceHelper replaceHelper(matchExpression, replaceExpression,
+                                        makefile);
+    if (!replaceHelper.IsReplaceExpressionValid()) {
+      throw std::invalid_argument(replaceHelper.GetError());
+    }
+    if (!replaceHelper.IsRegularExpressionValid()) {
+      throw std::invalid_argument(
+        cmStrCat("Failed to compile regex \"", matchExpression, '"'));
+    }
+
+    std ::string output;
+    if (!replaceHelper.Replace(this->String_, output)) {
+      throw std::runtime_error(replaceHelper.GetError());
+    }
+    this->String_ = std::move(output);
+  } else {
+    std::string output = this->String_.str();
+    cmsys::SystemTools::ReplaceString(output, matchExpression,
+                                      replaceExpression);
+    this->String_ = std::move(output);
+  }
+
+  return *this;
+};
+
+cmList CMakeString::Match(std::string const& matchExpression,
+                          MatchItems matchItems, cmMakefile* makefile) const
+{
+  if (makefile) {
+    makefile->ClearMatches();
+  }
+
+  // Compile the regular expression.
+  cmsys::RegularExpression re;
+  if (!re.compile(matchExpression)) {
+    throw std::invalid_argument(
+      cmStrCat("Failed to compile regex \"", matchExpression, '"'));
+  }
+
+  cmList output;
+  if (matchItems == MatchItems::Once) {
+    if (re.find(this->String_.data())) {
+      if (makefile) {
+        makefile->StoreMatches(re);
+      }
+      output = re.match();
+    }
+  } else {
+    unsigned optAnchor = 0;
+    if (makefile &&
+        makefile->GetPolicyStatus(cmPolicies::CMP0186) != cmPolicies::NEW) {
+      optAnchor = cmsys::RegularExpression::BOL_AT_OFFSET;
+    }
+
+    // Scan through the input for all matches.
+    std::string::size_type base = 0;
+    unsigned optNonEmpty = 0;
+    while (re.find(this->String_.data(), base, optAnchor | optNonEmpty)) {
+      if (makefile) {
+        makefile->ClearMatches();
+        makefile->StoreMatches(re);
+      }
+
+      output.push_back(re.match());
+      base = re.end();
+
+      if (re.start() == this->String_.length()) {
+        break;
+      }
+      if (re.start() == re.end()) {
+        optNonEmpty = cmsys::RegularExpression::NONEMPTY_AT_OFFSET;
+      } else {
+        optNonEmpty = 0;
+      }
+    }
+  }
+
+  return output;
+}
+
+CMakeString CMakeString::Substring(long begin, long count) const
+{
+  if (begin < 0 || static_cast<size_type>(begin) > this->String_.size()) {
+    throw std::out_of_range(cmStrCat(
+      "begin index: ", begin, " is out of range 0 - ", this->String_.size()));
+  }
+  if (count < -1) {
+    throw std::out_of_range(
+      cmStrCat("end index: ", count, " should be -1 or greater"));
+  }
+
+  return this->String_.substr(static_cast<size_type>(begin),
+                              count == -1 ? npos
+                                          : static_cast<size_type>(count));
+}
+
+CMakeString& CMakeString::Strip(StripItems stripItems)
+{
+  if (stripItems == StripItems::Space) {
+    this->String_ = cmTrimWhitespace(this->String_);
+  } else {
+    this->String_ = cmGeneratorExpression::Preprocess(
+      this->String_, cmGeneratorExpression::StripAllGeneratorExpressions);
+  }
+
+  return *this;
+}
+
+CMakeString& CMakeString::Repeat(size_type count)
+{
+  switch (this->Size()) {
+    case 0u:
+      // Nothing to do for zero length input strings
+      break;
+    case 1u:
+      // NOTE If the string to repeat consists of the only character,
+      // use the appropriate constructor.
+      this->String_ = std::string(count, this->String_[0]);
+      break;
+    default:
+      std::string result;
+      auto size = this->Size();
+
+      result.reserve(size * count);
+      for (auto i = 0u; i < count; ++i) {
+        result.insert(i * size, this->String_.data(), size);
+      }
+      this->String_ = std::move(result);
+      break;
+  }
+  return *this;
+}
+
+CMakeString& CMakeString::Quote(QuoteItems)
+{
+  std ::string output;
+  // Escape all regex special characters
+  cmStringReplaceHelper replaceHelper("([][()+*^.$?|\\\\])", R"(\\\1)");
+  if (!replaceHelper.Replace(this->String_, output)) {
+    throw std::runtime_error(replaceHelper.GetError());
+  }
+
+  this->String_ = std::move(output);
+  return *this;
+}
+
+CMakeString& CMakeString::Hash(cm::string_view hashAlgorithm)
+{
+  std::unique_ptr<cmCryptoHash> hash(cmCryptoHash::New(hashAlgorithm));
+  if (hash) {
+    this->String_ = hash->HashString(this->String_);
+    return *this;
+  }
+
+  throw std::invalid_argument(
+    cmStrCat(hashAlgorithm, ": invalid hash algorithm."));
+}
+
+CMakeString& CMakeString::FromASCII(string_range codes)
+{
+  std::string output;
+  output.reserve(codes.size());
+
+  for (auto const& code : codes) {
+    try {
+      auto ch = std::stoi(code);
+      if (ch > 0 && ch < 256) {
+        output += static_cast<char>(ch);
+      } else {
+        throw std::invalid_argument(
+          cmStrCat("Character with code ", code, " does not exist."));
+      }
+    } catch (...) {
+      throw std::invalid_argument(
+        cmStrCat("Character with code ", code, " does not exist."));
+    }
+  }
+  this->String_ = std::move(output);
+  return *this;
+}
+
+CMakeString& CMakeString::ToHexadecimal(cm::string_view str)
+{
+  std::string output(str.size() * 2, ' ');
+  std::string::size_type hexIndex = 0;
+
+  for (auto const& c : str) {
+    std::snprintf(&output[hexIndex], 3, "%.2x", c & 0xFFu);
+    hexIndex += 2;
+  }
+  this->String_ = output;
+  return *this;
+}
+
+cm::string_view const CMakeString::RandomDefaultAlphabet{
+  "qwertyuiopasdfghjklzxcvbnm"
+  "QWERTYUIOPASDFGHJKLZXCVBNM"
+  "0123456789"
+};
+bool CMakeString::Seeded = false;
+
+CMakeString& CMakeString::Random(unsigned int seed, std::size_t length,
+                                 cm::string_view alphabet)
+{
+  if (alphabet.empty()) {
+    alphabet = RandomDefaultAlphabet;
+  }
+
+  if (length < 1) {
+    throw std::out_of_range("Invoked with bad length.");
+  }
+
+  if (!this->Seeded) {
+    this->Seeded = true;
+    std::srand(seed);
+  }
+
+  double alphabetSize = static_cast<double>(alphabet.size());
+  std::vector<char> result;
+  result.reserve(length + 1);
+
+  for (std::size_t i = 0; i < length; i++) {
+    auto index = static_cast<std::string::size_type>(
+      alphabetSize * std::rand() / (RAND_MAX + 1.0));
+    result.push_back(alphabet[index]);
+  }
+  result.push_back(0);
+
+  this->String_ = result.data();
+  return *this;
+}
+
+CMakeString& CMakeString::Timestamp(cm::string_view format, UTC utc)
+{
+  cmTimestamp timestamp;
+  this->String_ = timestamp.CurrentTime(format, utc == UTC::Yes);
+  return *this;
+}
+
+CMakeString& CMakeString::UUID(cm::string_view nameSpace, cm::string_view name,
+                               UUIDType type, Case uuidCase)
+{
+#if !defined(CMAKE_BOOTSTRAP)
+  cmUuid uuidGenerator;
+  std::vector<unsigned char> uuidNamespace;
+  std::string uuid;
+
+  if (!uuidGenerator.StringToBinary(nameSpace, uuidNamespace)) {
+    throw std::invalid_argument("malformed NAMESPACE UUID");
+  }
+
+  if (type == UUIDType::MD5) {
+    uuid = uuidGenerator.FromMd5(uuidNamespace, name);
+  } else if (type == UUIDType::SHA1) {
+    uuid = uuidGenerator.FromSha1(uuidNamespace, name);
+  }
+
+  if (uuid.empty()) {
+    throw std::runtime_error("generation failed");
+  }
+
+  if (uuidCase == Case::Upper) {
+    uuid = cmSystemTools::UpperCase(uuid);
+  }
+
+  this->String_ = std::move(uuid);
+  return *this;
+#else
+  throw std::runtime_error("not available during bootstrap");
+#endif
+}
+
+}
diff --git a/Source/cmCMakeString.hxx b/Source/cmCMakeString.hxx
new file mode 100644
index 0000000..3c29871
--- /dev/null
+++ b/Source/cmCMakeString.hxx
@@ -0,0 +1,259 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file LICENSE.rst or https://cmake.org/licensing for details.  */
+
+#pragma once
+
+#include "cmConfigure.h" // IWYU pragma: keep
+
+#include <cstddef>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include <cm/string_view>
+
+#include "cmList.h"
+#include "cmRange.h"
+#include "cmString.hxx"
+#include "cmStringAlgorithms.h"
+#include "cmSystemTools.h"
+#include "cmValue.h"
+
+class cmMakefile;
+
+//
+// Class offering various string operations which is used by
+// * CMake string() command
+// * $<STRING> generator expression
+//
+
+namespace cm {
+
+class CMakeString
+{
+public:
+  using size_type = cm::String::size_type;
+  static auto const npos = cm::String::npos;
+
+  using string_range = cmRange<std::vector<std::string>::const_iterator>;
+
+  CMakeString(std::string const& str)
+    : String_(cm::String::borrow(str))
+  {
+  }
+  CMakeString(cm::string_view str)
+    : String_(cm::String::borrow(str))
+  {
+  }
+  CMakeString(cm::String const& str)
+    : String_(str)
+  {
+  }
+  CMakeString(cm::String&& str)
+    : String_(std::move(str))
+  {
+  }
+  CMakeString(cmValue value)
+    : String_(cm::String::borrow(*value))
+  {
+  }
+  CMakeString(string_range range,
+              cm::string_view separator = cm::string_view{})
+    : String_(cmJoin(range, separator))
+  {
+  }
+
+  CMakeString() = default;
+  CMakeString(CMakeString const&) = default;
+  CMakeString(CMakeString&&) = default;
+
+  CMakeString& operator=(CMakeString const& string)
+  {
+    if (this != &string) {
+      this->String_ = string.String_;
+    }
+    return *this;
+  }
+  CMakeString& operator=(CMakeString&& string) noexcept
+  {
+    if (this != &string) {
+      this->String_ = std::move(string.String_);
+    }
+    return *this;
+  }
+  CMakeString& operator=(cm::string_view string)
+  {
+    this->String_ = string;
+    return *this;
+  }
+
+  // conversions
+  string_view view() const noexcept { return this->String_.view(); }
+  operator cm::string_view() noexcept { return this->String_.view(); }
+  operator std::string const&() { return this->String_.str(); }
+
+  size_type Size() const { return this->String_.size(); }
+  size_type Length() const { return this->String_.size(); }
+
+  enum class CompOperator
+  {
+    EQUAL,
+    LESS,
+    LESS_EQUAL,
+    GREATER,
+    GREATER_EQUAL
+  };
+  bool Compare(CompOperator op, cm::string_view other);
+
+  enum class FindFrom
+  {
+    Begin,
+    End
+  };
+  size_type Find(cm::string_view substring,
+                 FindFrom from = FindFrom::Begin) const
+  {
+    return from == FindFrom::Begin ? this->String_.find(substring)
+                                   : this->String_.rfind(substring);
+  }
+
+  enum class Regex
+  {
+    No,
+    Yes
+  };
+  // Throw std::invalid_argument if regular expression is invalid
+  //       std::runtime_error if replacement failed
+  CMakeString& Replace(std::string const& matchExpression,
+                       std::string const& replaceExpression,
+                       Regex regex = Regex::No,
+                       cmMakefile* makefile = nullptr);
+
+  enum class MatchItems
+  {
+    Once,
+    All
+  };
+  // Throw std::invalid_argument if regular expression is invalid
+  cmList Match(std::string const& matchExpression,
+               MatchItems matchItems = MatchItems::Once,
+               cmMakefile* makefile = nullptr) const;
+
+  CMakeString& Append(cm::string_view str)
+  {
+    this->String_.append(str);
+    return *this;
+  }
+  CMakeString& Append(string_range range)
+  {
+    this->Append(cmJoin(range, {}));
+    return *this;
+  }
+  CMakeString& Prepend(cm::string_view str)
+  {
+    this->String_.insert(0, str);
+    return *this;
+  }
+  CMakeString& Prepend(string_range range)
+  {
+    this->Prepend(cmJoin(range, {}));
+    return *this;
+  }
+
+  CMakeString& ToLower()
+  {
+    this->String_ = cmSystemTools::LowerCase(this->String_);
+    return *this;
+  }
+  CMakeString& ToLower(cm::string_view str)
+  {
+    this->String_ = cmSystemTools::LowerCase(str);
+    return *this;
+  }
+  CMakeString& ToUpper()
+  {
+    this->String_ = cmSystemTools::UpperCase(this->String_);
+    return *this;
+  }
+  CMakeString& ToUpper(cm::string_view str)
+  {
+    this->String_ = cmSystemTools::UpperCase(str);
+    return *this;
+  }
+
+  // Throw std::out_of_range if pos or count are outside of the expected range
+  CMakeString Substring(long pos = 0, long count = -1) const;
+
+  enum class StripItems
+  {
+    Space,
+    Genex
+  };
+  CMakeString& Strip(StripItems stripItems = StripItems::Space);
+
+  // Throw std::runtime_error  if quoting string failed
+  enum class QuoteItems
+  {
+    Regex
+  };
+  CMakeString& Quote(QuoteItems quoteItems = QuoteItems::Regex);
+
+  CMakeString& Repeat(size_type count);
+
+  // Throw std::invalid_argument if the hash algorithm is invalid
+  CMakeString& Hash(cm::string_view hashAlgorithm);
+
+  // Throw std::invalid_argument if one of the codes is invalid
+  CMakeString& FromASCII(string_range codes);
+  CMakeString& ToHexadecimal() { return this->ToHexadecimal(this->String_); }
+  CMakeString& ToHexadecimal(cm::string_view str);
+
+  CMakeString& MakeCIdentifier()
+  {
+    this->String_ = cmSystemTools::MakeCidentifier(this->String_.str());
+    return *this;
+  }
+  CMakeString& MakeCIdentifier(std::string const& str)
+  {
+    this->String_ = cmSystemTools::MakeCidentifier(str);
+    return *this;
+  }
+
+  static cm::string_view const RandomDefaultAlphabet;
+  // Throw std::invalid_argument if the alphabet is invalid
+  //       std::out_of_range if length is outside valid range
+  CMakeString& Random(std::size_t length = 5,
+                      cm::string_view alphabet = RandomDefaultAlphabet)
+  {
+    return this->Random(cmSystemTools::RandomSeed(), length, alphabet);
+  }
+  CMakeString& Random(unsigned int seed, std::size_t length = 5,
+                      cm::string_view alphabet = RandomDefaultAlphabet);
+
+  enum class UTC
+  {
+    No,
+    Yes
+  };
+  CMakeString& Timestamp(cm::string_view format, UTC utc = UTC::No);
+
+  enum class UUIDType
+  {
+    MD5,
+    SHA1
+  };
+  enum class Case
+  {
+    Lower,
+    Upper
+  };
+  // Throw std::invalid_argument if namespace or the type are invalid
+  //       std::runtime_error if the UUID cannot be generated
+  CMakeString& UUID(cm::string_view nameSpace, cm::string_view name,
+                    UUIDType type, Case uuidCase = Case::Lower);
+
+private:
+  static bool Seeded;
+  cm::String String_;
+};
+}
diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx
index e62743b..a51570b 100644
--- a/Source/cmCTest.cxx
+++ b/Source/cmCTest.cxx
@@ -2531,7 +2531,7 @@
         this->Impl->BuildAndTest.TestCommandArgs.emplace_back(args[i]);
       }
     }
-    if (!matched && cmHasLiteralPrefix(arg, "-") &&
+    if (!matched && cmHasPrefix(arg, '-') &&
         !cmHasLiteralPrefix(arg, "--preset")) {
       cmSystemTools::Error(cmStrCat("Unknown argument: ", arg));
       cmSystemTools::Error("Run 'ctest --help' for all supported options.");
@@ -2660,9 +2660,7 @@
   cmCTestTestHandler handler(this);
 
   {
-    cmake cm(cmake::RoleScript, cmState::CTest);
-    cm.SetHomeDirectory("");
-    cm.SetHomeOutputDirectory("");
+    cmake cm(cmState::Role::CTest);
     cm.GetCurrentSnapshot().SetDefaultDefinitions();
     cmGlobalGenerator gg(&cm);
     cmMakefile mf(&gg, cm.GetCurrentSnapshot());
diff --git a/Source/cmCustomCommandGenerator.cxx b/Source/cmCustomCommandGenerator.cxx
index 4d34d66..b63d2a6 100644
--- a/Source/cmCustomCommandGenerator.cxx
+++ b/Source/cmCustomCommandGenerator.cxx
@@ -53,7 +53,7 @@
         ++pos;
         continue;
       }
-      if (cmHasLiteralPrefix(cur, ">")) {
+      if (cmHasPrefix(cur, '>')) {
         --nestingLevel;
         if (nestingLevel == 0) {
           ++pos;
diff --git a/Source/cmCxxModuleMetadata.cxx b/Source/cmCxxModuleMetadata.cxx
new file mode 100644
index 0000000..b090305
--- /dev/null
+++ b/Source/cmCxxModuleMetadata.cxx
@@ -0,0 +1,460 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file LICENSE.rst or https://cmake.org/licensing for details.  */
+
+#include "cmCxxModuleMetadata.h"
+
+#include <algorithm>
+#include <set>
+#include <string>
+#include <utility>
+
+#include <cmext/string_view>
+
+#include <cm3p/json/value.h>
+#include <cm3p/json/writer.h>
+
+#include "cmsys/FStream.hxx"
+
+#include "cmFileSet.h"
+#include "cmJSONState.h"
+#include "cmListFileCache.h"
+#include "cmStringAlgorithms.h"
+#include "cmSystemTools.h"
+#include "cmTarget.h"
+
+namespace {
+
+bool JsonIsStringArray(Json::Value const& v)
+{
+  return v.isArray() &&
+    std::all_of(v.begin(), v.end(),
+                [](Json::Value const& it) { return it.isString(); });
+}
+
+bool ParsePreprocessorDefine(Json::Value& dval,
+                             cmCxxModuleMetadata::PreprocessorDefineData& out,
+                             cmJSONState* state)
+{
+  if (!dval.isObject()) {
+    state->AddErrorAtValue("each entry in 'definitions' must be an object",
+                           &dval);
+    return false;
+  }
+
+  if (!dval.isMember("name") || !dval["name"].isString() ||
+      dval["name"].asString().empty()) {
+    state->AddErrorAtValue(
+      "preprocessor definition requires a non-empty 'name'", &dval["name"]);
+    return false;
+  }
+  out.Name = dval["name"].asString();
+
+  if (dval.isMember("value")) {
+    if (dval["value"].isString()) {
+      out.Value = dval["value"].asString();
+    } else if (!dval["value"].isNull()) {
+      state->AddErrorAtValue(
+        "'value' in preprocessor definition must be string or null",
+        &dval["value"]);
+      return false;
+    }
+  }
+
+  if (dval.isMember("undef")) {
+    if (!dval["undef"].isBool()) {
+      state->AddErrorAtValue(
+        "'undef' in preprocessor definition must be boolean", &dval["undef"]);
+      return false;
+    }
+    out.Undef = dval["undef"].asBool();
+  }
+
+  if (dval.isMember("vendor")) {
+    out.Vendor = std::move(dval["vendor"]);
+  }
+
+  return true;
+}
+
+bool ParseLocalArguments(Json::Value& lav,
+                         cmCxxModuleMetadata::LocalArgumentsData& out,
+                         cmJSONState* state)
+{
+  if (!lav.isObject()) {
+    state->AddErrorAtValue("'local-arguments' must be an object", &lav);
+    return false;
+  }
+
+  if (lav.isMember("include-directories")) {
+    if (!JsonIsStringArray(lav["include-directories"])) {
+      state->AddErrorAtValue(
+        "'include-directories' must be an array of strings",
+        &lav["include-directories"]);
+      return false;
+    }
+    for (auto const& s : lav["include-directories"]) {
+      out.IncludeDirectories.push_back(s.asString());
+    }
+  }
+
+  if (lav.isMember("system-include-directories")) {
+    if (!JsonIsStringArray(lav["system-include-directories"])) {
+      state->AddErrorAtValue(
+        "'system-include-directories' must be an array of strings",
+        &lav["system-include-directories"]);
+      return false;
+    }
+    for (auto const& s : lav["system-include-directories"]) {
+      out.SystemIncludeDirectories.push_back(s.asString());
+    }
+  }
+
+  if (lav.isMember("definitions")) {
+    if (!lav["definitions"].isArray()) {
+      state->AddErrorAtValue("'definitions' must be an array",
+                             &lav["definitions"]);
+      return false;
+    }
+    for (Json::Value& dval : lav["definitions"]) {
+      out.Definitions.emplace_back();
+      if (!ParsePreprocessorDefine(dval, out.Definitions.back(), state)) {
+        return false;
+      }
+    }
+  }
+
+  if (lav.isMember("vendor")) {
+    out.Vendor = std::move(lav["vendor"]);
+  }
+
+  return true;
+}
+
+bool ParseModule(Json::Value& mval, cmCxxModuleMetadata::ModuleData& mod,
+                 cmJSONState* state)
+{
+  if (!mval.isObject()) {
+    state->AddErrorAtValue("each entry in 'modules' must be an object", &mval);
+    return false;
+  }
+
+  if (!mval.isMember("logical-name") || !mval["logical-name"].isString() ||
+      mval["logical-name"].asString().empty()) {
+    state->AddErrorAtValue(
+      "module entries require a non-empty 'logical-name' string",
+      &mval["logical-name"]);
+    return false;
+  }
+  mod.LogicalName = mval["logical-name"].asString();
+
+  if (!mval.isMember("source-path") || !mval["source-path"].isString() ||
+      mval["source-path"].asString().empty()) {
+    state->AddErrorAtValue(
+      "module entries require a non-empty 'source-path' string",
+      &mval["source-path"]);
+    return false;
+  }
+  mod.SourcePath = mval["source-path"].asString();
+
+  if (mval.isMember("is-interface")) {
+    if (!mval["is-interface"].isBool()) {
+      state->AddErrorAtValue("'is-interface' must be boolean",
+                             &mval["is-interface"]);
+      return false;
+    }
+    mod.IsInterface = mval["is-interface"].asBool();
+  } else {
+    mod.IsInterface = true;
+  }
+
+  if (mval.isMember("is-std-library")) {
+    if (!mval["is-std-library"].isBool()) {
+      state->AddErrorAtValue("'is-std-library' must be boolean",
+                             &mval["is-std-library"]);
+      return false;
+    }
+    mod.IsStdLibrary = mval["is-std-library"].asBool();
+  } else {
+    mod.IsStdLibrary = false;
+  }
+
+  if (mval.isMember("local-arguments")) {
+    mod.LocalArguments.emplace();
+    if (!ParseLocalArguments(mval["local-arguments"], *mod.LocalArguments,
+                             state)) {
+      return false;
+    }
+  }
+
+  if (mval.isMember("vendor")) {
+    mod.Vendor = std::move(mval["vendor"]);
+  }
+
+  return true;
+}
+
+bool ParseRoot(Json::Value& root, cmCxxModuleMetadata& meta,
+               cmJSONState* state)
+{
+  if (!root.isMember("version") || !root["version"].isInt()) {
+    state->AddErrorAtValue(
+      "Top-level member 'version' is required and must be an integer", &root);
+    return false;
+  }
+  meta.Version = root["version"].asInt();
+
+  if (root.isMember("revision")) {
+    if (!root["revision"].isInt()) {
+      state->AddErrorAtValue("'revision' must be an integer",
+                             &root["revision"]);
+      return false;
+    }
+    meta.Revision = root["revision"].asInt();
+  }
+
+  if (root.isMember("modules")) {
+    if (!root["modules"].isArray()) {
+      state->AddErrorAtValue("'modules' must be an array", &root["modules"]);
+      return false;
+    }
+    for (Json::Value& mval : root["modules"]) {
+      meta.Modules.emplace_back();
+      if (!ParseModule(mval, meta.Modules.back(), state)) {
+        return false;
+      }
+    }
+  }
+
+  for (std::string& key : root.getMemberNames()) {
+    if (key == "version" || key == "revision" || key == "modules") {
+      continue;
+    }
+    meta.Extensions.emplace(std::move(key), std::move(root[key]));
+  }
+
+  return true;
+}
+
+} // namespace
+
+cmCxxModuleMetadata::ParseResult cmCxxModuleMetadata::LoadFromFile(
+  std::string const& path)
+{
+  ParseResult res;
+
+  Json::Value root;
+  cmJSONState parseState(path, &root);
+  if (!parseState.errors.empty()) {
+    res.Error = parseState.GetErrorMessage();
+    return res;
+  }
+
+  cmCxxModuleMetadata meta;
+  if (!ParseRoot(root, meta, &parseState)) {
+    res.Error = parseState.GetErrorMessage();
+    return res;
+  }
+
+  meta.MetadataFilePath = path;
+  res.Meta = std::move(meta);
+  return res;
+}
+
+namespace {
+
+Json::Value SerializePreprocessorDefine(
+  cmCxxModuleMetadata::PreprocessorDefineData const& d)
+{
+  Json::Value dv(Json::objectValue);
+  dv["name"] = d.Name;
+  if (d.Value) {
+    dv["value"] = *d.Value;
+  } else {
+    dv["value"] = Json::Value::null;
+  }
+  dv["undef"] = d.Undef;
+  if (d.Vendor) {
+    dv["vendor"] = *d.Vendor;
+  }
+  return dv;
+}
+
+Json::Value SerializeLocalArguments(
+  cmCxxModuleMetadata::LocalArgumentsData const& la)
+{
+  Json::Value lav(Json::objectValue);
+
+  if (!la.IncludeDirectories.empty()) {
+    Json::Value& inc = lav["include-directories"] = Json::arrayValue;
+    for (auto const& s : la.IncludeDirectories) {
+      inc.append(s);
+    }
+  }
+
+  if (!la.SystemIncludeDirectories.empty()) {
+    Json::Value& sinc = lav["system-include-directories"] = Json::arrayValue;
+    for (auto const& s : la.SystemIncludeDirectories) {
+      sinc.append(s);
+    }
+  }
+
+  if (!la.Definitions.empty()) {
+    Json::Value& defs = lav["definitions"] = Json::arrayValue;
+    for (auto const& d : la.Definitions) {
+      defs.append(SerializePreprocessorDefine(d));
+    }
+  }
+
+  if (la.Vendor) {
+    lav["vendor"] = *la.Vendor;
+  }
+
+  return lav;
+}
+
+Json::Value SerializeModule(cmCxxModuleMetadata::ModuleData const& m)
+{
+  Json::Value mv(Json::objectValue);
+  mv["logical-name"] = m.LogicalName;
+  mv["source-path"] = m.SourcePath;
+  mv["is-interface"] = m.IsInterface;
+  mv["is-std-library"] = m.IsStdLibrary;
+
+  if (m.LocalArguments) {
+    mv["local-arguments"] = SerializeLocalArguments(*m.LocalArguments);
+  }
+
+  if (m.Vendor) {
+    mv["vendor"] = *m.Vendor;
+  }
+
+  return mv;
+}
+
+} // namespace
+
+Json::Value cmCxxModuleMetadata::ToJsonValue(cmCxxModuleMetadata const& meta)
+{
+  Json::Value root(Json::objectValue);
+
+  root["version"] = meta.Version;
+  root["revision"] = meta.Revision;
+
+  Json::Value& modules = root["modules"] = Json::arrayValue;
+  for (auto const& m : meta.Modules) {
+    modules.append(SerializeModule(m));
+  }
+
+  for (auto const& kv : meta.Extensions) {
+    root[kv.first] = kv.second;
+  }
+
+  return root;
+}
+
+cmCxxModuleMetadata::SaveResult cmCxxModuleMetadata::SaveToFile(
+  std::string const& path, cmCxxModuleMetadata const& meta)
+{
+  SaveResult st;
+
+  cmsys::ofstream ofs(path.c_str());
+  if (!ofs.is_open()) {
+    st.Error = cmStrCat("Unable to open file for writing: "_s, path);
+    return st;
+  }
+
+  Json::StreamWriterBuilder wbuilder;
+  wbuilder["indentation"] = "  ";
+  ofs << Json::writeString(wbuilder, ToJsonValue(meta));
+
+  if (!ofs.good()) {
+    st.Error = cmStrCat("Write failed for file: "_s, path);
+    return st;
+  }
+
+  st.Ok = true;
+  return st;
+}
+
+void cmCxxModuleMetadata::PopulateTarget(
+  cmTarget& target, cmCxxModuleMetadata const& meta,
+  std::vector<std::string> const& configs)
+{
+  std::vector<cm::string_view> allIncludeDirectories;
+  std::vector<std::string> allCompileDefinitions;
+  std::set<std::string> baseDirs;
+
+  std::string metadataDir =
+    cmSystemTools::GetFilenamePath(meta.MetadataFilePath);
+
+  auto fileSet = target.GetOrCreateFileSet("CXX_MODULES", "CXX_MODULES",
+                                           cmFileSetVisibility::Interface);
+
+  for (auto const& module : meta.Modules) {
+    std::string sourcePath = module.SourcePath;
+    if (!cmSystemTools::FileIsFullPath(sourcePath)) {
+      sourcePath = cmStrCat(metadataDir, '/', sourcePath);
+    }
+
+    // Module metadata files can reference files in different roots,
+    // just use the immediate parent directory as a base directory
+    baseDirs.insert(cmSystemTools::GetFilenamePath(sourcePath));
+
+    fileSet.first->AddFileEntry(sourcePath);
+
+    if (module.LocalArguments) {
+      for (auto const& incDir : module.LocalArguments->IncludeDirectories) {
+        allIncludeDirectories.push_back(incDir);
+      }
+      for (auto const& sysIncDir :
+           module.LocalArguments->SystemIncludeDirectories) {
+        allIncludeDirectories.push_back(sysIncDir);
+      }
+
+      for (auto const& def : module.LocalArguments->Definitions) {
+        if (!def.Undef) {
+          if (def.Value) {
+            allCompileDefinitions.push_back(
+              cmStrCat(def.Name, "="_s, *def.Value));
+          } else {
+            allCompileDefinitions.push_back(def.Name);
+          }
+        }
+      }
+    }
+  }
+
+  for (auto const& baseDir : baseDirs) {
+    fileSet.first->AddDirectoryEntry(baseDir);
+  }
+
+  if (!allIncludeDirectories.empty()) {
+    target.SetProperty("IMPORTED_CXX_MODULES_INCLUDE_DIRECTORIES",
+                       cmJoin(allIncludeDirectories, ";"));
+  }
+
+  if (!allCompileDefinitions.empty()) {
+    target.SetProperty("IMPORTED_CXX_MODULES_COMPILE_DEFINITIONS",
+                       cmJoin(allCompileDefinitions, ";"));
+  }
+
+  for (auto const& config : configs) {
+    std::vector<std::string> moduleList;
+    for (auto const& module : meta.Modules) {
+      if (module.IsInterface) {
+        std::string sourcePath = module.SourcePath;
+        if (!cmSystemTools::FileIsFullPath(sourcePath)) {
+          sourcePath = cmStrCat(metadataDir, '/', sourcePath);
+        }
+        moduleList.push_back(cmStrCat(module.LogicalName, "="_s, sourcePath));
+      }
+    }
+
+    if (!moduleList.empty()) {
+      std::string upperConfig = cmSystemTools::UpperCase(config);
+      std::string propertyName =
+        cmStrCat("IMPORTED_CXX_MODULES_"_s, upperConfig);
+      target.SetProperty(propertyName, cmJoin(moduleList, ";"));
+    }
+  }
+}
diff --git a/Source/cmCxxModuleMetadata.h b/Source/cmCxxModuleMetadata.h
new file mode 100644
index 0000000..60769b8
--- /dev/null
+++ b/Source/cmCxxModuleMetadata.h
@@ -0,0 +1,84 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file LICENSE.rst or https://cmake.org/licensing for details.  */
+#pragma once
+
+#include <string>
+#include <unordered_map>
+#include <vector>
+
+#include <cm/optional>
+#include <cm/string_view>
+
+#include <cm3p/json/value.h>
+
+class cmTarget;
+
+class cmCxxModuleMetadata
+{
+public:
+  struct PreprocessorDefineData
+  {
+    std::string Name;
+    cm::optional<std::string> Value;
+    bool Undef = false;
+    cm::optional<Json::Value> Vendor;
+  };
+
+  struct LocalArgumentsData
+  {
+    std::vector<std::string> IncludeDirectories;
+    std::vector<std::string> SystemIncludeDirectories;
+    std::vector<PreprocessorDefineData> Definitions;
+    cm::optional<Json::Value> Vendor;
+  };
+
+  struct ModuleData
+  {
+    std::string LogicalName;
+    std::string SourcePath;
+    bool IsInterface = true;
+    bool IsStdLibrary = false;
+    cm::optional<LocalArgumentsData> LocalArguments;
+    cm::optional<Json::Value> Vendor;
+  };
+
+  int Version = 0;
+  int Revision = 0;
+  std::vector<ModuleData> Modules;
+  std::string MetadataFilePath;
+
+  std::unordered_map<std::string, Json::Value> Extensions;
+
+  struct ParseResult;
+
+  struct SaveResult
+  {
+    bool Ok = false;
+    std::string Error;
+    explicit operator bool() const { return Ok; }
+  };
+
+  static ParseResult LoadFromFile(std::string const& path);
+  static Json::Value ToJsonValue(cmCxxModuleMetadata const& meta);
+  static SaveResult SaveToFile(std::string const& path,
+                               cmCxxModuleMetadata const& meta);
+  static void PopulateTarget(cmTarget& target, cmCxxModuleMetadata const& meta,
+                             std::vector<std::string> const& configs);
+  static void PopulateTarget(cmTarget& target, cmCxxModuleMetadata const& meta,
+                             cm::string_view config)
+  {
+    PopulateTarget(target, meta,
+                   std::vector<std::string>{ std::string(config) });
+  }
+  static void PopulateTarget(cmTarget& target, cmCxxModuleMetadata const& meta)
+  {
+    PopulateTarget(target, meta, "NOCONFIG");
+  }
+};
+
+struct cmCxxModuleMetadata::ParseResult
+{
+  cm::optional<cmCxxModuleMetadata> Meta;
+  std::string Error;
+  explicit operator bool() const { return static_cast<bool>(Meta); }
+};
diff --git a/Source/cmExperimental.cxx b/Source/cmExperimental.cxx
index b7aec46..fe180b6 100644
--- a/Source/cmExperimental.cxx
+++ b/Source/cmExperimental.cxx
@@ -55,6 +55,15 @@
     "experimentation and feedback to CMake developers.",
     {},
     cmExperimental::TryCompileCondition::Always },
+  // MappedPackageInfo
+  { "MappedPackageInfo",
+    "ababa1b5-7099-495f-a9cd-e22d38f274f2",
+    "CMAKE_EXPERIMENTAL_MAPPED_PACKAGE_INFO",
+    "CMake's support for generating package information in the Common Package "
+    "Specification format from CMake script exports is experimental. It is "
+    "meant only for experimentation and feedback to CMake developers.",
+    {},
+    cmExperimental::TryCompileCondition::Always },
   // ExportBuildDatabase
   { "ExportBuildDatabase",
     "73194a1d-c0b5-41b9-9190-a4512925e192",
diff --git a/Source/cmExperimental.h b/Source/cmExperimental.h
index 54fd691..5171e18 100644
--- a/Source/cmExperimental.h
+++ b/Source/cmExperimental.h
@@ -21,6 +21,7 @@
     CxxImportStd,
     ImportPackageInfo,
     ExportPackageInfo,
+    MappedPackageInfo,
     ExportBuildDatabase,
     Instrumentation,
 
diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx
index 9accd7d..db78ba7 100644
--- a/Source/cmExportInstallFileGenerator.cxx
+++ b/Source/cmExportInstallFileGenerator.cxx
@@ -388,9 +388,8 @@
   cmGeneratorTarget const* const gt = targetExport->Target;
 
   std::string includesDestinationDirs;
-  this->PopulateInterfaceProperty("INTERFACE_SYSTEM_INCLUDE_DIRECTORIES", gt,
-                                  cmGeneratorExpression::InstallInterface,
-                                  properties);
+  this->PopulateSystemIncludeDirectoriesInterface(
+    gt, cmGeneratorExpression::InstallInterface, properties);
   this->PopulateIncludeDirectoriesInterface(
     gt, cmGeneratorExpression::InstallInterface, properties, *targetExport,
     includesDestinationDirs);
@@ -519,6 +518,38 @@
   }
 }
 
+void cmExportInstallFileGenerator::PopulateSystemIncludeDirectoriesInterface(
+  cmGeneratorTarget const* target,
+  cmGeneratorExpression::PreprocessContext preprocessRule,
+  ImportPropertyMap& properties)
+{
+  assert(preprocessRule == cmGeneratorExpression::InstallInterface);
+
+  char const* const propName = "INTERFACE_SYSTEM_INCLUDE_DIRECTORIES";
+  cmValue input = target->GetProperty(propName);
+
+  if (!input) {
+    return;
+  }
+  if (input->empty()) {
+    // Set to empty
+    properties[propName].clear();
+    return;
+  }
+
+  std::string includes = (input ? *input : "");
+  std::string prepro = cmGeneratorExpression::Preprocess(
+    includes, preprocessRule, this->GetImportPrefixWithSlash());
+  if (!prepro.empty()) {
+    this->ResolveTargetsInGeneratorExpressions(prepro, target);
+
+    if (!this->CheckInterfaceDirs(prepro, target, propName)) {
+      return;
+    }
+    properties[propName] = prepro;
+  }
+}
+
 void cmExportInstallFileGenerator::PopulateIncludeDirectoriesInterface(
   cmGeneratorTarget const* target,
   cmGeneratorExpression::PreprocessContext preprocessRule,
diff --git a/Source/cmExportInstallFileGenerator.h b/Source/cmExportInstallFileGenerator.h
index 738fbb7..79dff1d 100644
--- a/Source/cmExportInstallFileGenerator.h
+++ b/Source/cmExportInstallFileGenerator.h
@@ -158,6 +158,10 @@
     cmGeneratorExpression::PreprocessContext preprocessRule,
     ImportPropertyMap& properties, cmTargetExport const& te,
     std::string& includesDestinationDirs);
+  void PopulateSystemIncludeDirectoriesInterface(
+    cmGeneratorTarget const* target,
+    cmGeneratorExpression::PreprocessContext preprocessRule,
+    ImportPropertyMap& properties);
   void PopulateSourcesInterface(
     cmGeneratorTarget const* target,
     cmGeneratorExpression::PreprocessContext preprocessRule,
diff --git a/Source/cmFastbuildNormalTargetGenerator.cxx b/Source/cmFastbuildNormalTargetGenerator.cxx
index efeabae..37bee5f 100644
--- a/Source/cmFastbuildNormalTargetGenerator.cxx
+++ b/Source/cmFastbuildNormalTargetGenerator.cxx
@@ -185,7 +185,7 @@
   if (iter != compilers.end()) {
     LogMessage("Linker launcher: " + iter->first);
     outLinkerExecutable = iter->second.Executable;
-    outLinkerArgs = cmStrCat(iter->second.Args, " ", command);
+    outLinkerArgs = cmStrCat(iter->second.Args, ' ', command);
   } else {
     SplitLinkerFromArgs(command, outLinkerExecutable, outLinkerArgs);
   }
@@ -359,7 +359,7 @@
     this->GetGeneratorTarget(), "RULE_LAUNCH_LINK", Config);
   if (cmNonempty(val)) {
     LogMessage("RULE_LAUNCH_LINK: " + val);
-    command = cmStrCat(val, " ", command);
+    command = cmStrCat(val, ' ', command);
   }
 }
 
@@ -550,7 +550,7 @@
     execNode.Name = target.Name + "-def-files";
     execNode.ExecExecutable = cmSystemTools::GetCMakeCommand();
     execNode.ExecArguments =
-      cmStrCat("-E __create_def ", FASTBUILD_2_INPUT_PLACEHOLDER, " ",
+      cmStrCat("-E __create_def ", FASTBUILD_2_INPUT_PLACEHOLDER, ' ',
                FASTBUILD_1_INPUT_PLACEHOLDER);
     std::string const obj_list_file = mdi->DefFile + ".objs";
 
@@ -1492,7 +1492,7 @@
 
   for (auto& val : nodesPermutations) {
     auto& objectListNode = val.second;
-    objectListNode.Name = cmStrCat(objectListNode.Name, "_", ++groupNameCount);
+    objectListNode.Name = cmStrCat(objectListNode.Name, '_', ++groupNameCount);
     LogMessage(cmStrCat("ObjectList name: ", objectListNode.Name));
   }
   std::vector<FastbuildObjectListNode>& objects = target.ObjectListNodes;
diff --git a/Source/cmFileAPICodemodel.cxx b/Source/cmFileAPICodemodel.cxx
index c16ea28..cbb731b 100644
--- a/Source/cmFileAPICodemodel.cxx
+++ b/Source/cmFileAPICodemodel.cxx
@@ -1067,7 +1067,7 @@
     installer["destination"] = installDir->GetDestination(this->Config);
     Json::Value paths = Json::arrayValue;
     for (std::string const& dir : dirs) {
-      if (cmHasLiteralSuffix(dir, "/")) {
+      if (cmHasSuffix(dir, '/')) {
         paths.append(this->DumpInstallerPath(
           this->TopSource, dir.substr(0, dir.size() - 1), "."));
       } else {
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index 057b3fa..1f4a6f8 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -686,7 +686,6 @@
   std::vector<std::string> files;
   bool configureDepends = false;
   bool warnConfigureLate = false;
-  cmake::WorkingMode const workingMode = cm->GetWorkingMode();
   while (i != args.end()) {
     if (*i == "LIST_DIRECTORIES") {
       ++i; // skip LIST_DIRECTORIES
@@ -737,7 +736,7 @@
           "CONFIGURE_DEPENDS flag was given after a glob expression was "
           "already evaluated.");
       }
-      if (workingMode != cmake::NORMAL_MODE) {
+      if (cm->GetState()->GetRole() != cmState::Role::Project) {
         status.GetMakefile().IssueMessage(
           MessageType::FATAL_ERROR,
           "CONFIGURE_DEPENDS is invalid for script and find package modes.");
@@ -3221,8 +3220,13 @@
     return false;
   }
 
+  cmPolicies::PolicyStatus const cmp0205 =
+    status.GetMakefile().GetPolicyStatus(cmPolicies::CMP0205);
+
   // Hard link requires original file to exist.
-  if (!arguments.Symbolic && !cmSystemTools::FileExists(fileName)) {
+  if (!arguments.Symbolic &&
+      (!cmSystemTools::PathExists(fileName) ||
+       (cmp0205 != cmPolicies::NEW && !cmSystemTools::FileExists(fileName)))) {
     result = "Cannot hard link \'" + fileName + "\' as it does not exist.";
     if (!arguments.Result.empty()) {
       status.GetMakefile().AddDefinition(arguments.Result, result);
@@ -3233,20 +3237,30 @@
   }
 
   // Check if the new file already exists and remove it.
-  if (cmSystemTools::PathExists(newFileName) &&
-      !cmSystemTools::RemoveFile(newFileName)) {
-    auto err = cmStrCat("Failed to create link '", newFileName,
-                        "' because existing path cannot be removed: ",
-                        cmSystemTools::GetLastSystemError(), '\n');
-
-    if (!arguments.Result.empty()) {
-      status.GetMakefile().AddDefinition(arguments.Result, err);
-      return true;
+  if (cmSystemTools::PathExists(newFileName)) {
+    cmsys::Status rmStatus;
+    if (cmp0205 == cmPolicies::NEW &&
+        cmSystemTools::FileIsDirectory(newFileName)) {
+      rmStatus = cmSystemTools::RepeatedRemoveDirectory(newFileName);
+    } else {
+      rmStatus = cmSystemTools::RemoveFile(newFileName);
     }
-    status.SetError(err);
-    return false;
+    if (!rmStatus) {
+      std::string err = cmStrCat("Failed to create link '", newFileName,
+                                 "' because existing path cannot be removed: ",
+                                 rmStatus.GetString(), '\n');
+
+      if (!arguments.Result.empty()) {
+        status.GetMakefile().AddDefinition(arguments.Result, err);
+        return true;
+      }
+      status.SetError(err);
+      return false;
+    }
   }
 
+  bool const sourceIsDirectory = cmSystemTools::FileIsDirectory(fileName);
+
   // Whether the operation completed successfully.
   bool completed = false;
 
@@ -3261,20 +3275,54 @@
                         "': ", linked.GetString());
     }
   } else {
-    cmsys::Status linked =
-      cmSystemTools::CreateLinkQuietly(fileName, newFileName);
-    if (linked) {
-      completed = true;
-    } else {
-      result = cmStrCat("failed to create link '", newFileName,
-                        "': ", linked.GetString());
+    bool needToTry = true;
+    if (sourceIsDirectory) {
+      if (cmp0205 == cmPolicies::NEW) {
+        needToTry = false;
+      } else if (cmp0205 == cmPolicies::WARN) {
+        status.GetMakefile().IssueMessage(
+          MessageType::AUTHOR_WARNING,
+          cmStrCat("Path\n  ", fileName,
+                   "\nis directory. Hardlinks creation is not supported for "
+                   "directories.\n",
+                   cmPolicies::GetPolicyWarning(cmPolicies::CMP0205)));
+      }
     }
+
+    if (needToTry) {
+      cmsys::Status linked =
+        cmSystemTools::CreateLinkQuietly(fileName, newFileName);
+      if (linked) {
+        completed = true;
+      } else {
+        result = cmStrCat("failed to create link '", newFileName,
+                          "': ", linked.GetString());
+      }
+    } else {
+      result =
+        cmStrCat("failed to create link '", newFileName, "': not supported");
+    }
+  }
+
+  if (arguments.CopyOnError && cmp0205 == cmPolicies::WARN &&
+      sourceIsDirectory) {
+    status.GetMakefile().IssueMessage(
+      MessageType::AUTHOR_WARNING,
+      cmStrCat("Path\n  ", fileName,
+               "\nis directory. It will be copied recursively when NEW policy "
+               "behavior applies for CMP0205.\n",
+               cmPolicies::GetPolicyWarning(cmPolicies::CMP0205)));
   }
 
   // Check if copy-on-error is enabled in the arguments.
   if (!completed && arguments.CopyOnError) {
-    cmsys::Status copied =
-      cmsys::SystemTools::CopyFileAlways(fileName, newFileName);
+    cmsys::Status copied;
+    if (cmp0205 == cmPolicies::NEW && sourceIsDirectory) {
+      copied = cmsys::SystemTools::CopyADirectory(fileName, newFileName);
+    } else {
+      copied = cmsys::SystemTools::CopyFileAlways(fileName, newFileName);
+    }
+
     if (copied) {
       completed = true;
     } else {
@@ -3312,7 +3360,7 @@
     return false;
   }
 
-  if (status.GetMakefile().GetState()->GetMode() == cmState::Project) {
+  if (status.GetMakefile().GetState()->GetRole() == cmState::Role::Project) {
     status.GetMakefile().IssueMessage(
       MessageType::AUTHOR_WARNING,
       "You have used file(GET_RUNTIME_DEPENDENCIES)"
diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx
index b3ae9d7..7da364b 100644
--- a/Source/cmGeneratorExpression.cxx
+++ b/Source/cmGeneratorExpression.cxx
@@ -166,7 +166,7 @@
 }
 
 static std::string extractAllGeneratorExpressions(
-  std::string const& input,
+  cm::string_view input,
   std::map<std::string, std::vector<std::string>>* collected)
 {
   std::string result;
@@ -176,9 +176,9 @@
   std::stack<char const*> colons; // indices of ":"
   while ((pos = input.find("$<", lastPos)) != std::string::npos) {
     result += input.substr(lastPos, pos - lastPos);
-    starts.push(input.c_str() + pos);
+    starts.push(input.data() + pos);
     pos += 2;
-    char const* c = input.c_str() + pos;
+    char const* c = input.data() + pos;
     char const* const cStart = c;
     for (; *c; ++c) {
       if (cmGeneratorExpression::StartsWithGeneratorExpression(c)) {
@@ -209,7 +209,7 @@
     }
     std::string::size_type const traversed = (c - cStart) + 1;
     if (!*c) {
-      result += "$<" + input.substr(pos, traversed);
+      result += cmStrCat("$<", input.substr(pos, traversed));
     }
     pos += traversed;
     lastPos = pos;
@@ -220,7 +220,7 @@
   return cmGeneratorExpression::StripEmptyListElements(result);
 }
 
-static std::string stripAllGeneratorExpressions(std::string const& input)
+static std::string stripAllGeneratorExpressions(cm::string_view input)
 {
   return extractAllGeneratorExpressions(input, nullptr);
 }
@@ -243,7 +243,7 @@
 }
 
 static std::string stripExportInterface(
-  std::string const& input, cmGeneratorExpression::PreprocessContext context,
+  cm::string_view input, cmGeneratorExpression::PreprocessContext context,
   cm::string_view importPrefix)
 {
   std::string result;
@@ -282,7 +282,7 @@
       assert(false && "Invalid position found");
     }
     nestingLevel = 1;
-    char const* c = input.c_str() + pos;
+    char const* c = input.data() + pos;
     char const* const cStart = c;
     for (; *c; ++c) {
       if (cmGeneratorExpression::StartsWithGeneratorExpression(c)) {
@@ -300,7 +300,8 @@
           result += input.substr(pos, c - cStart);
         } else if (context == cmGeneratorExpression::InstallInterface &&
                    foundGenex == FoundGenex::InstallInterface) {
-          std::string const content = input.substr(pos, c - cStart);
+          std::string const content =
+            static_cast<std::string>(input.substr(pos, c - cStart));
           if (!importPrefix.empty()) {
             prefixItems(content, result, importPrefix);
           } else {
@@ -390,7 +391,7 @@
   }
 }
 
-std::string cmGeneratorExpression::Preprocess(std::string const& input,
+std::string cmGeneratorExpression::Preprocess(cm::string_view input,
                                               PreprocessContext context,
                                               cm::string_view importPrefix)
 {
diff --git a/Source/cmGeneratorExpression.h b/Source/cmGeneratorExpression.h
index 3897e67..a84b7ac 100644
--- a/Source/cmGeneratorExpression.h
+++ b/Source/cmGeneratorExpression.h
@@ -65,7 +65,7 @@
     InstallInterface
   };
 
-  static std::string Preprocess(std::string const& input,
+  static std::string Preprocess(cm::string_view input,
                                 PreprocessContext context,
                                 cm::string_view importPrefix = {});
 
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index 9f75f5c..d6c1d88 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -7,6 +7,7 @@
 #include <cerrno>
 #include <cstdlib>
 #include <cstring>
+#include <exception>
 #include <functional>
 #include <map>
 #include <memory>
@@ -26,6 +27,7 @@
 #include "cmsys/String.h"
 
 #include "cmCMakePath.h"
+#include "cmCMakeString.hxx"
 #include "cmComputeLinkInformation.h"
 #include "cmGenExContext.h"
 #include "cmGenExEvaluation.h"
@@ -265,9 +267,84 @@
     GeneratorExpressionContent const* /*content*/,
     cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
   {
-    return parameters.front() == parameters[1] ? "1" : "0";
+    return cm::CMakeString{ parameters.front() }.Compare(
+             cm::CMakeString::CompOperator::EQUAL, parameters[1])
+      ? "1"
+      : "0";
   }
 } strEqualNode;
+static const struct StrLessNode : public cmGeneratorExpressionNode
+{
+  StrLessNode() {} // NOLINT(modernize-use-equals-default)
+
+  int NumExpectedParameters() const override { return 2; }
+
+  std::string Evaluate(
+    std::vector<std::string> const& parameters,
+    cm::GenEx::Evaluation* /*eval*/,
+    GeneratorExpressionContent const* /*content*/,
+    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
+  {
+    return cm::CMakeString{ parameters.front() }.Compare(
+             cm::CMakeString::CompOperator::LESS, parameters[1])
+      ? "1"
+      : "0";
+  }
+} strLessNode;
+static const struct StrLessEqualNode : public cmGeneratorExpressionNode
+{
+  StrLessEqualNode() {} // NOLINT(modernize-use-equals-default)
+
+  int NumExpectedParameters() const override { return 2; }
+
+  std::string Evaluate(
+    std::vector<std::string> const& parameters,
+    cm::GenEx::Evaluation* /*eval*/,
+    GeneratorExpressionContent const* /*content*/,
+    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
+  {
+    return cm::CMakeString{ parameters.front() }.Compare(
+             cm::CMakeString::CompOperator::LESS_EQUAL, parameters[1])
+      ? "1"
+      : "0";
+  }
+} strLessEqualNode;
+static const struct StrGreaterNode : public cmGeneratorExpressionNode
+{
+  StrGreaterNode() {} // NOLINT(modernize-use-equals-default)
+
+  int NumExpectedParameters() const override { return 2; }
+
+  std::string Evaluate(
+    std::vector<std::string> const& parameters,
+    cm::GenEx::Evaluation* /*eval*/,
+    GeneratorExpressionContent const* /*content*/,
+    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
+  {
+    return cm::CMakeString{ parameters.front() }.Compare(
+             cm::CMakeString::CompOperator::GREATER, parameters[1])
+      ? "1"
+      : "0";
+  }
+} strGreaterNode;
+static const struct StrGreaterEqualNode : public cmGeneratorExpressionNode
+{
+  StrGreaterEqualNode() {} // NOLINT(modernize-use-equals-default)
+
+  int NumExpectedParameters() const override { return 2; }
+
+  std::string Evaluate(
+    std::vector<std::string> const& parameters,
+    cm::GenEx::Evaluation* /*eval*/,
+    GeneratorExpressionContent const* /*content*/,
+    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
+  {
+    return cm::CMakeString{ parameters.front() }.Compare(
+             cm::CMakeString::CompOperator::GREATER_EQUAL, parameters[1])
+      ? "1"
+      : "0";
+  }
+} strGreaterEqualNode;
 
 static const struct EqualNode : public cmGeneratorExpressionNode
 {
@@ -706,6 +783,55 @@
   return true;
 };
 
+template <typename IndexType>
+bool GetNumericArgument(std::string const& arg, IndexType& value)
+{
+  try {
+    std::size_t pos;
+
+    if (sizeof(IndexType) == sizeof(long)) {
+      value = std::stol(arg, &pos);
+    } else {
+      value = std::stoll(arg, &pos);
+    }
+
+    if (pos != arg.length()) {
+      // this is not a number
+      return false;
+    }
+  } catch (std::invalid_argument const&) {
+    return false;
+  }
+
+  return true;
+}
+
+template <typename IndexType>
+bool GetNumericArguments(
+  cm::GenEx::Evaluation* eval, GeneratorExpressionContent const* cnt,
+  Arguments args, std::vector<IndexType>& indexes,
+  cmList::ExpandElements expandElements = cmList::ExpandElements::No)
+{
+  using IndexRange = cmRange<Arguments::const_iterator>;
+  IndexRange arguments(args.begin(), args.end());
+  cmList list;
+  if (expandElements == cmList::ExpandElements::Yes) {
+    list = cmList{ args.begin(), args.end(), expandElements };
+    arguments = IndexRange{ list.begin(), list.end() };
+  }
+
+  for (auto const& value : arguments) {
+    IndexType index;
+    if (!GetNumericArgument(value, index)) {
+      reportError(eval, cnt->GetOriginalExpression(),
+                  cmStrCat("index: \"", value, "\" is not a valid index"));
+      return false;
+    }
+    indexes.push_back(index);
+  }
+  return true;
+}
+
 bool CheckPathParametersEx(cm::GenEx::Evaluation* eval,
                            GeneratorExpressionContent const* cnt,
                            cm::string_view option, std::size_t count,
@@ -1163,6 +1289,553 @@
 } pathEqualNode;
 
 namespace {
+inline bool CheckStringParametersEx(cm::GenEx::Evaluation* eval,
+                                    GeneratorExpressionContent const* cnt,
+                                    cm::string_view option, std::size_t count,
+                                    int required = 1, bool exactly = true)
+{
+  return CheckGenExParameters(eval, cnt, "STRING"_s, option, count, required,
+                              exactly);
+}
+inline bool CheckStringParameters(cm::GenEx::Evaluation* eval,
+                                  GeneratorExpressionContent const* cnt,
+                                  cm::string_view option, Arguments args,
+                                  int required = 1)
+{
+  return CheckStringParametersEx(eval, cnt, option, args.size(), required);
+};
+}
+
+static const struct StringNode : public cmGeneratorExpressionNode
+{
+  StringNode() {} // NOLINT(modernize-use-equals-default)
+
+  int NumExpectedParameters() const override { return OneOrMoreParameters; }
+
+  bool AcceptsArbitraryContentParameter() const override { return true; }
+
+  std::string Evaluate(
+    std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
+    GeneratorExpressionContent const* content,
+    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
+  {
+    static std::unordered_map<
+      cm::string_view,
+      std::function<std::string(cm::GenEx::Evaluation*,
+                                GeneratorExpressionContent const*,
+                                Arguments&)>>
+      stringCommands{
+        { "LENGTH"_s,
+          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
+             Arguments& args) -> std::string {
+            if (CheckStringParameters(ev, cnt, "LENGTH"_s, args)) {
+              return std::to_string(cm::CMakeString{ args.front() }.Length());
+            }
+            return std::string{};
+          } },
+        { "SUBSTRING"_s,
+          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
+             Arguments& args) -> std::string {
+            if (CheckStringParameters(ev, cnt, "SUBSTRING"_s, args, 3)) {
+              cm::CMakeString str{ args.front() };
+              std::vector<long> indexes;
+              if (GetNumericArguments(ev, cnt, args.advance(1), indexes)) {
+                try {
+                  return str.Substring(indexes.front(), indexes.back());
+                } catch (std::out_of_range const& e) {
+                  reportError(ev, cnt->GetOriginalExpression(), e.what());
+                  return std::string{};
+                }
+              }
+            }
+            return std::string{};
+          } },
+        { "FIND"_s,
+          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
+             Arguments& args) -> std::string {
+            if (CheckStringParametersEx(ev, cnt, "FIND"_s, args.size(), 2,
+                                        false)) {
+              if (args.size() > 3) {
+                reportError(ev, cnt->GetOriginalExpression(),
+                            "$<STRING:FIND> expression expects at "
+                            "most three parameters.");
+                return std::string{};
+              }
+
+              auto const FROM = "FROM:"_s;
+
+              cm::CMakeString str{ args.front() };
+              cm::CMakeString::FindFrom from =
+                cm::CMakeString::FindFrom::Begin;
+              cm::string_view substring;
+
+              args.advance(1);
+              if (args.size() == 2) {
+                cm::CMakeString::FindFrom opt =
+                  static_cast<cm::CMakeString::FindFrom>(-1);
+
+                for (auto const& arg : args) {
+                  if (cmHasPrefix(arg, FROM)) {
+                    if (arg != "FROM:BEGIN"_s && arg != "FROM:END"_s) {
+                      reportError(
+                        ev, cnt->GetOriginalExpression(),
+                        cmStrCat("Invalid value for '", FROM,
+                                 "' option. 'BEGIN' or 'END' expected."));
+                      return std::string{};
+                    }
+                    opt = arg == "FROM:BEGIN"_s
+                      ? cm::CMakeString::FindFrom::Begin
+                      : cm::CMakeString::FindFrom::End;
+                  } else {
+                    substring = arg;
+                  }
+                }
+                if (opt == static_cast<cm::CMakeString::FindFrom>(-1)) {
+                  reportError(
+                    ev, cnt->GetOriginalExpression(),
+                    cmStrCat("Expected option '", FROM, "' is missing."));
+                  return std::string{};
+                }
+                from = opt;
+              } else {
+                substring = args.front();
+              }
+              auto pos = str.Find(substring, from);
+              return pos == cm::CMakeString::npos ? "-1" : std::to_string(pos);
+            }
+            return std::string{};
+          } },
+        { "MATCH"_s,
+          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
+             Arguments& args) -> std::string {
+            if (CheckStringParametersEx(ev, cnt, "MATCH"_s, args.size(), 2,
+                                        false)) {
+              if (args.size() > 3) {
+                reportError(ev, cnt->GetOriginalExpression(),
+                            "$<STRING:MATCH> expression expects at "
+                            "most three parameters.");
+                return std::string{};
+              }
+
+              auto const SEEK = "SEEK:"_s;
+
+              cm::CMakeString str{ args.front() };
+              cm::CMakeString::MatchItems seek =
+                cm::CMakeString::MatchItems::Once;
+              auto const* regex = &args[1];
+
+              args.advance(1);
+              if (args.size() == 2) {
+                cm::CMakeString::MatchItems opt =
+                  static_cast<cm::CMakeString::MatchItems>(-1);
+
+                for (auto const& arg : args) {
+                  if (cmHasPrefix(arg, SEEK)) {
+                    if (arg != "SEEK:ONCE"_s && arg != "SEEK:ALL"_s) {
+                      reportError(
+                        ev, cnt->GetOriginalExpression(),
+                        cmStrCat("Invalid value for '", SEEK,
+                                 "' option. 'ONCE' or 'ALL' expected."));
+                      return std::string{};
+                    }
+                    opt = arg == "SEEK:ONCE"_s
+                      ? cm::CMakeString::MatchItems::Once
+                      : cm::CMakeString::MatchItems::All;
+                  } else {
+                    regex = &arg;
+                  }
+                }
+                if (opt == static_cast<cm::CMakeString::MatchItems>(-1)) {
+                  reportError(
+                    ev, cnt->GetOriginalExpression(),
+                    cmStrCat("Expected option '", SEEK, "' is missing."));
+                  return std::string{};
+                }
+                seek = opt;
+              }
+
+              try {
+                return str.Match(*regex, seek).to_string();
+              } catch (std::invalid_argument const& e) {
+                reportError(ev, cnt->GetOriginalExpression(), e.what());
+                return std::string{};
+              }
+            }
+            return std::string{};
+          } },
+        { "JOIN"_s,
+          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
+             Arguments& args) -> std::string {
+            if (CheckStringParametersEx(ev, cnt, "JOIN"_s, args.size(), 2,
+                                        false)) {
+              auto const& glue = args.front();
+              return cm::CMakeString{ args.advance(1), glue };
+            }
+            return std::string{};
+          } },
+        { "ASCII"_s,
+          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
+             Arguments& args) -> std::string {
+            if (CheckStringParametersEx(ev, cnt, "ASCII"_s, args.size(), 1,
+                                        false)) {
+              try {
+                return cm::CMakeString{}.FromASCII(args);
+              } catch (std::invalid_argument const& e) {
+                reportError(ev, cnt->GetOriginalExpression(), e.what());
+                return std::string{};
+              }
+            }
+            return std::string{};
+          } },
+        { "TIMESTAMP"_s,
+          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
+             Arguments& args) -> std::string {
+            cm::string_view format;
+            cm::CMakeString::UTC utc = cm::CMakeString::UTC::No;
+
+            if (args.size() == 2 && args.front() != "UTC"_s &&
+                args.back() != "UTC"_s) {
+              reportError(ev, cnt->GetOriginalExpression(),
+                          "'UTC' option is expected.");
+              return std::string{};
+            }
+            if (args.size() > 2) {
+              reportError(ev, cnt->GetOriginalExpression(),
+                          "$<STRING:TIMESTAMP> expression expects at most two "
+                          "parameters.");
+              return std::string{};
+            }
+
+            for (auto const& arg : args) {
+              if (arg == "UTC"_s) {
+                utc = cm::CMakeString::UTC::Yes;
+              } else {
+                format = arg;
+              }
+            }
+            return cm::CMakeString{}.Timestamp(format, utc);
+          } },
+        { "RANDOM"_s,
+          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
+             Arguments& args) -> std::string {
+            auto const ALPHABET = "ALPHABET:"_s;
+            auto const LENGTH = "LENGTH:"_s;
+            auto const RANDOM_SEED = "RANDOM_SEED:"_s;
+
+            if (args.size() > 3) {
+              reportError(ev, cnt->GetOriginalExpression(),
+                          "$<STRING:RANDOM> expression expects at most three "
+                          "parameters.");
+              return std::string{};
+            }
+
+            cm::string_view alphabet;
+            std::size_t length = 5;
+            bool seed_specified = false;
+            unsigned int seed = 0;
+            for (auto const& arg : args) {
+              if (cmHasPrefix(arg, ALPHABET)) {
+                alphabet = cm::string_view{ arg.c_str() + ALPHABET.length() };
+                continue;
+              }
+              if (cmHasPrefix(arg, LENGTH)) {
+                try {
+                  length = std::stoul(arg.substr(LENGTH.size()));
+                } catch (std::exception const&) {
+                  reportError(ev, cnt->GetOriginalExpression(),
+                              cmStrCat(arg, ": invalid numeric value for '",
+                                       LENGTH, "' option."));
+                  return std::string{};
+                }
+                continue;
+              }
+              if (cmHasPrefix(arg, RANDOM_SEED)) {
+                try {
+                  seed_specified = true;
+                  seed = static_cast<unsigned int>(
+                    std::stoul(arg.substr(RANDOM_SEED.size())));
+                } catch (std::exception const&) {
+                  reportError(ev, cnt->GetOriginalExpression(),
+                              cmStrCat(arg, ": invalid numeric value for '",
+                                       RANDOM_SEED, "' option."));
+                  return std::string{};
+                }
+                continue;
+              }
+              reportError(ev, cnt->GetOriginalExpression(),
+                          cmStrCat(arg, ": invalid parameter."));
+              return std::string{};
+            }
+
+            try {
+              if (seed_specified) {
+                return cm::CMakeString{}.Random(seed, length, alphabet);
+              }
+              return cm::CMakeString{}.Random(length, alphabet);
+            } catch (std::exception const& e) {
+              reportError(ev, cnt->GetOriginalExpression(), e.what());
+              return std::string{};
+            }
+          } },
+        { "UUID"_s,
+          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
+             Arguments& args) -> std::string {
+            if (CheckStringParametersEx(ev, cnt, "UUID"_s, args.size(), 2,
+                                        false)) {
+              auto const NAMESPACE = "NAMESPACE:"_s;
+              auto const NAME = "NAME:"_s;
+              auto const TYPE = "TYPE:"_s;
+              auto const CASE = "CASE:"_s;
+
+              if (args.size() > 4) {
+                reportError(ev, cnt->GetOriginalExpression(),
+                            "$<STRING:UUID> expression expects at most four "
+                            "parameters.");
+                return std::string{};
+              }
+
+              cm::string_view nameSpace;
+              cm::string_view name;
+              cm::CMakeString::UUIDType type =
+                static_cast<cm::CMakeString::UUIDType>(-1);
+              cm::CMakeString::Case uuidCase = cm::CMakeString::Case::Lower;
+              for (auto const& arg : args) {
+                if (cmHasPrefix(arg, NAMESPACE)) {
+                  nameSpace =
+                    cm::string_view{ arg.c_str() + NAMESPACE.length() };
+                  if (nameSpace.empty()) {
+                    reportError(
+                      ev, cnt->GetOriginalExpression(),
+                      cmStrCat("Invalid value for '", NAMESPACE, "' option."));
+                    return std::string{};
+                  }
+                  continue;
+                }
+                if (cmHasPrefix(arg, NAME)) {
+                  name = cm::string_view{ arg.c_str() + NAME.length() };
+                  continue;
+                }
+                if (cmHasPrefix(arg, TYPE)) {
+                  auto value = cm::string_view{ arg.c_str() + TYPE.length() };
+                  if (value != "MD5"_s && value != "SHA1"_s) {
+                    reportError(
+                      ev, cnt->GetOriginalExpression(),
+                      cmStrCat("Invalid value for '", TYPE,
+                               "' option. 'MD5' or 'SHA1' expected."));
+                    return std::string{};
+                  }
+                  type = value == "MD5"_s ? cm::CMakeString::UUIDType::MD5
+                                          : cm::CMakeString::UUIDType::SHA1;
+                  continue;
+                }
+                if (cmHasPrefix(arg, CASE)) {
+                  auto value = cm::string_view{ arg.c_str() + CASE.length() };
+                  if (value != "UPPER"_s && value != "LOWER"_s) {
+                    reportError(
+                      ev, cnt->GetOriginalExpression(),
+                      cmStrCat("Invalid value for '", CASE,
+                               "' option. 'UPPER' or 'LOWER' expected."));
+                    return std::string{};
+                  }
+                  uuidCase = value == "UPPER"_s ? cm::CMakeString::Case::Upper
+                                                : cm::CMakeString::Case::Lower;
+                  continue;
+                }
+                reportError(ev, cnt->GetOriginalExpression(),
+                            cmStrCat(arg, ": invalid parameter."));
+                return std::string{};
+              }
+              if (nameSpace.empty()) {
+                reportError(
+                  ev, cnt->GetOriginalExpression(),
+                  cmStrCat("Required option '", NAMESPACE, "' is missing."));
+                return std::string{};
+              }
+              if (type == static_cast<cm::CMakeString::UUIDType>(-1)) {
+                reportError(
+                  ev, cnt->GetOriginalExpression(),
+                  cmStrCat("Required option '", TYPE, "' is missing."));
+                return std::string{};
+              }
+
+              try {
+                return cm::CMakeString{}.UUID(nameSpace, name, type, uuidCase);
+              } catch (std::exception const& e) {
+                reportError(ev, cnt->GetOriginalExpression(), e.what());
+                return std::string{};
+              }
+            }
+            return std::string{};
+          } },
+        { "REPLACE"_s,
+          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
+             Arguments& args) -> std::string {
+            if (CheckStringParametersEx(ev, cnt, "REPLACE"_s, args.size(), 3,
+                                        false)) {
+              if (args.size() > 4) {
+                reportError(ev, cnt->GetOriginalExpression(),
+                            "$<STRING:REPLACE> expression expects at "
+                            "most four parameters.");
+                return std::string{};
+              }
+
+              cm::CMakeString::Regex isRegex = cm::CMakeString::Regex::No;
+              if (args.size() == 4) {
+                cm::string_view type = args.front();
+                if (type != "STRING"_s && type != "REGEX"_s) {
+                  reportError(
+                    ev, cnt->GetOriginalExpression(),
+                    cmStrCat(
+                      '\'', type,
+                      "' is unexpected. 'STRING' or 'REGEX' expected."));
+                  return std::string{};
+                }
+                isRegex = type == "STRING"_s ? cm::CMakeString::Regex::No
+                                             : cm::CMakeString::Regex::Yes;
+                args.advance(1);
+              }
+
+              try {
+                return cm::CMakeString{ args.front() }.Replace(
+                  args[1], args[2], isRegex);
+              } catch (std::invalid_argument const& e) {
+                reportError(ev, cnt->GetOriginalExpression(), e.what());
+                return std::string{};
+              }
+            }
+            return std::string{};
+          } },
+        { "APPEND"_s,
+          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
+             Arguments& args) -> std::string {
+            if (CheckStringParametersEx(ev, cnt, "APPEND"_s, args.size(), 2,
+                                        false)) {
+              cm::CMakeString data{ args.front() };
+              return data.Append(args.advance(1));
+            }
+            return std::string{};
+          } },
+        { "PREPEND"_s,
+          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
+             Arguments& args) -> std::string {
+            if (CheckStringParametersEx(ev, cnt, "PREPEND "_s, args.size(), 2,
+                                        false)) {
+              cm::CMakeString data{ args.front() };
+              return data.Prepend(args.advance(1));
+            }
+            return std::string{};
+          } },
+        { "TOLOWER"_s,
+          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
+             Arguments& args) -> std::string {
+            if (CheckStringParameters(ev, cnt, "TOLOWER"_s, args, 1)) {
+              return cm::CMakeString{}.ToLower(args.front());
+            }
+            return std::string{};
+          } },
+        { "TOUPPER"_s,
+          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
+             Arguments& args) -> std::string {
+            if (CheckStringParameters(ev, cnt, "TOUPPER"_s, args, 1)) {
+              return cm::CMakeString{}.ToUpper(args.front());
+            }
+            return std::string{};
+          } },
+        { "STRIP"_s,
+          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
+             Arguments& args) -> std::string {
+            if (CheckStringParameters(ev, cnt, "STRIP"_s, args, 2)) {
+              if (args.front() != "SPACES"_s) {
+                reportError(ev, cnt->GetOriginalExpression(),
+                            cmStrCat('\'', args.front(),
+                                     "' is unexpected. 'SPACES' expected."));
+                return std::string{};
+              }
+
+              return cm::CMakeString{ args[1] }.Strip();
+            }
+            return std::string{};
+          } },
+        { "QUOTE"_s,
+          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
+             Arguments& args) -> std::string {
+            if (CheckStringParameters(ev, cnt, "QUOTE"_s, args, 2)) {
+              if (args.front() != "REGEX"_s) {
+                reportError(ev, cnt->GetOriginalExpression(),
+                            cmStrCat('\'', args.front(),
+                                     "' is unexpected. 'REGEX' expected."));
+                return std::string{};
+              }
+
+              return cm::CMakeString{ args[1] }.Quote();
+            }
+            return std::string{};
+          } },
+        { "HEX"_s,
+          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
+             Arguments& args) -> std::string {
+            if (CheckStringParameters(ev, cnt, "HEX"_s, args, 1)) {
+              return cm::CMakeString{ args.front() }.ToHexadecimal();
+            }
+            return std::string{};
+          } },
+        { "HASH"_s,
+          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
+             Arguments& args) -> std::string {
+            if (CheckStringParameters(ev, cnt, "HASH"_s, args, 2)) {
+              auto const ALGORITHM = "ALGORITHM:"_s;
+
+              if (cmHasPrefix(args[1], ALGORITHM)) {
+                try {
+                  auto const algo =
+                    cm::string_view{ args[1].c_str() + ALGORITHM.length() };
+                  if (algo.empty()) {
+                    reportError(
+                      ev, cnt->GetOriginalExpression(),
+                      cmStrCat("Missing value for '", ALGORITHM, "' option."));
+                    return std::string{};
+                  }
+                  return cm::CMakeString{ args.front() }.Hash(algo);
+                } catch (std::exception const& e) {
+                  reportError(ev, cnt->GetOriginalExpression(), e.what());
+                  return std::string{};
+                }
+              }
+              reportError(ev, cnt->GetOriginalExpression(),
+                          cmStrCat(args[1], ": invalid parameter. Option '",
+                                   ALGORITHM, "' expected."));
+            }
+            return std::string{};
+          } },
+        { "MAKE_C_IDENTIFIER"_s,
+          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
+             Arguments& args) -> std::string {
+            if (CheckStringParameters(ev, cnt, "MAKE_C_IDENTIFIER"_s, args,
+                                      1)) {
+              return cm::CMakeString{ args.front() }.MakeCIdentifier();
+            }
+            return std::string{};
+          } }
+      };
+
+    if (parameters.front().empty()) {
+      reportError(eval, content->GetOriginalExpression(),
+                  "$<STRING> expression requires at least one parameter.");
+      return std::string{};
+    }
+
+    if (cm::contains(stringCommands, parameters.front())) {
+      auto args = Arguments{ parameters }.advance(1);
+      return stringCommands[parameters.front()](eval, content, args);
+    }
+
+    reportError(eval, content->GetOriginalExpression(),
+                cmStrCat(parameters.front(), ": invalid option."));
+    return std::string{};
+  }
+} stringNode;
+
+namespace {
 inline bool CheckListParametersEx(cm::GenEx::Evaluation* eval,
                                   GeneratorExpressionContent const* cnt,
                                   cm::string_view option, std::size_t count,
@@ -1183,53 +1856,6 @@
 {
   return list.empty() ? cmList{} : cmList{ list, cmList::EmptyElements::Yes };
 }
-
-bool GetNumericArgument(std::string const& arg, cmList::index_type& value)
-{
-  try {
-    std::size_t pos;
-
-    if (sizeof(cmList::index_type) == sizeof(long)) {
-      value = std::stol(arg, &pos);
-    } else {
-      value = std::stoll(arg, &pos);
-    }
-
-    if (pos != arg.length()) {
-      // this is not a number
-      return false;
-    }
-  } catch (std::invalid_argument const&) {
-    return false;
-  }
-
-  return true;
-}
-
-bool GetNumericArguments(
-  cm::GenEx::Evaluation* eval, GeneratorExpressionContent const* cnt,
-  Arguments args, std::vector<cmList::index_type>& indexes,
-  cmList::ExpandElements expandElements = cmList::ExpandElements::No)
-{
-  using IndexRange = cmRange<Arguments::const_iterator>;
-  IndexRange arguments(args.begin(), args.end());
-  cmList list;
-  if (expandElements == cmList::ExpandElements::Yes) {
-    list = cmList{ args.begin(), args.end(), expandElements };
-    arguments = IndexRange{ list.begin(), list.end() };
-  }
-
-  for (auto const& value : arguments) {
-    cmList::index_type index;
-    if (!GetNumericArgument(value, index)) {
-      reportError(eval, cnt->GetOriginalExpression(),
-                  cmStrCat("index: \"", value, "\" is not a valid index"));
-      return false;
-    }
-    indexes.push_back(index);
-  }
-  return true;
-}
 }
 
 static const struct ListNode : public cmGeneratorExpressionNode
@@ -4427,7 +5053,8 @@
         postfix != Postfix::Unspecified) {
       eval->Context.LG->GetCMakeInstance()->IssueMessage(
         MessageType::AUTHOR_WARNING,
-        cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0202), '\n',
+        cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0202),
+                 "\n"
                  "\"POSTFIX\" option is recognized only when the policy is "
                  "set to NEW. Since the policy is not set, the OLD behavior "
                  "will be used."),
@@ -4872,6 +5499,11 @@
     { "TARGET_BUNDLE_DIR_NAME", &targetBundleDirNameNode },
     { "TARGET_BUNDLE_CONTENT_DIR", &targetBundleContentDirNode },
     { "STREQUAL", &strEqualNode },
+    { "STRLESS", &strLessNode },
+    { "STRLESS_EQUAL", &strLessEqualNode },
+    { "STRGREATER", &strGreaterNode },
+    { "STRGREATER_EQUAL", &strGreaterEqualNode },
+    { "STRING", &stringNode },
     { "EQUAL", &equalNode },
     { "IN_LIST", &inListNode },
     { "FILTER", &filterNode },
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 3ff37b8..74eca71 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -22,6 +22,7 @@
 #include "cmAlgorithms.h"
 #include "cmComputeLinkInformation.h" // IWYU pragma: keep
 #include "cmCryptoHash.h"
+#include "cmCxxModuleMetadata.h"
 #include "cmCxxModuleUsageEffects.h"
 #include "cmExperimental.h"
 #include "cmFileSet.h"
@@ -5126,6 +5127,70 @@
   return cm::contains(this->LinkImplicitNullProperties, p);
 }
 
+namespace {
+bool CreateCxxStdlibTarget(cmMakefile* makefile, cmLocalGenerator* lg,
+                           std::string const& targetName,
+                           std::string const& cxxTargetName,
+                           std::string const& stdLevel,
+                           std::vector<std::string> const& configs)
+{
+#ifndef CMAKE_BOOTSTRAP
+
+  static cm::optional<cmCxxModuleMetadata> metadata;
+
+  // Load metadata only when we need to create a target
+  if (!metadata) {
+    auto errorMessage =
+      makefile->GetDefinition("CMAKE_CXX_COMPILER_IMPORT_STD_ERROR_MESSAGE");
+    if (!errorMessage.IsEmpty()) {
+      makefile->IssueMessage(
+        MessageType::FATAL_ERROR,
+        cmStrCat(R"(The "CXX_MODULE_STD" property on target ")", targetName,
+                 "\" requires toolchain support, but it was not provided.  "
+                 "Reason:\n  ",
+                 *errorMessage));
+      return false;
+    }
+
+    auto metadataPath =
+      makefile->GetDefinition("CMAKE_CXX_STDLIB_MODULES_JSON");
+    if (metadataPath.IsEmpty()) {
+      makefile->IssueMessage(
+        MessageType::FATAL_ERROR,
+        cmStrCat(
+          R"("The "CXX_MODULE_STD" property on target ")", targetName,
+          "\" requires CMAKE_CXX_STDLIB_MODULES_JSON be set, but it was not "
+          "provided by the toolchain."));
+      return false;
+    }
+
+    auto parseResult = cmCxxModuleMetadata::LoadFromFile(*metadataPath);
+    if (!parseResult) {
+      makefile->IssueMessage(
+        MessageType::FATAL_ERROR,
+        cmStrCat("Failed to load C++ standard library modules metadata "
+                 "from \"",
+                 *metadataPath, "\": ", parseResult.Error));
+      return false;
+    }
+
+    metadata = std::move(*parseResult.Meta);
+  }
+
+  auto* stdlibTgt = makefile->AddImportedTarget(
+    cxxTargetName, cmStateEnums::INTERFACE_LIBRARY, true);
+  cmCxxModuleMetadata::PopulateTarget(*stdlibTgt, *metadata, configs);
+  stdlibTgt->AppendProperty("IMPORTED_CXX_MODULES_COMPILE_FEATURES",
+                            cmStrCat("cxx_std_", stdLevel));
+
+  lg->AddGeneratorTarget(cm::make_unique<cmGeneratorTarget>(stdlibTgt, lg));
+
+#endif // CMAKE_BOOTSTRAP
+
+  return true;
+}
+} // namespace
+
 bool cmGeneratorTarget::ApplyCXXStdTargets()
 {
   cmStandardLevelResolver standardResolver(this->Makefile);
@@ -5207,35 +5272,33 @@
 
     auto const stdLevel =
       standardResolver.GetLevelString("CXX", *explicitLevel);
-    auto const targetName = cmStrCat("__CMAKE::CXX", stdLevel);
-    if (!this->Makefile->FindTargetToUse(targetName)) {
-      auto basicReason = this->Makefile->GetDefinition(cmStrCat(
-        "CMAKE_CXX", stdLevel, "_COMPILER_IMPORT_STD_NOT_FOUND_MESSAGE"));
-      std::string reason;
-      if (!basicReason.IsEmpty()) {
-        reason = cmStrCat("  Reason:\n  ", basicReason);
-      }
-      this->Makefile->IssueMessage(
-        MessageType::FATAL_ERROR,
-        cmStrCat(R"(The "CXX_MODULE_STD" property on the target ")",
-                 this->GetName(), "\" requires that the \"", targetName,
-                 "\" target exist, but it was not provided by the toolchain.",
-                 reason));
-      break;
-    }
+    auto const cxxTargetName = cmStrCat("__CMAKE::CXX", stdLevel);
 
-    // Check the experimental feature here as well. A toolchain may have
-    // provided the target and skipped the check in the toolchain preparation
-    // logic.
-    if (!cmExperimental::HasSupportEnabled(
-          *this->Makefile, cmExperimental::Feature::CxxImportStd)) {
-      break;
+    // Create the __CMAKE::CXX## IMPORTED interface target if it doesn't
+    // already exist
+    if (!this->Makefile->FindTargetToUse(cxxTargetName) &&
+        !CreateCxxStdlibTarget(this->Makefile, this->LocalGenerator,
+                               this->GetName(), cxxTargetName, stdLevel,
+                               configs)) {
+      return false;
     }
 
     this->Target->AppendProperty(
       "LINK_LIBRARIES",
-      cmStrCat("$<BUILD_LOCAL_INTERFACE:$<$<CONFIG:", config, ">:", targetName,
-               ">>"));
+      cmStrCat("$<BUILD_LOCAL_INTERFACE:$<$<CONFIG:", config,
+               ">:", cxxTargetName, ">>"));
+  }
+
+  // Check the experimental feature here. A toolchain may have
+  // skipped the check in the toolchain preparation logic.
+  if (!cmExperimental::HasSupportEnabled(
+        *this->Makefile, cmExperimental::Feature::CxxImportStd)) {
+    this->Makefile->IssueMessage(
+      MessageType::FATAL_ERROR,
+      "Experimental `import std` support not enabled when detecting "
+      "toolchain; it must be set before `CXX` is enabled (usually a "
+      "`project()` call).");
+    return false;
   }
 
   return true;
@@ -5335,7 +5398,9 @@
         }
         // See `cmGlobalGenerator::ApplyCXXStdTargets` in
         // `cmGlobalGenerator::Compute` for non-synthetic target resolutions.
-        gtp->ApplyCXXStdTargets();
+        if (!gtp->ApplyCXXStdTargets()) {
+          return false;
+        }
 
         gtp->DiscoverSyntheticTargets(cache, config);
 
diff --git a/Source/cmGlobalFastbuildGenerator.cxx b/Source/cmGlobalFastbuildGenerator.cxx
index 7b613c7..157e9de 100644
--- a/Source/cmGlobalFastbuildGenerator.cxx
+++ b/Source/cmGlobalFastbuildGenerator.cxx
@@ -1631,7 +1631,7 @@
         folderName,
         { { "Path", Quote(pathToFolder) },
           { "Projects",
-            cmStrCat("{", cmJoin(Wrap(projectsInFolder), ","), "}") } },
+            cmStrCat('{', cmJoin(Wrap(projectsInFolder), ","), '}') } },
         1);
       folders.emplace_back(std::move(folderName));
     }
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index 4c40e93..34f4d07 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -1185,7 +1185,7 @@
     std::string outputExtension = *p;
     this->LanguageToOutputExtension[l] = outputExtension;
     this->OutputExtensions[outputExtension] = outputExtension;
-    if (cmHasPrefix(outputExtension, ".")) {
+    if (cmHasPrefix(outputExtension, '.')) {
       outputExtension = outputExtension.substr(1);
       this->OutputExtensions[outputExtension] = outputExtension;
     }
@@ -1787,7 +1787,17 @@
 bool cmGlobalGenerator::ApplyCXXStdTargets()
 {
   for (auto const& gen : this->LocalGenerators) {
-    for (auto const& tgt : gen->GetGeneratorTargets()) {
+
+    // tgt->ApplyCXXStd can create targets itself, so we need iterators which
+    // won't be invalidated by that target creation
+    auto const& genTgts = gen->GetGeneratorTargets();
+    std::vector<cmGeneratorTarget*> existingTgts;
+    existingTgts.reserve(genTgts.size());
+    for (auto const& tgt : genTgts) {
+      existingTgts.push_back(tgt.get());
+    }
+
+    for (auto const& tgt : existingTgts) {
       if (!tgt->ApplyCXXStdTargets()) {
         return false;
       }
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index ff4dbc6..46bb45e 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -2511,7 +2511,7 @@
     }
 
     dir_top_bld = tdi["dir-top-bld"].asString();
-    if (!dir_top_bld.empty() && !cmHasLiteralSuffix(dir_top_bld, "/")) {
+    if (!dir_top_bld.empty() && !cmHasSuffix(dir_top_bld, '/')) {
       dir_top_bld += '/';
     }
 
@@ -2524,7 +2524,7 @@
 
     Json::Value const& tdi_module_dir = tdi["module-dir"];
     module_dir = tdi_module_dir.asString();
-    if (!module_dir.empty() && !cmHasLiteralSuffix(module_dir, "/")) {
+    if (!module_dir.empty() && !cmHasSuffix(module_dir, '/')) {
       module_dir += '/';
     }
 
@@ -2993,11 +2993,35 @@
   }
 
   std::string const dir_cur_bld = tdi["dir-cur-bld"].asString();
+  if (!cmSystemTools::FileIsFullPath(dir_cur_bld)) {
+    cmSystemTools::Error(
+      "-E cmake_ninja_dyndep --tdi= file has no absolute dir-cur-bld");
+    return 1;
+  }
+
   std::string const dir_cur_src = tdi["dir-cur-src"].asString();
+  if (!cmSystemTools::FileIsFullPath(dir_cur_src)) {
+    cmSystemTools::Error(
+      "-E cmake_ninja_dyndep --tdi= file has no absolute dir-cur-src");
+    return 1;
+  }
+
   std::string const dir_top_bld = tdi["dir-top-bld"].asString();
+  if (!cmSystemTools::FileIsFullPath(dir_top_bld)) {
+    cmSystemTools::Error(
+      "-E cmake_ninja_dyndep --tdi= file has no absolute dir-top-bld");
+    return 1;
+  }
+
   std::string const dir_top_src = tdi["dir-top-src"].asString();
+  if (!cmSystemTools::FileIsFullPath(dir_top_src)) {
+    cmSystemTools::Error(
+      "-E cmake_ninja_dyndep --tdi= file has no absolute dir-top-src");
+    return 1;
+  }
+
   std::string module_dir = tdi["module-dir"].asString();
-  if (!module_dir.empty() && !cmHasLiteralSuffix(module_dir, "/")) {
+  if (!module_dir.empty() && !cmHasSuffix(module_dir, '/')) {
     module_dir += '/';
   }
   std::vector<std::string> linked_target_dirs;
@@ -3024,7 +3048,7 @@
 
   auto export_info = cmDyndepCollation::ParseExportInfo(tdi);
 
-  cmake cm(cmake::RoleInternal, cmState::Unknown);
+  cmake cm(cmState::Role::Internal);
   cm.SetHomeDirectory(dir_top_src);
   cm.SetHomeOutputDirectory(dir_top_bld);
   auto ggd = cm.CreateGlobalGenerator("Ninja");
diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx
index 39086f7..759806f 100644
--- a/Source/cmGlobalVisualStudioGenerator.cxx
+++ b/Source/cmGlobalVisualStudioGenerator.cxx
@@ -998,7 +998,7 @@
         root->MaybeRelativeToCurBinDir(lg->GetCurrentBinaryDirectory());
       if (dir == "."_s) {
         dir.clear();
-      } else if (!cmHasLiteralSuffix(dir, "/")) {
+      } else if (!cmHasSuffix(dir, '/')) {
         dir += "/";
       }
 
diff --git a/Source/cmGraphVizWriter.cxx b/Source/cmGraphVizWriter.cxx
index 65036fd..25bca40 100644
--- a/Source/cmGraphVizWriter.cxx
+++ b/Source/cmGraphVizWriter.cxx
@@ -197,9 +197,7 @@
   std::string const& settingsFileName,
   std::string const& fallbackSettingsFileName)
 {
-  cmake cm(cmake::RoleScript, cmState::Unknown);
-  cm.SetHomeDirectory("");
-  cm.SetHomeOutputDirectory("");
+  cmake cm(cmState::Role::Script);
   cm.GetCurrentSnapshot().SetDefaultDefinitions();
   cmGlobalGenerator ggi(&cm);
   cmMakefile mf(&ggi, cm.GetCurrentSnapshot());
diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx
index e66fa8a..47654b9 100644
--- a/Source/cmInstallCommand.cxx
+++ b/Source/cmInstallCommand.cxx
@@ -247,7 +247,8 @@
       cmInstallGenerator::SelectMessageLevel(helper.Makefile),
       runtimeDependenciesArgsRef.GetExcludeFromAll() &&
         (apple ? frameworkArgs.GetExcludeFromAll() : true),
-      helper.Makefile->GetBacktrace());
+      helper.Makefile->GetBacktrace(),
+      helper.Makefile->GetPolicyStatus(cmPolicies::CMP0207));
   helper.Makefile->AddInstallGenerator(
     std::move(getRuntimeDependenciesGenerator));
 
@@ -2035,6 +2036,152 @@
 #endif
 }
 
+#ifndef CMAKE_BOOTSTRAP
+cm::optional<cm::string_view> MatchExport(cm::string_view directive,
+                                          std::string const& exportName)
+{
+  std::string::size_type const l = exportName.size();
+  if (directive.substr(0, l) == exportName) {
+    if (directive.size() > l && directive[l] == ':') {
+      return directive.substr(l + 1);
+    }
+  }
+  return cm::nullopt;
+}
+
+void AssignValue(std::string& dest, std::string const& value)
+{
+  dest = value;
+}
+
+void AssignValue(std::vector<std::string>& dest, std::string const& value)
+{
+  dest = cmList{ value }.data();
+}
+
+template <typename T>
+void GetExportArgumentFromVariable(cmMakefile const* makefile,
+                                   cmExportSet const& exportSet,
+                                   cm::string_view suffix, T& variable)
+{
+  std::string const& name =
+    cmStrCat(exportSet.GetName(), "_EXPORT_PACKAGE_INFO_"_s, suffix);
+  if (cmValue const& value = makefile->GetDefinition(name)) {
+    std::string realValue;
+    makefile->ConfigureString(value, realValue, true, false);
+    AssignValue(variable, realValue);
+  }
+}
+
+bool HandleMappedPackageInfo(
+  cmExportSet& exportSet, cm::string_view directive, Helper& helper,
+  cmInstallCommandArguments const& installCommandArgs,
+  cmExecutionStatus& status, cmInstallGenerator::MessageLevel message,
+  std::string const& cxxModulesDirectory)
+{
+  cmPackageInfoArguments arguments;
+
+  // Extract information from the directive.
+  std::string::size_type const n = directive.find('/');
+  if (n != std::string::npos) {
+    arguments.PackageName = std::string{ directive.substr(0, n) };
+    directive = directive.substr(n + 1);
+
+    if (!directive.empty() && directive[0] == 'l') {
+      arguments.LowerCase = true;
+      directive = directive.substr(1);
+    }
+
+    if (!directive.empty() && directive[0] == 'a') {
+      std::string::size_type const d = directive.find('/');
+      if (d != std::string::npos) {
+        arguments.Appendix = std::string{ directive.substr(1, d - 1) };
+        directive = directive.substr(d);
+      } else {
+        arguments.Appendix = std::string{ directive.substr(1) };
+        directive = {};
+      }
+
+      if (arguments.Appendix.empty()) {
+        status.SetError(cmStrCat(
+          "CMAKE_INSTALL_EXPORTS_AS_PACKAGE_INFO given APPENDIX "
+          R"(directive for export ")"_s,
+          exportSet.GetName(), R"(", but no appendix name was provided.)"_s));
+        return false;
+      }
+    }
+
+    if (!directive.empty()) {
+      if (directive[0] != '/') {
+        status.SetError(
+          cmStrCat("CMAKE_INSTALL_EXPORTS_AS_PACKAGE_INFO given unrecognized "
+                   R"(directive  ")"_s,
+                   directive, R"(".)"_s));
+        return false;
+      }
+
+      directive = directive.substr(1);
+    }
+  } else {
+    arguments.PackageName = std::string{ directive };
+    directive = {};
+  }
+
+  if (arguments.PackageName.empty()) {
+    status.SetError(
+      cmStrCat("CMAKE_INSTALL_EXPORTS_AS_PACKAGE_INFO missing package name "
+               R"(for export ")"_s,
+               exportSet.GetName(), R"(".)"_s));
+    return false;
+  }
+
+  // Build destination.
+  std::string dest = std::string{ directive };
+  if (dest.empty()) {
+    if (helper.Makefile->GetSafeDefinition("CMAKE_SYSTEM_NAME") == "Windows") {
+      dest = std::string{ "cps"_s };
+    } else {
+      dest = cmStrCat(helper.GetLibraryDestination(nullptr), "/cps/",
+                      arguments.GetPackageDirName());
+    }
+  }
+
+  if (arguments.Appendix.empty()) {
+    // Get additional export information from variables.
+    GetExportArgumentFromVariable( // BR
+      helper.Makefile, exportSet, "VERSION"_s, arguments.Version);
+    GetExportArgumentFromVariable( // BR
+      helper.Makefile, exportSet, "COMPAT_VERSION"_s, arguments.VersionCompat);
+    GetExportArgumentFromVariable( // BR
+      helper.Makefile, exportSet, "VERSION_SCHEMA"_s, arguments.VersionSchema);
+    GetExportArgumentFromVariable( // BR
+      helper.Makefile, exportSet, "LICENSE"_s, arguments.License);
+    GetExportArgumentFromVariable( // BR
+      helper.Makefile, exportSet, "DEFAULT_LICENSE"_s,
+      arguments.DefaultLicense);
+    GetExportArgumentFromVariable( // BR
+      helper.Makefile, exportSet, "DEFAULT_CONFIGURATIONS"_s,
+      arguments.DefaultConfigs);
+  }
+
+  // Sanity-check export information.
+  if (!arguments.Check(status)) {
+    return false;
+  }
+
+  // Create the package info generator.
+  helper.Makefile->AddInstallGenerator(
+    cm::make_unique<cmInstallPackageInfoExportGenerator>(
+      &exportSet, dest, installCommandArgs.GetPermissions(),
+      installCommandArgs.GetConfigurations(),
+      installCommandArgs.GetComponent(), message,
+      installCommandArgs.GetExcludeFromAll(), std::move(arguments),
+      cxxModulesDirectory, helper.Makefile->GetBacktrace()));
+
+  return true;
+}
+#endif
+
 bool HandleExportMode(std::vector<std::string> const& args,
                       cmExecutionStatus& status)
 {
@@ -2135,6 +2282,28 @@
   helper.Makefile->GetGlobalGenerator()->AddInstallComponent(
     ica.GetComponent());
 
+#ifndef CMAKE_BOOTSTRAP
+  // Check if PACKAGE_INFO export has been requested for this export set.
+  if (cmExperimental::HasSupportEnabled(
+        status.GetMakefile(), cmExperimental::Feature::ExportPackageInfo) &&
+      cmExperimental::HasSupportEnabled(
+        status.GetMakefile(), cmExperimental::Feature::MappedPackageInfo)) {
+    if (cmValue const& piExports = helper.Makefile->GetDefinition(
+          "CMAKE_INSTALL_EXPORTS_AS_PACKAGE_INFO")) {
+      for (auto const& pie : cmList{ piExports }) {
+        cm::optional<cm::string_view> const directive = MatchExport(pie, exp);
+        if (directive) {
+          if (!HandleMappedPackageInfo(exportSet, *directive, helper, ica,
+                                       status, message,
+                                       cxx_modules_directory)) {
+            return false;
+          }
+        }
+      }
+    }
+  }
+#endif
+
   // Create the export install generator.
   helper.Makefile->AddInstallGenerator(
     cm::make_unique<cmInstallCMakeConfigExportGenerator>(
diff --git a/Source/cmInstallGetRuntimeDependenciesGenerator.cxx b/Source/cmInstallGetRuntimeDependenciesGenerator.cxx
index 0ba9f14..4292f8f 100644
--- a/Source/cmInstallGetRuntimeDependenciesGenerator.cxx
+++ b/Source/cmInstallGetRuntimeDependenciesGenerator.cxx
@@ -19,6 +19,7 @@
 #include "cmLocalGenerator.h"
 #include "cmMakefile.h"
 #include "cmOutputConverter.h"
+#include "cmPolicies.h"
 #include "cmScriptGenerator.h"
 #include "cmStringAlgorithms.h"
 
@@ -83,7 +84,8 @@
     std::vector<std::string> postExcludeFiles, std::string libraryComponent,
     std::string frameworkComponent, bool noInstallRPath, char const* depsVar,
     char const* rpathPrefix, std::vector<std::string> const& configurations,
-    MessageLevel message, bool exclude_from_all, cmListFileBacktrace backtrace)
+    MessageLevel message, bool exclude_from_all, cmListFileBacktrace backtrace,
+    cmPolicies::PolicyStatus policyStatusCMP0207)
   : cmInstallGenerator("", configurations, "", message, exclude_from_all,
                        false, std::move(backtrace))
   , RuntimeDependencySet(runtimeDependencySet)
@@ -96,6 +98,7 @@
   , PostExcludeFiles(std::move(postExcludeFiles))
   , LibraryComponent(std::move(libraryComponent))
   , FrameworkComponent(std::move(frameworkComponent))
+  , PolicyStatusCMP0207(policyStatusCMP0207)
   , NoInstallRPath(noInstallRPath)
   , DepsVar(depsVar)
   , RPathPrefix(rpathPrefix)
@@ -141,6 +144,14 @@
     this->LocalGenerator->GetMakefile()->GetSafeDefinition(
       "CMAKE_INSTALL_NAME_TOOL");
 
+  Indent inputIndent = indent;
+  if (this->PolicyStatusCMP0207 != cmPolicies::WARN) {
+    indent = indent.Next();
+    os << inputIndent << "block(SCOPE_FOR POLICIES)\n"
+       << indent << "cmake_policy(SET CMP0207 "
+       << (this->PolicyStatusCMP0207 == cmPolicies::NEW ? "NEW" : "OLD")
+       << ")\n";
+  }
   os << indent << "file(GET_RUNTIME_DEPENDENCIES\n"
      << indent << "  RESOLVED_DEPENDENCIES_VAR " << this->DepsVar << '\n';
   WriteFilesArgument(os, "EXECUTABLES"_s,
@@ -204,4 +215,8 @@
     os << indent << "  RPATH_PREFIX " << this->RPathPrefix << '\n';
   }
   os << indent << "  )\n";
+
+  if (this->PolicyStatusCMP0207 != cmPolicies::WARN) {
+    os << inputIndent << "endblock()\n";
+  }
 }
diff --git a/Source/cmInstallGetRuntimeDependenciesGenerator.h b/Source/cmInstallGetRuntimeDependenciesGenerator.h
index 11b6d87..9670dcf 100644
--- a/Source/cmInstallGetRuntimeDependenciesGenerator.h
+++ b/Source/cmInstallGetRuntimeDependenciesGenerator.h
@@ -7,6 +7,7 @@
 #include <vector>
 
 #include "cmInstallGenerator.h"
+#include "cmPolicies.h"
 
 class cmListFileBacktrace;
 class cmLocalGenerator;
@@ -26,8 +27,8 @@
     std::vector<std::string> postExcludeFiles, std::string libraryComponent,
     std::string frameworkComponent, bool noInstallRPath, char const* depsVar,
     char const* rpathPrefix, std::vector<std::string> const& configurations,
-    MessageLevel message, bool exclude_from_all,
-    cmListFileBacktrace backtrace);
+    MessageLevel message, bool exclude_from_all, cmListFileBacktrace backtrace,
+    cmPolicies::PolicyStatus policyStatusCMP0207);
 
   bool Compute(cmLocalGenerator* lg) override;
 
@@ -48,6 +49,7 @@
   std::vector<std::string> PostExcludeFiles;
   std::string LibraryComponent;
   std::string FrameworkComponent;
+  cmPolicies::PolicyStatus PolicyStatusCMP0207;
   bool NoInstallRPath;
   char const* DepsVar;
   char const* RPathPrefix;
diff --git a/Source/cmLinkLineDeviceComputer.cxx b/Source/cmLinkLineDeviceComputer.cxx
index daacea5..6fb481b 100644
--- a/Source/cmLinkLineDeviceComputer.cxx
+++ b/Source/cmLinkLineDeviceComputer.cxx
@@ -45,7 +45,7 @@
   // * '-pthread' => drop
   // * '-a' => drop
   // * '-framework Name' (as one string) => drop
-  return (!cmHasLiteralPrefix(item, "-") || //
+  return (!cmHasPrefix(item, '-') ||        //
           cmHasLiteralPrefix(item, "-l") || //
           cmHasLiteralPrefix(item, "-L") || //
           cmHasLiteralPrefix(item, "--library"));
diff --git a/Source/cmLoadCacheCommand.cxx b/Source/cmLoadCacheCommand.cxx
index d88dbb3..5a665cb 100644
--- a/Source/cmLoadCacheCommand.cxx
+++ b/Source/cmLoadCacheCommand.cxx
@@ -8,6 +8,7 @@
 
 #include "cmExecutionStatus.h"
 #include "cmMakefile.h"
+#include "cmState.h"
 #include "cmStateTypes.h"
 #include "cmSystemTools.h"
 #include "cmake.h"
@@ -31,8 +32,9 @@
     return ReadWithPrefix(args, status);
   }
 
-  if (status.GetMakefile().GetCMakeInstance()->GetWorkingMode() ==
-      cmake::SCRIPT_MODE) {
+  cmState::Role const role =
+    status.GetMakefile().GetCMakeInstance()->GetState()->GetRole();
+  if (role != cmState::Role::Project) {
     status.SetError(
       "Only load_cache(READ_WITH_PREFIX) may be used in script mode");
     return false;
diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx
index 4f186a8..b6cc3a6 100644
--- a/Source/cmLocalNinjaGenerator.cxx
+++ b/Source/cmLocalNinjaGenerator.cxx
@@ -489,7 +489,7 @@
   auto it = std::find_if(args.cbegin(), args.cend(),
                          [](std::string const& arg) -> bool {
                            // FIXME: Detect more windows shell operators.
-                           return cmHasLiteralPrefix(arg, ">");
+                           return cmHasPrefix(arg, '>');
                          });
   return it != args.cend();
 }
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index f480874..c169d0f 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -586,7 +586,7 @@
         }
       }
       if (this->GetCMakeInstance()->HasScriptModeExitCode() &&
-          this->GetCMakeInstance()->GetWorkingMode() == cmake::SCRIPT_MODE) {
+          this->GetCMakeInstance()->RoleSupportsExitCode()) {
         // pass-through the exit code from inner cmake_language(EXIT) ,
         // possibly from include() or similar command...
         status.SetExitCode(this->GetCMakeInstance()->GetScriptModeExitCode());
@@ -3252,8 +3252,7 @@
   // make sure the same generator is used
   // use this program as the cmake to be run, it should not
   // be run that way but the cmake object requires a valid path
-  cmake cm(cmake::RoleProject, cmState::Project,
-           cmState::ProjectKind::TryCompile);
+  cmake cm(cmState::Role::Project, cmState::TryCompile::Yes);
   auto gg = cm.CreateGlobalGenerator(this->GetGlobalGenerator()->GetName());
   if (!gg) {
     this->IssueMessage(MessageType::INTERNAL_ERROR,
@@ -3395,8 +3394,8 @@
 void cmMakefile::DisplayStatus(std::string const& message, float s) const
 {
   cmake* cm = this->GetCMakeInstance();
-  if (cm->GetWorkingMode() == cmake::FIND_PACKAGE_MODE) {
-    // don't output any STATUS message in FIND_PACKAGE_MODE, since they will
+  if (cm->GetState()->GetRole() == cmState::Role::FindPackage) {
+    // don't output any STATUS message in --find-package mode, since they will
     // directly be fed to the compiler, which will be confused.
     return;
   }
@@ -4122,7 +4121,9 @@
   this->StateSnapshot.SetPolicy(id, status);
 
   // Handle CMAKE_PARENT_LIST_FILE for CMP0198 policy changes
-  if (id == cmPolicies::CMP0198) {
+  if (id == cmPolicies::CMP0198 &&
+      this->GetCMakeInstance()->GetState()->GetRole() ==
+        cmState::Role::Project) {
     this->UpdateParentListFileVariable();
   }
 
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index 4e3cee9..df32316 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -919,7 +919,7 @@
       cmOutputConverter::SHELL);
 
     if (this->LocalGenerator->IsMinGWMake() &&
-        cmHasLiteralSuffix(targetOutPathCompilePDB, "\\")) {
+        cmHasSuffix(targetOutPathCompilePDB, '\\')) {
       // mingw32-make incorrectly interprets 'a\ b c' as 'a b' and 'c'
       // (but 'a\ b "c"' as 'a\', 'b', and 'c'!).  Workaround this by
       // avoiding a trailing backslash in the argument.
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index ef8dabe..d833bbb 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -456,7 +456,7 @@
 {
   // Choose an extension to compile already-preprocessed source.
   std::string ppExt = source->GetExtension();
-  if (cmHasLiteralPrefix(ppExt, "F")) {
+  if (cmHasPrefix(ppExt, 'F')) {
     // Some Fortran compilers automatically enable preprocessing for
     // upper-case extensions.  Since the source is already preprocessed,
     // use a lower-case extension.
diff --git a/Source/cmPackageInfoReader.cxx b/Source/cmPackageInfoReader.cxx
index 3c7c970..97a4d0c 100644
--- a/Source/cmPackageInfoReader.cxx
+++ b/Source/cmPackageInfoReader.cxx
@@ -223,7 +223,7 @@
 std::string NormalizeTargetName(std::string const& name,
                                 std::string const& context)
 {
-  if (cmHasLiteralPrefix(name, ":")) {
+  if (cmHasPrefix(name, ':')) {
     return cmStrCat(context, ':', name);
   }
 
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index 2f22aaa..b52a3c8 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -612,7 +612,16 @@
          4, 2, 0, WARN)                                                       \
   SELECT(POLICY, CMP0204,                                                     \
          "A character set is always defined when targeting the MSVC ABI.", 4, \
-         2, 0, WARN)
+         2, 0, WARN)                                                          \
+  SELECT(POLICY, CMP0205,                                                     \
+         "file(CREATE_LINK) with COPY_ON_ERROR copies directory content.", 4, \
+         3, 0, WARN)                                                          \
+  SELECT(POLICY, CMP0206,                                                     \
+         "The CPack Archive Generator defaults to UID 0 and GID 0.", 4, 3, 0, \
+         WARN)                                                                \
+  SELECT(POLICY, CMP0207,                                                     \
+         "file(GET_RUNTIME_DEPENDENCIES) normalizes paths before matching.",  \
+         4, 3, 0, WARN)
 
 #define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
 #define CM_FOR_EACH_POLICY_ID(POLICY)                                         \
diff --git a/Source/cmProjectCommand.cxx b/Source/cmProjectCommand.cxx
index dd91fe868..d00cae1 100644
--- a/Source/cmProjectCommand.cxx
+++ b/Source/cmProjectCommand.cxx
@@ -273,7 +273,7 @@
   // Note, this intentionally doesn't touch cache variables as the legacy
   // behavior did not modify cache
   auto checkAndClearVariables = [&](cm::string_view var) {
-    std::vector<std::string> vv = { "PROJECT_", cmStrCat(projectName, "_") };
+    std::vector<std::string> vv = { "PROJECT_", cmStrCat(projectName, '_') };
     if (mf.IsRootMakefile()) {
       vv.push_back("CMAKE_PROJECT_");
     }
diff --git a/Source/cmRuntimeDependencyArchive.cxx b/Source/cmRuntimeDependencyArchive.cxx
index 1ee80b4..998d306 100644
--- a/Source/cmRuntimeDependencyArchive.cxx
+++ b/Source/cmRuntimeDependencyArchive.cxx
@@ -367,7 +367,7 @@
       break;
     }
   }
-  it->second.insert(path);
+  it->second.emplace(path);
   this->RPaths[path] = std::move(rpaths);
 }
 
diff --git a/Source/cmSPDXSerializer.cxx b/Source/cmSPDXSerializer.cxx
deleted file mode 100644
index 7d22103..0000000
--- a/Source/cmSPDXSerializer.cxx
+++ /dev/null
@@ -1,1375 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
-   file LICENSE.rst or https://cmake.org/licensing for details.  */
-#include "cmSPDXSerializer.h"
-
-#include <new>
-#include <string>
-
-#include <cm/optional>
-
-#include <cm3p/json/value.h>
-
-// Serialization Utilities
-
-template <typename T>
-void addVectorSPDXValue(Json::Value& obj, std::string const& key,
-                        std::vector<T> const& vec)
-{
-  auto& list = obj[key];
-  list = Json::Value(Json::arrayValue);
-  for (auto const& val : vec) {
-    list.append(val.toJsonLD());
-  }
-}
-
-template <>
-void addVectorSPDXValue(Json::Value& obj, std::string const& key,
-                        std::vector<std::string> const& vec)
-{
-  auto& list = obj[key];
-  list = Json::Value(Json::arrayValue);
-  for (auto const& val : vec) {
-    list.append(val);
-  }
-}
-
-template <typename T>
-void addOptionalSPDXValue(Json::Value& obj, std::string const& key,
-                          cm::optional<std::vector<T>> const& opt)
-{
-  if (opt) {
-    addVectorSPDXValue(obj, key, *opt);
-  }
-}
-
-template <typename T>
-void addOptionalSPDXValue(Json::Value& obj, std::string const& key,
-                          cm::optional<T> const& opt)
-{
-  if (opt) {
-    obj[key] = opt->toJsonLD();
-  }
-}
-
-template <>
-void addOptionalSPDXValue(Json::Value& obj, std::string const& key,
-                          cm::optional<std::string> const& opt)
-{
-  if (opt) {
-    obj[key] = *opt;
-  }
-}
-
-// Base Class
-
-cmSPDXSerializationBase::SPDXTypeId cmSPDXSerializationBase::getTypeId() const
-{
-  return TypeId;
-}
-
-cmSPDXSerializationBase::cmSPDXSerializationBase(SPDXTypeId id)
-  : TypeId(id)
-{
-}
-
-cmSPDXSerializationBase::cmSPDXSerializationBase(SPDXTypeId id,
-                                                 std::string nodeId)
-  : NodeId(std::move(nodeId))
-  , TypeId(id)
-{
-}
-
-// Convenience Classes
-
-cmSPDXIdentifierReference::cmSPDXIdentifierReference()
-  : cmSPDXSerializationBase(CM_IDENTIFIER_REFERENCE)
-{
-}
-cmSPDXIdentifierReference::cmSPDXIdentifierReference(
-  cmSPDXSerializationBase const& ref)
-  : cmSPDXSerializationBase(CM_IDENTIFIER_REFERENCE, ref.NodeId)
-{
-}
-cmSPDXIdentifierReference::cmSPDXIdentifierReference(std::string const& ref)
-  : cmSPDXSerializationBase(CM_IDENTIFIER_REFERENCE, ref)
-{
-}
-
-Json::Value cmSPDXIdentifierReference::toJsonLD() const
-{
-  return NodeId;
-}
-
-cmSPDXNonElementBase::cmSPDXNonElementBase(SPDXTypeId id)
-  : cmSPDXSerializationBase(id)
-{
-}
-
-Json::Value cmSPDXNonElementBase::toJsonLD() const
-{
-  Json::Value obj(Json::objectValue);
-  obj["@id"] = NodeId;
-  return obj;
-}
-
-// SPDX Core Enums
-
-cmSPDXAnnotationType::cmSPDXAnnotationType(cmSPDXAnnotationTypeId typeId)
-  : TypeId(typeId)
-{
-}
-
-Json::Value cmSPDXAnnotationType::toJsonLD() const
-{
-  switch (TypeId) {
-    case OTHER:
-      return "other";
-    case REVIEW:
-      return "review";
-    default:
-      return "INVALID_ANNOTATION_TYPE_ID";
-  }
-}
-
-cmSPDXExternalIdentifierType::cmSPDXExternalIdentifierType(
-  cmSPDXExternalIdentifierTypeId typeId)
-  : TypeId(typeId)
-{
-}
-
-Json::Value cmSPDXExternalIdentifierType::toJsonLD() const
-{
-  switch (TypeId) {
-    case CPE22:
-      return "cpe22";
-    case CPE23:
-      return "cpe23";
-    case CVE:
-      return "cve";
-    case EMAIL:
-      return "email";
-    case GITOID:
-      return "gitoid";
-    case OTHER:
-      return "other";
-    case PACKAGE_URL:
-      return "packageUrl";
-    case SECURITY_OTHER:
-      return "securityOther";
-    case SWHID:
-      return "swhid";
-    case SWID:
-      return "swid";
-    case URL_SCHEME:
-      return "urlScheme";
-    default:
-      return "INVALID_EXTERNAL_IDENTIFIER_TYPE_ID";
-  }
-}
-
-cmSPDXExternalRefType::cmSPDXExternalRefType(cmSPDXExternalRefTypeId typeId)
-  : TypeId(typeId)
-{
-}
-
-Json::Value cmSPDXExternalRefType::toJsonLD() const
-{
-  switch (TypeId) {
-    case ALT_DOWNLOAD_LOCATION:
-      return "altDownloadLocation:";
-    case ALT_WEB_PAGE:
-      return "altWebPage";
-    case BINARY_ARTIFACT:
-      return "binaryArtifact";
-    case BOWER:
-      return "bower";
-    case BUILD_META:
-      return "buildMeta";
-    case BUILD_SYSTEM:
-      return "buildSystem";
-    case CERTIFICATION_REPORT:
-      return "certificationReport";
-    case CHAT:
-      return "chat";
-    case COMPONENT_ANALYSIS_REPORT:
-      return "componentAnalysisReport";
-    case CWE:
-      return "cwe";
-    case DOCUMENTATION:
-      return "documentation";
-    case DYNAMIC_ANALYSIS_REPORT:
-      return "dynamicAnalysisReport";
-    case EOL_NOTICE:
-      return "eolNotice";
-    case EXPORT_CONTROL_ASSESSMENT:
-      return "exportControlAssessment";
-    case FUNDING:
-      return "funding";
-    case ISSUE_TRACKER:
-      return "issueTracker";
-    case LICENSE:
-      return "license";
-    case MAILING_LIST:
-      return "mailingList";
-    case MAVEN_CENTRAL:
-      return "mavenCentral";
-    case METRICS:
-      return "metrics";
-    case NPM:
-      return "npm";
-    case NUGET:
-      return "nuget";
-    case OTHER:
-      return "other";
-    case PRIVACY_ASSESSMENT:
-      return "privacyAssessment";
-    case PRODUCT_METADATA:
-      return "productMetadata";
-    case PURCHASE_ORDER:
-      return "purchaseOrder";
-    case QUALITY_ASSESSMENT_REPORT:
-      return "qualityAssessmentReport";
-    case RELEASE_HISTORY:
-      return "releaseHistory";
-    case RELEASE_NOTES:
-      return "releaseNotes";
-    case RISK_ASSESSMENT:
-      return "riskAssessment";
-    case RUNTIME_ANALYSIS_REPORT:
-      return "runtimeAnalysisReport";
-    case SECURE_SOFTWARE_ATTESTATION:
-      return "secureSoftwareAttestation";
-    case SECURITY_ADVERSARY_MODEL:
-      return "securityAdversaryModel";
-    case SECURITY_ADVISORY:
-      return "securityAdvisory";
-    case SECURITY_FIX:
-      return "securityFix";
-    case SECURITY_OTHER:
-      return "securityOther";
-    case SECURITY_PEN_TEST_REPORT:
-      return "securityPenTestReport";
-    case SECURITY_POLICY:
-      return "securityPolicy";
-    case SECURITY_THREAT_MODEL:
-      return "securityThreatModel";
-    case SOCIAL_MEDIA:
-      return "socialMedia";
-    case SOURCE_ARTIFACT:
-      return "sourceArtifact";
-    case STATIC_ANALYSIS_REPORT:
-      return "staticAnalysisReport";
-    case SUPPORT:
-      return "support";
-    case VCS:
-      return "vcs";
-    case VULNERABILITY_DISCLOSURE_REPORT:
-      return "vulnerabilityDisclosureReport";
-    case VULNERABILITY_EXPLOITABILITY_ASSESSMENT:
-      return "vulnerabilityExploitabilityAssessment";
-    default:
-      return "INVALID_EXTERNAL_REF_TYPE_ID";
-  }
-}
-
-cmSPDXHashAlgorithm::cmSPDXHashAlgorithm(cmSPDXHashAlgorithmId typeId)
-  : TypeId(typeId)
-{
-}
-
-Json::Value cmSPDXHashAlgorithm::toJsonLD() const
-{
-  switch (TypeId) {
-    case ADLER32:
-      return "adler32";
-    case BLAKE2B256:
-      return "blake2b256";
-    case BLAKE2B384:
-      return "blake2b384";
-    case BLAKE2B512:
-      return "blake2b512";
-    case BLAKE3:
-      return "blake3";
-    case CRYSTALS_DILITHIUM:
-      return "crystalsDilithium";
-    case CRYSTALS_KYBER:
-      return "crystalsLyber";
-    case FALCON:
-      return "falcon";
-    case MD2:
-      return "md2";
-    case MD4:
-      return "md4";
-    case MD5:
-      return "md5";
-    case MD6:
-      return "md6";
-    case OTHER:
-      return "other";
-    case SHA1:
-      return "sha1";
-    case SHA224:
-      return "sha224";
-    case SHA256:
-      return "sha256";
-    case SHA384:
-      return "sha384";
-    case SHA3_224:
-      return "sha3_224";
-    case SHA3_256:
-      return "sha3_256";
-    case SHA3_384:
-      return "sha3_384";
-    case SHA3_512:
-      return "sha3_512";
-    case SHA512:
-      return "sha512";
-    default:
-      return "INVALID_HASH_TYPE_ID";
-  }
-}
-
-cmSPDXLifecycleScopeType::cmSPDXLifecycleScopeType(
-  cmSPDXLifecycleScopeTypeId typeId)
-  : TypeId(typeId)
-{
-}
-
-Json::Value cmSPDXLifecycleScopeType::toJsonLD() const
-{
-  switch (TypeId) {
-    case BUILD:
-      return "build";
-    case DESIGN:
-      return "design";
-    case DEVELOPMENT:
-      return "development";
-    case OTHER:
-      return "other";
-    case RUNTIME:
-      return "runtime";
-    case TEST:
-      return "test";
-    default:
-      return "INVALID_LIFECYCLE_SCOPE_TYPE_ID";
-  }
-}
-
-cmSPDXProfileIdentifierType::cmSPDXProfileIdentifierType(
-  cmSPDXProfileIdentifierTypeId typeId)
-  : TypeId(typeId)
-{
-}
-
-Json::Value cmSPDXProfileIdentifierType::toJsonLD() const
-{
-  switch (TypeId) {
-    case AI:
-      return "ai";
-    case BUILD:
-      return "build";
-    case CORE:
-      return "code";
-    case DATASET:
-      return "dataset";
-    case EXPANDED_LICENSING:
-      return "expandedLicensing";
-    case EXTENSION:
-      return "extension";
-    case LITE:
-      return "lite";
-    case SECURITY:
-      return "security";
-    case SIMPLE_LICENSING:
-      return "simpleLicensing";
-    case SOFTWARE:
-      return "software";
-    default:
-      return "INVALID_PROFILE_IDENTIFIER_TYPE_ID";
-  }
-}
-
-cmSPDXRelationshipCompletenessType::cmSPDXRelationshipCompletenessType(
-  cmSPDXRelationshipCompletenessTypeId typeId)
-  : TypeId(typeId)
-{
-}
-
-Json::Value cmSPDXRelationshipCompletenessType::toJsonLD() const
-{
-  switch (TypeId) {
-    case COMPLETE:
-      return "complete";
-    case INCOMPLETE:
-      return "incomplete";
-    case NO_ASSERTION:
-      return "noAssertion";
-    default:
-      return "INVALID_RELATIONSHIP_COMPLETENESS_TYPE_ID";
-  }
-}
-
-cmSPDXRelationshipType::cmSPDXRelationshipType(cmSPDXRelationshipTypeId typeId)
-  : TypeId(typeId)
-{
-}
-
-Json::Value cmSPDXRelationshipType::toJsonLD() const
-{
-  switch (TypeId) {
-    case AFFECTS:
-      return "affects";
-    case AMENDED_BY:
-      return "amendedBy";
-    case ANCESTOR_OF:
-      return "ancestorOf";
-    case AVAILABLE_FROM:
-      return "availableFrom";
-    case CONFIGURES:
-      return "configures";
-    case CONTAINS:
-      return "contains";
-    case COORDINATED_BY:
-      return "coordinatedBy";
-    case COPIED_TO:
-      return "copiedTo";
-    case DELEGATED_TO:
-      return "delegatedTo";
-    case DEPENDS_ON:
-      return "dependsOn";
-    case DESCENDANT_OF:
-      return "descendantOf";
-    case DESCRIBES:
-      return "describes";
-    case DOES_NOT_AFFECT:
-      return "doesNotAffect";
-    case EXPANDS_TO:
-      return "expandsTo";
-    case EXPLOIT_CREATED_BY:
-      return "exploitCreatedBy";
-    case FIXED_BY:
-      return "fixedBy";
-    case FIXED_IN:
-      return "fixedIn";
-    case FOUND_BY:
-      return "foundBy";
-    case GENERATES:
-      return "generates";
-    case HAS_ADDED_FILE:
-      return "hasAddedFile";
-    case HAS_ASSESSMENT_FOR:
-      return "hasAssessmentFor";
-    case HAS_ASSOCIATED_VULNERABILITY:
-      return "hasAssociatedVulnerability";
-    case HAS_CONCLUDED_LICENSE:
-      return "hasConcludedLicense";
-    case HAS_DATA_FILE:
-      return "hasDataFile";
-    case HAS_DECLARED_LICENSE:
-      return "hasDeclaredLicense";
-    case HAS_DELETED_FILE:
-      return "hasDeletedFile";
-    case HAS_DEPENDENCY_MANIFEST:
-      return "hasDependencyManifest";
-    case HAS_DISTRIBUTION_ARTIFACT:
-      return "hasDistributionArtifact";
-    case HAS_DOCUMENTATION:
-      return "hasDocumentation";
-    case HAS_DYNAMIC_LINK:
-      return "hasDynamicLink";
-    case HAS_EVIDENCE:
-      return "hasEvidence";
-    case HAS_EXAMPLE:
-      return "hasExample";
-    case HAS_HOST:
-      return "hasHost";
-    case HAS_INPUT:
-      return "hasInput";
-    case HAS_METADATA:
-      return "hasMetadata";
-    case HAS_OPTIONAL_COMPONENT:
-      return "hasOptionalComponent";
-    case HAS_OPTIONAL_DEPENDENCY:
-      return "hasOptionalDependency";
-    case HAS_OUTPUT:
-      return "hasOutput";
-    case HAS_PREREQUISITE:
-      return "hasPrerequisite";
-    case HAS_PROVIDED_DEPENDENCY:
-      return "hasProvidedDependency";
-    case HAS_REQUIREMENT:
-      return "hasRequirement";
-    case HAS_SPECIFICATION:
-      return "hasSpecification";
-    case HAS_STATIC_LINK:
-      return "hasStaticLink";
-    case HAS_TEST:
-      return "hasTest";
-    case HAS_TEST_CASE:
-      return "hasTestCase";
-    case HAS_VARIANT:
-      return "hasVariant";
-    case INVOKED_BY:
-      return "invokedBy";
-    case MODIFIED_BY:
-      return "modifiedBy";
-    case OTHER:
-      return "other";
-    case PACKAGED_BY:
-      return "packagedBy";
-    case PATCHED_BY:
-      return "patchedBy";
-    case PUBLISHED_BY:
-      return "publishedBy";
-    case REPORTED_BY:
-      return "reportedBy";
-    case REPUBLISHED_BY:
-      return "republishedBy";
-    case SERIALIZED_IN_ARTIFACT:
-      return "serializedInArtifact";
-    case TESTED_ON:
-      return "testedOn";
-    case TRAINED_ON:
-      return "trainedOn";
-    case UNDER_INVESTIGATION_FOR:
-      return "underInvestigationFor";
-    case USES_TOOL:
-      return "usesTool";
-    default:
-      return "INVALID_RELATIONSHIP_TYPE_ID";
-  }
-}
-
-cmSPDXSupportType::cmSPDXSupportType(cmSPDXSupportTypeId typeId)
-  : TypeId(typeId)
-{
-}
-
-Json::Value cmSPDXSupportType::toJsonLD() const
-{
-  switch (TypeId) {
-    case DEPLOYED:
-      return "deployed";
-    case DEVELOPMENT:
-      return "development";
-    case END_OF_SUPPORT:
-      return "endOfSupport";
-    case LIMITED_SUPPORT:
-      return "limitedSupport";
-    case NO_ASSERTION:
-      return "noAssertion";
-    case NO_SUPPORT:
-      return "noSupport";
-    case SUPPORT:
-      return "support";
-    default:
-      return "INVALID_SUPPORT_TYPE_ID";
-  }
-}
-
-// SPDX Core NonElement Classes, Abstract
-
-cmSPDXIntegrityMethod::cmSPDXIntegrityMethod(SPDXTypeId id)
-  : cmSPDXNonElementBase(id)
-{
-}
-
-Json::Value cmSPDXIntegrityMethod::toJsonLD() const
-{
-  auto obj = cmSPDXNonElementBase::toJsonLD();
-  addOptionalSPDXValue(obj, "comment", Comment);
-  return obj;
-}
-
-// SPDX Core NonElement Classes, Concrete
-
-cmSPDXCreationInfo::cmSPDXCreationInfo()
-  : cmSPDXNonElementBase(CORE_CREATION_INFO)
-{
-}
-
-Json::Value cmSPDXCreationInfo::toJsonLD() const
-{
-  auto obj = cmSPDXNonElementBase::toJsonLD();
-  obj["type"] = "CreationInfo";
-  addOptionalSPDXValue(obj, "Comment", Comment);
-  obj["created"] = Created;
-  addVectorSPDXValue(obj, "createdBy", CreatedBy);
-  addOptionalSPDXValue(obj, "createdUsing", CreatedUsing);
-  return obj;
-}
-
-cmSPDXDictionaryEntry::cmSPDXDictionaryEntry()
-  : cmSPDXNonElementBase(CORE_DICTIONARY_ENTRY)
-{
-}
-cmSPDXDictionaryEntry::cmSPDXDictionaryEntry(std::string key)
-  : cmSPDXNonElementBase(CORE_DICTIONARY_ENTRY)
-  , Key(std::move(key))
-{
-}
-cmSPDXDictionaryEntry::cmSPDXDictionaryEntry(std::string key, std::string val)
-  : cmSPDXNonElementBase(CORE_DICTIONARY_ENTRY)
-  , Key(std::move(key))
-  , Value(std::move(val))
-{
-}
-
-Json::Value cmSPDXDictionaryEntry::toJsonLD() const
-{
-  auto obj = cmSPDXNonElementBase::toJsonLD();
-  obj["type"] = "DictionaryEntry";
-  obj["key"] = Key;
-  addOptionalSPDXValue(obj, "value", Value);
-  return obj;
-}
-
-cmSPDXExternalIdentifier::cmSPDXExternalIdentifier()
-  : cmSPDXNonElementBase(CORE_EXTERNAL_IDENTIFIER)
-{
-}
-
-Json::Value cmSPDXExternalIdentifier::toJsonLD() const
-{
-  auto obj = cmSPDXNonElementBase::toJsonLD();
-  obj["type"] = "ExternalIdentifier";
-  addOptionalSPDXValue(obj, "comment", Comment);
-  obj["externalIdentifierType"] = ExternalIdentifierType.toJsonLD();
-  obj["identifier"] = Identifier;
-  addOptionalSPDXValue(obj, "identifierLocator", IdentifierLocator);
-  addOptionalSPDXValue(obj, "issuingAuthority", IssuingAuthority);
-  return obj;
-}
-
-cmSPDXExternalMap::cmSPDXExternalMap()
-  : cmSPDXNonElementBase(CORE_EXTERNAL_MAP)
-{
-}
-
-Json::Value cmSPDXExternalMap::toJsonLD() const
-{
-  auto obj = cmSPDXNonElementBase::toJsonLD();
-  obj["type"] = "ExternalMap";
-  addOptionalSPDXValue(obj, "definingArtifact", DefiningArtifact);
-  obj["externalSpdxId"] = ExternalSpdxId;
-  addOptionalSPDXValue(obj, "locationHint", LocationHint);
-  addOptionalSPDXValue(obj, "integrityMethod", IntegrityMethod);
-  return obj;
-}
-
-cmSPDXExternalRef::cmSPDXExternalRef()
-  : cmSPDXNonElementBase(CORE_EXTERNAL_REF)
-{
-}
-
-Json::Value cmSPDXExternalRef::toJsonLD() const
-{
-  auto obj = cmSPDXNonElementBase::toJsonLD();
-  obj["type"] = "ExternalRef";
-  addOptionalSPDXValue(obj, "comment", Comment);
-  addOptionalSPDXValue(obj, "contentType", ContentType);
-  addOptionalSPDXValue(obj, "externalRefType", ExternalRefType);
-  addOptionalSPDXValue(obj, "locator", Locator);
-  return obj;
-}
-
-cmSPDXHash::cmSPDXHash()
-  : cmSPDXIntegrityMethod(CORE_HASH)
-{
-}
-
-Json::Value cmSPDXHash::toJsonLD() const
-{
-  auto obj = cmSPDXIntegrityMethod::toJsonLD();
-  obj["type"] = "Hash";
-  obj["algorithm"] = Algorithm.toJsonLD();
-  obj["hashValue"] = HashValue;
-  return obj;
-}
-
-cmSPDXNamespaceMap::cmSPDXNamespaceMap()
-  : cmSPDXNonElementBase(CORE_NAMESPACE_MAP)
-{
-}
-
-Json::Value cmSPDXNamespaceMap::toJsonLD() const
-{
-  auto obj = cmSPDXNonElementBase::toJsonLD();
-  obj["type"] = "NamespaceMap";
-  obj["namespace"] = Namespace;
-  obj["prefix"] = Namespace;
-  return obj;
-}
-
-cmSPDXPackageVerificationCode::cmSPDXPackageVerificationCode()
-  : cmSPDXIntegrityMethod(CORE_PACKAGE_VERIFICATION_CODE)
-{
-}
-
-Json::Value cmSPDXPackageVerificationCode::toJsonLD() const
-{
-  auto obj = cmSPDXIntegrityMethod::toJsonLD();
-  obj["type"] = "PackageVerificationCode";
-  obj["algorithm"] = Algorithm.toJsonLD();
-  obj["hashValue"] = HashValue;
-  return obj;
-}
-
-cmSPDXPositiveIntegerRange::cmSPDXPositiveIntegerRange(
-  unsigned int beingIntegerRange, unsigned int endIntegerRange)
-  : cmSPDXNonElementBase(CORE_POSITIVE_INTEGER_RANGE)
-  , BeginIntegerRange(beingIntegerRange)
-  , EndIntegerRange(endIntegerRange)
-{
-}
-
-Json::Value cmSPDXPositiveIntegerRange::toJsonLD() const
-{
-  auto obj = cmSPDXNonElementBase::toJsonLD();
-  obj["type"] = "PositiveIntegerRange";
-  obj["beginIntegerRange"] = BeginIntegerRange;
-  obj["endIntegerRange"] = EndIntegerRange;
-  return obj;
-}
-
-// SPDX Core Element Classes, Abstract
-
-cmSPDXElement::cmSPDXElement(SPDXTypeId id,
-                             cmSPDXCreationInfo const& creationInfo)
-  : cmSPDXSerializationBase(id)
-  , CreationInfo(creationInfo)
-{
-}
-
-Json::Value cmSPDXElement::toJsonLD() const
-{
-  Json::Value obj(Json::objectValue);
-  addOptionalSPDXValue(obj, "comment", Comment);
-  obj["creationInfo"] = CreationInfo.toJsonLD();
-  addOptionalSPDXValue(obj, "description", Description);
-  addOptionalSPDXValue(obj, "extension", Extension);
-  addOptionalSPDXValue(obj, "externalIdentifier", ExternalIdentifier);
-  addOptionalSPDXValue(obj, "externalRef", ExternalRef);
-  addOptionalSPDXValue(obj, "name", Name);
-  obj["spdxId"] = NodeId;
-  addOptionalSPDXValue(obj, "summary", Summary);
-  addOptionalSPDXValue(obj, "verifiedUsing", VerifiedUsing);
-  return obj;
-}
-
-cmSPDXArtifact::cmSPDXArtifact(SPDXTypeId id,
-                               cmSPDXCreationInfo const& creationInfo)
-  : cmSPDXElement(id, creationInfo)
-{
-}
-
-Json::Value cmSPDXArtifact::toJsonLD() const
-{
-  auto obj = cmSPDXElement::toJsonLD();
-  addOptionalSPDXValue(obj, "builtTime", BuiltTime);
-  addOptionalSPDXValue(obj, "originateBy", OriginatedBy);
-  addOptionalSPDXValue(obj, "releaseTime", ReleaseTime);
-  addOptionalSPDXValue(obj, "standardName", StandardName);
-  addOptionalSPDXValue(obj, "suppliedBy", SuppliedBy);
-  addOptionalSPDXValue(obj, "supportType", SupportType);
-  addOptionalSPDXValue(obj, "validUntilTime", ValidUntilTime);
-  return obj;
-}
-
-cmSPDXElementCollection::cmSPDXElementCollection(
-  SPDXTypeId id, cmSPDXCreationInfo const& creationInfo)
-  : cmSPDXElement(id, creationInfo)
-{
-}
-
-Json::Value cmSPDXElementCollection::toJsonLD() const
-{
-  auto obj = cmSPDXElement::toJsonLD();
-  addOptionalSPDXValue(obj, "element", Element);
-  addOptionalSPDXValue(obj, "profileConformance", ProfileConformance);
-  addOptionalSPDXValue(obj, "rootElement", RootElement);
-  return obj;
-}
-
-// SPDX Implicit Core Element Classes, Abstract
-
-// Nominally an inheritable class, but adds nothing to Element
-using cmSPDXAgentAbstract = cmSPDXElement;
-
-cmSPDXBundleAbstract::cmSPDXBundleAbstract(
-  SPDXTypeId id, cmSPDXCreationInfo const& creationInfo)
-  : cmSPDXElementCollection(id, creationInfo)
-{
-}
-
-Json::Value cmSPDXBundleAbstract::toJsonLD() const
-{
-  auto obj = cmSPDXElementCollection::toJsonLD();
-  obj["context"] = Context;
-  return obj;
-}
-
-// Nominally an inheritable class, but adds nothing to Bundle
-using cmSPDXBomAbstract = cmSPDXBundleAbstract;
-
-cmSPDXRelationshipAbstract::cmSPDXRelationshipAbstract(
-  SPDXTypeId id, cmSPDXCreationInfo const& creationInfo)
-  : cmSPDXElement(id, creationInfo)
-{
-}
-
-Json::Value cmSPDXRelationshipAbstract::toJsonLD() const
-{
-  auto obj = cmSPDXElement::toJsonLD();
-  addOptionalSPDXValue(obj, "completeness", Completeness);
-  addOptionalSPDXValue(obj, "endTime", EndTime);
-  obj["from"] = From.toJsonLD();
-  obj["relationshipType"] = RelationshipType.toJsonLD();
-  addOptionalSPDXValue(obj, "startTime", StartTime);
-  addVectorSPDXValue(obj, "to", To);
-  return obj;
-}
-
-// SPDX Core Element Classes, Concrete
-
-cmSPDXAgent::cmSPDXAgent(cmSPDXCreationInfo const& creationInfo)
-  : cmSPDXAgentAbstract(CORE_AGENT, creationInfo)
-{
-}
-
-Json::Value cmSPDXAgent::toJsonLD() const
-{
-  auto obj = cmSPDXAgentAbstract::toJsonLD();
-  obj["type"] = "Agent";
-  return obj;
-}
-
-cmSPDXAnnotation::cmSPDXAnnotation(cmSPDXCreationInfo const& creationInfo,
-                                   cmSPDXIdentifierReference subject)
-  : cmSPDXElement(CORE_ANNOTATION, creationInfo)
-  , Subject(std::move(subject))
-{
-}
-
-Json::Value cmSPDXAnnotation::toJsonLD() const
-{
-  auto obj = cmSPDXElement::toJsonLD();
-  obj["type"] = "Annotation";
-  obj["annotationType"] = AnnotationType.toJsonLD();
-  addOptionalSPDXValue(obj, "contentType", ContentType);
-  addOptionalSPDXValue(obj, "statement", Statement);
-  obj["subject"] = Subject.toJsonLD();
-  return obj;
-}
-
-cmSPDXBom::cmSPDXBom(cmSPDXCreationInfo const& creationInfo)
-  : cmSPDXBomAbstract(CORE_BOM, creationInfo)
-{
-}
-
-Json::Value cmSPDXBom::toJsonLD() const
-{
-  auto obj = cmSPDXBomAbstract::toJsonLD();
-  obj["type"] = "Bom";
-  return obj;
-}
-
-cmSPDXBundle::cmSPDXBundle(cmSPDXCreationInfo const& creationInfo)
-  : cmSPDXBundleAbstract(CORE_BUNDLE, creationInfo)
-{
-}
-
-Json::Value cmSPDXBundle::toJsonLD() const
-{
-  auto obj = cmSPDXBundleAbstract::toJsonLD();
-  obj["type"] = "Bundle";
-  return obj;
-}
-
-cmSPDXIndividualElement::cmSPDXIndividualElement(
-  cmSPDXCreationInfo const& creationInfo)
-  : cmSPDXElement(CORE_INDIVIDUAL_ELEMENT, creationInfo)
-{
-}
-
-Json::Value cmSPDXIndividualElement::toJsonLD() const
-{
-  auto obj = cmSPDXElement::toJsonLD();
-  obj["type"] = "IndividualElement";
-  return obj;
-}
-
-cmSPDXLifecycleScopedRelationship::cmSPDXLifecycleScopedRelationship(
-  cmSPDXCreationInfo const& creationInfo)
-  : cmSPDXRelationshipAbstract(CORE_LIFECYCLE_SCOPED_RELATIONSHIP,
-                               creationInfo)
-{
-}
-
-Json::Value cmSPDXLifecycleScopedRelationship::toJsonLD() const
-{
-  auto obj = cmSPDXRelationshipAbstract::toJsonLD();
-  obj["type"] = "LifecycleScopedRelationship";
-  addOptionalSPDXValue(obj, "scope", Scope);
-  return obj;
-}
-
-cmSPDXOrganization::cmSPDXOrganization(cmSPDXCreationInfo const& creationInfo)
-  : cmSPDXAgentAbstract(CORE_ORGANIZATION, creationInfo)
-{
-}
-
-Json::Value cmSPDXOrganization::toJsonLD() const
-{
-  auto obj = cmSPDXAgentAbstract::toJsonLD();
-  obj["type"] = "Organization";
-  return obj;
-}
-
-cmSPDXPerson::cmSPDXPerson(cmSPDXCreationInfo const& creationInfo)
-  : cmSPDXAgentAbstract(CORE_PERSON, creationInfo)
-{
-}
-
-Json::Value cmSPDXPerson::toJsonLD() const
-{
-  auto obj = cmSPDXAgentAbstract::toJsonLD();
-  obj["type"] = "Person";
-  return obj;
-}
-
-cmSPDXRelationship::cmSPDXRelationship(cmSPDXCreationInfo const& creationInfo)
-  : cmSPDXRelationshipAbstract(CORE_RELATIONSHIP, creationInfo)
-{
-}
-
-Json::Value cmSPDXRelationship::toJsonLD() const
-{
-  auto obj = cmSPDXRelationshipAbstract::toJsonLD();
-  obj["type"] = "Relationship";
-  return obj;
-}
-
-cmSPDXSoftwareAgent::cmSPDXSoftwareAgent(
-  cmSPDXCreationInfo const& creationInfo)
-  : cmSPDXAgentAbstract(CORE_SOFTWARE_AGENT, creationInfo)
-{
-}
-
-Json::Value cmSPDXSoftwareAgent::toJsonLD() const
-{
-  auto obj = cmSPDXAgentAbstract::toJsonLD();
-  obj["type"] = "SoftwareAgent";
-  return obj;
-}
-
-cmSPDXSpdxDocument::cmSPDXSpdxDocument(cmSPDXCreationInfo const& creationInfo)
-  : cmSPDXElementCollection(CORE_SPDX_DOCUMENT, creationInfo)
-{
-}
-
-Json::Value cmSPDXSpdxDocument::toJsonLD() const
-{
-  auto obj = cmSPDXElementCollection::toJsonLD();
-  obj["type"] = "SpdxDocument";
-  addOptionalSPDXValue(obj, "dataLicense", DataLicense);
-  addOptionalSPDXValue(obj, "externalMap", ExternalMap);
-  addOptionalSPDXValue(obj, "namespaceMap", NamespaceMap);
-  return obj;
-}
-
-cmSPDXTool::cmSPDXTool(cmSPDXCreationInfo const& creationInfo)
-  : cmSPDXElement(CORE_TOOL, creationInfo)
-{
-}
-
-Json::Value cmSPDXTool::toJsonLD() const
-{
-  auto obj = cmSPDXElement::toJsonLD();
-  obj["type"] = "Tool";
-  return obj;
-}
-
-// SPDX Software Enums
-
-cmSPDXContentIdentifierType::cmSPDXContentIdentifierType(
-  cmSPDXContentIdentifierTypeId typeId)
-  : TypeId(typeId)
-{
-}
-
-Json::Value cmSPDXContentIdentifierType::toJsonLD() const
-{
-  switch (TypeId) {
-    case GITOID:
-      return "gitoid";
-    case SWHID:
-      return "swhid";
-    default:
-      return "INVALID_CONTENT_IDENTIFIER_TYPE_ID";
-  }
-}
-
-cmSPDXFileKindType::cmSPDXFileKindType(cmSPDXFileKindTypeId typeId)
-  : TypeId(typeId)
-{
-}
-
-Json::Value cmSPDXFileKindType::toJsonLD() const
-{
-  switch (TypeId) {
-    case DIRECTORY:
-      return "directory";
-    case FILE:
-      return "file";
-    default:
-      return "INVALID_FILE_KIND_TYPE_ID";
-  }
-}
-
-cmSPDXSbomType::cmSPDXSbomType(cmSPDXSbomTypeId typeId)
-  : TypeId(typeId)
-{
-}
-
-Json::Value cmSPDXSbomType::toJsonLD() const
-{
-  switch (TypeId) {
-    case ANALYZED:
-      return "analyzed";
-    case BUILD:
-      return "build";
-    case DEPLOYED:
-      return "deployed";
-    case DESIGN:
-      return "design";
-    case RUNTIME:
-      return "runtime";
-    case SOURCE:
-      return "source";
-    default:
-      return "INVALID_SBOM_TYPE_ID";
-  }
-}
-
-cmSPDXSoftwarePurpose::cmSPDXSoftwarePurpose(cmSPDXSoftwarePurposeId typeId)
-  : TypeId(typeId)
-{
-}
-
-Json::Value cmSPDXSoftwarePurpose::toJsonLD() const
-{
-  switch (TypeId) {
-    case APPLICATION:
-      return "application";
-    case ARCHIVE:
-      return "archive";
-    case BOM:
-      return "bom";
-    case CONFIGURATION:
-      return "configuration";
-    case CONTAINER:
-      return "container";
-    case DATA:
-      return "data";
-    case DEVICE:
-      return "device";
-    case DEVICE_DRIVER:
-      return "deviceDriver";
-    case DISK_IMAGE:
-      return "diskImage";
-    case DOCUMENTATION:
-      return "documentation";
-    case EVIDENCE:
-      return "evidence";
-    case EXECUTABLE:
-      return "executable";
-    case FILE:
-      return "file";
-    case FILESYSTEM_IMAGE:
-      return "filesystemImage";
-    case FIRMWARE:
-      return "firmware";
-    case FRAMEWORK:
-      return "framework";
-    case INSTALL:
-      return "install";
-    case LIBRARY:
-      return "library";
-    case MANIFEST:
-      return "manifest";
-    case MODEL:
-      return "model";
-    case MODULE:
-      return "module";
-    case OPERATING_SYSTEM:
-      return "operatingSystem";
-    case OTHER:
-      return "other";
-    case PATCH:
-      return "patch";
-    case PLATFORM:
-      return "platform";
-    case REQUIREMENT:
-      return "requirement";
-    case SOURCE:
-      return "source";
-    case SPECIFICATION:
-      return "specification";
-    case TEST:
-      return "test";
-    default:
-      return "INVALID_SOFTWARE_PURPOSE_ID";
-  }
-}
-
-// SPDX Software NonElement Classes, Concrete
-
-cmSPDXContentIdentifier::cmSPDXContentIdentifier()
-  : cmSPDXIntegrityMethod(SOFTWARE_CONTENT_IDENTIFIER)
-{
-}
-
-Json::Value cmSPDXContentIdentifier::toJsonLD() const
-{
-  auto obj = cmSPDXIntegrityMethod::toJsonLD();
-  obj["type"] = "ContentIdentifier";
-  obj["contentIdentifierType"] = ContentIdentifierType.toJsonLD();
-  obj["contentIdentifierValue"] = ContentIdentifierValue;
-  return obj;
-}
-
-// SPDX Software Element Classes, Abstract
-
-cmSPDXSoftwareArtifact::cmSPDXSoftwareArtifact(
-  SPDXTypeId id, cmSPDXCreationInfo const& creationInfo)
-  : cmSPDXArtifact(id, creationInfo)
-{
-}
-
-Json::Value cmSPDXSoftwareArtifact::toJsonLD() const
-{
-  auto obj = cmSPDXArtifact::toJsonLD();
-  addOptionalSPDXValue(obj, "additionalPurpose", AdditionalPurpose);
-  addOptionalSPDXValue(obj, "attributionText", AttributionText);
-  addOptionalSPDXValue(obj, "contentIdentifier", ContentIdentifier);
-  addOptionalSPDXValue(obj, "copyrightText", CopyrightText);
-  addOptionalSPDXValue(obj, "primaryPurpose", PrimaryPurpose);
-  return obj;
-}
-
-// SPDX Software Element Classes, Concrete
-
-cmSPDXFile::cmSPDXFile(cmSPDXCreationInfo const& creationInfo)
-  : cmSPDXSoftwareArtifact(SOFTWARE_FILE, creationInfo)
-{
-}
-
-Json::Value cmSPDXFile::toJsonLD() const
-{
-  auto obj = cmSPDXSoftwareArtifact::toJsonLD();
-  obj["type"] = "File";
-  addOptionalSPDXValue(obj, "contentType", ContentType);
-  addOptionalSPDXValue(obj, "fileKind", FileKind);
-  return obj;
-}
-
-cmSPDXPackage::cmSPDXPackage(cmSPDXCreationInfo const& creationInfo)
-  : cmSPDXSoftwareArtifact(SOFTWARE_PACKAGE, creationInfo)
-{
-}
-
-Json::Value cmSPDXPackage::toJsonLD() const
-{
-  auto obj = cmSPDXSoftwareArtifact::toJsonLD();
-  obj["type"] = "Package";
-  addOptionalSPDXValue(obj, "downloadLocation", DownloadLocation);
-  addOptionalSPDXValue(obj, "homePage", HomePage);
-  addOptionalSPDXValue(obj, "packageUrl", PackageUrl);
-  addOptionalSPDXValue(obj, "packageVersion", PackageVersion);
-  addOptionalSPDXValue(obj, "sourceInfo", SourceInfo);
-  return obj;
-}
-
-cmSPDXSbom::cmSPDXSbom(cmSPDXCreationInfo const& creationInfo)
-  : cmSPDXBomAbstract(SOFTWARE_SBOM, creationInfo)
-{
-}
-
-Json::Value cmSPDXSbom::toJsonLD() const
-{
-  auto obj = cmSPDXBomAbstract::toJsonLD();
-  obj["type"] = "Sbom";
-  addOptionalSPDXValue(obj, "sbomType", SbomType);
-  return obj;
-}
-
-cmSPDXSnippet::cmSPDXSnippet(cmSPDXCreationInfo const& creationInfo)
-  : cmSPDXSoftwareArtifact(SOFTWARE_SNIPPET, creationInfo)
-{
-}
-
-Json::Value cmSPDXSnippet::toJsonLD() const
-{
-  auto obj = cmSPDXSoftwareArtifact::toJsonLD();
-  obj["type"] = "Snippet";
-  addOptionalSPDXValue(obj, "byteRange", ByteRange);
-  addOptionalSPDXValue(obj, "lineRange", LineRange);
-  obj["snippetFromFile"] = SnippetFromFile.toJsonLD();
-  return obj;
-}
-
-// SPDX SimpleLicensing Element Classes, Concrete
-
-cmSPDXLicenseExpression::cmSPDXLicenseExpression(
-  cmSPDXCreationInfo const& creationInfo)
-  : cmSPDXAnyLicenseInfo(SIMPLE_LICENSING_LICENSE_EXPRESSION, creationInfo)
-{
-}
-
-Json::Value cmSPDXLicenseExpression::toJsonLD() const
-{
-  auto obj = cmSPDXAnyLicenseInfo::toJsonLD();
-  obj["type"] = "LicenseExpression";
-  addOptionalSPDXValue(obj, "customIdToUri", CustomIdToUri);
-  obj["licenseExpression"] = LicenseExpression;
-  addOptionalSPDXValue(obj, "licenseListVersion", LicenseListVersion);
-  return obj;
-}
-
-cmSPDXSimpleLicensingText::cmSPDXSimpleLicensingText(
-  cmSPDXCreationInfo const& creationInfo)
-  : cmSPDXElement(SIMPLE_LICENSING_SIMPLE_LICENSING_TEXT, creationInfo)
-{
-}
-
-Json::Value cmSPDXSimpleLicensingText::toJsonLD() const
-{
-  auto obj = cmSPDXElement::toJsonLD();
-  obj["type"] = "SimpleLicensingText";
-  obj["licenseText"] = LicenseText;
-  return obj;
-}
-
-// Graph Manipulation
-
-#define X_SPDX(classtype, enumid, member, camel)                              \
-  template <>                                                                 \
-  cmSPDXSerializationBase::SPDXTypeId cmSPDXGetTypeId<classtype>()            \
-  {                                                                           \
-    return cmSPDXSerializationBase::enumid;                                   \
-  }                                                                           \
-                                                                              \
-  template <>                                                                 \
-  std::string cmSPDXGetTypeName<classtype>()                                  \
-  {                                                                           \
-    return #camel;                                                            \
-  }                                                                           \
-                                                                              \
-  cmSPDXObject::cmSPDXObject(classtype val)                                   \
-    : member(std::move(val)) {};                                              \
-                                                                              \
-  void cmSPDXObject::get(classtype** ptr)                                     \
-  {                                                                           \
-    *ptr = SerializationBase.getTypeId() == cmSPDXSerializationBase::enumid   \
-      ? &member                                                               \
-      : nullptr;                                                              \
-  }
-#include "cmSPDXTypes.def"
-
-cmSPDXObject::cmSPDXObject()
-  : IdentifierReference("UNINITIALIZED_SPDX_OBJECT")
-{
-}
-
-cmSPDXObject::cmSPDXObject(cmSPDXObject const& other)
-{
-  switch (other.SerializationBase.getTypeId()) {
-#define X_SPDX(classtype, enumid, member, camel)                              \
-  case cmSPDXSerializationBase::enumid:                                       \
-    new (&member) classtype(other.member);                                    \
-    break;
-#include "cmSPDXTypes.def"
-    default:
-      new (&IdentifierReference)
-        cmSPDXIdentifierReference("UNINITIALIZED_SPDX_OBJECT");
-  }
-}
-
-cmSPDXObject::cmSPDXObject(cmSPDXObject&& other) noexcept
-{
-  switch (other.SerializationBase.getTypeId()) {
-#define X_SPDX(classtype, enumid, member, camel)                              \
-  case cmSPDXSerializationBase::enumid:                                       \
-    new (&member) classtype(std::move(other.member));                         \
-    break;
-#include "cmSPDXTypes.def"
-    default:
-      new (&IdentifierReference)
-        cmSPDXIdentifierReference("UNINITIALIZED_SPDX_OBJECT");
-  }
-}
-
-cmSPDXObject& cmSPDXObject::operator=(cmSPDXObject const& other)
-{
-  this->~cmSPDXObject();
-  new (this) cmSPDXObject(other);
-  return *this;
-}
-
-cmSPDXObject& cmSPDXObject::operator=(cmSPDXObject&& other) noexcept
-{
-  this->~cmSPDXObject();
-  new (this) cmSPDXObject(std::move(other));
-  return *this;
-}
-
-cmSPDXObject::~cmSPDXObject()
-{
-  switch (SerializationBase.getTypeId()) {
-#define X_SPDX(classtype, enumid, member, camel)                              \
-  case cmSPDXSerializationBase::enumid:                                       \
-    member.~classtype();                                                      \
-    break;
-#include "cmSPDXTypes.def"
-    default:
-      break;
-  }
-}
-
-Json::Value cmSPDXObject::toJsonLD() const
-{
-  switch (SerializationBase.getTypeId()) {
-#define X_SPDX(classtype, enumid, member, camel)                              \
-  case cmSPDXSerializationBase::enumid:                                       \
-    return member.toJsonLD();
-#include "cmSPDXTypes.def"
-    default:
-      return "INVALID_SPDX_OBJECT_TYPE_ID";
-  }
-}
-
-cmSPDXSimpleGraph::cmSPDXSimpleGraph(std::string iriBase,
-                                     cmSPDXCreationInfo creationInfo)
-  : IRIBase(std::move(iriBase))
-  , CreationInfo(&insert<cmSPDXCreationInfo>(std::move(creationInfo)))
-{
-}
-
-cmSPDXCreationInfo& cmSPDXSimpleGraph::getCreationInfo()
-{
-  return *CreationInfo;
-}
-
-Json::Value cmSPDXSimpleGraph::toJsonLD()
-{
-  Json::Value obj(Json::objectValue);
-  obj["@context"] = "https://spdx.org/rdf/3.0.1/spdx-context.jsonld";
-
-  auto& graph = obj["@graph"];
-  for (auto const& it : Graph) {
-    graph.append(it.second.toJsonLD());
-  }
-
-  return obj;
-}
diff --git a/Source/cmSPDXSerializer.h b/Source/cmSPDXSerializer.h
deleted file mode 100644
index 65bf214..0000000
--- a/Source/cmSPDXSerializer.h
+++ /dev/null
@@ -1,1008 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
-   file LICENSE.rst or https://cmake.org/licensing for details.  */
-#pragma once
-
-#include <array>
-#include <cstddef>
-#include <map>
-#include <new>
-#include <string>
-#include <tuple>
-#include <utility>
-#include <vector>
-
-#include <cm/optional>
-#include <cm/type_traits>
-
-#include <cm3p/json/value.h>
-
-#include "cmStringAlgorithms.h"
-
-// Base Class
-
-struct cmSPDXSerializationBase
-{
-  enum SPDXTypeId
-  {
-    INVALID = -1,
-    NULL_ID = 0,
-
-#define X_SPDX(classtype, enumid, title, camel) enumid,
-#include "cmSPDXTypes.def"
-
-    SPDX_TYPE_ID_MAX,
-  };
-
-  SPDXTypeId getTypeId() const;
-
-  std::string NodeId;
-
-protected:
-  cmSPDXSerializationBase(SPDXTypeId id);
-  cmSPDXSerializationBase(SPDXTypeId id, std::string nodeId);
-
-private:
-  SPDXTypeId TypeId;
-};
-
-// Convenience Classes
-
-struct cmSPDXIdentifierReference : cmSPDXSerializationBase
-{
-  cmSPDXIdentifierReference();
-  cmSPDXIdentifierReference(cmSPDXSerializationBase const& ref);
-  cmSPDXIdentifierReference(std::string const& ref);
-
-  Json::Value toJsonLD() const;
-};
-
-struct cmSPDXNonElementBase : cmSPDXSerializationBase
-{
-protected:
-  cmSPDXNonElementBase(SPDXTypeId id);
-
-  Json::Value toJsonLD() const;
-};
-
-// SPDX Core Data Types
-
-// Nominally these are supposed to be validated strings
-using cmSPDXDateTime = std::string;
-using cmSPDXMediaType = std::string;
-using cmSPDXSemVer = std::string;
-
-// SPDX Core Enums
-
-struct cmSPDXAnnotationType
-{
-  enum cmSPDXAnnotationTypeId
-  {
-    INVALID = -1,
-    NULL_ID = 0,
-    OTHER,
-    REVIEW,
-  };
-
-  cmSPDXAnnotationTypeId TypeId;
-
-  cmSPDXAnnotationType(cmSPDXAnnotationTypeId typeId = NULL_ID);
-
-  Json::Value toJsonLD() const;
-};
-
-struct cmSPDXExternalIdentifierType
-{
-  enum cmSPDXExternalIdentifierTypeId
-  {
-    INVALID = -1,
-    NULL_ID = 0,
-    CPE22,
-    CPE23,
-    CVE,
-    EMAIL,
-    GITOID,
-    OTHER,
-    PACKAGE_URL,
-    SECURITY_OTHER,
-    SWHID,
-    SWID,
-    URL_SCHEME,
-  };
-
-  cmSPDXExternalIdentifierTypeId TypeId;
-
-  cmSPDXExternalIdentifierType(
-    cmSPDXExternalIdentifierTypeId typeId = NULL_ID);
-
-  Json::Value toJsonLD() const;
-};
-
-struct cmSPDXExternalRefType
-{
-  enum cmSPDXExternalRefTypeId
-  {
-    INVALID = -1,
-    NULL_ID = 0,
-    ALT_DOWNLOAD_LOCATION,
-    ALT_WEB_PAGE,
-    BINARY_ARTIFACT,
-    BOWER,
-    BUILD_META,
-    BUILD_SYSTEM,
-    CERTIFICATION_REPORT,
-    CHAT,
-    COMPONENT_ANALYSIS_REPORT,
-    CWE,
-    DOCUMENTATION,
-    DYNAMIC_ANALYSIS_REPORT,
-    EOL_NOTICE,
-    EXPORT_CONTROL_ASSESSMENT,
-    FUNDING,
-    ISSUE_TRACKER,
-    LICENSE,
-    MAILING_LIST,
-    MAVEN_CENTRAL,
-    METRICS,
-    NPM,
-    NUGET,
-    OTHER,
-    PRIVACY_ASSESSMENT,
-    PRODUCT_METADATA,
-    PURCHASE_ORDER,
-    QUALITY_ASSESSMENT_REPORT,
-    RELEASE_HISTORY,
-    RELEASE_NOTES,
-    RISK_ASSESSMENT,
-    RUNTIME_ANALYSIS_REPORT,
-    SECURE_SOFTWARE_ATTESTATION,
-    SECURITY_ADVERSARY_MODEL,
-    SECURITY_ADVISORY,
-    SECURITY_FIX,
-    SECURITY_OTHER,
-    SECURITY_PEN_TEST_REPORT,
-    SECURITY_POLICY,
-    SECURITY_THREAT_MODEL,
-    SOCIAL_MEDIA,
-    SOURCE_ARTIFACT,
-    STATIC_ANALYSIS_REPORT,
-    SUPPORT,
-    VCS,
-    VULNERABILITY_DISCLOSURE_REPORT,
-    VULNERABILITY_EXPLOITABILITY_ASSESSMENT,
-  };
-
-  cmSPDXExternalRefTypeId TypeId;
-
-  cmSPDXExternalRefType(cmSPDXExternalRefTypeId typeId = NULL_ID);
-
-  Json::Value toJsonLD() const;
-};
-
-struct cmSPDXHashAlgorithm
-{
-  enum cmSPDXHashAlgorithmId
-  {
-    INVALID = -1,
-    NULL_ID = 0,
-    ADLER32,
-    BLAKE2B256,
-    BLAKE2B384,
-    BLAKE2B512,
-    BLAKE3,
-    CRYSTALS_DILITHIUM,
-    CRYSTALS_KYBER,
-    FALCON,
-    MD2,
-    MD4,
-    MD5,
-    MD6,
-    OTHER,
-    SHA1,
-    SHA224,
-    SHA256,
-    SHA384,
-    SHA3_224,
-    SHA3_256,
-    SHA3_384,
-    SHA3_512,
-    SHA512,
-  };
-
-  cmSPDXHashAlgorithmId TypeId;
-
-  cmSPDXHashAlgorithm(cmSPDXHashAlgorithmId typeId = NULL_ID);
-
-  Json::Value toJsonLD() const;
-};
-
-struct cmSPDXLifecycleScopeType
-{
-  enum cmSPDXLifecycleScopeTypeId
-  {
-    INVALID = -1,
-    NULL_ID = 0,
-    BUILD,
-    DESIGN,
-    DEVELOPMENT,
-    OTHER,
-    RUNTIME,
-    TEST,
-  };
-
-  cmSPDXLifecycleScopeTypeId TypeId;
-
-  cmSPDXLifecycleScopeType(cmSPDXLifecycleScopeTypeId typeId = NULL_ID);
-
-  Json::Value toJsonLD() const;
-};
-
-struct cmSPDXProfileIdentifierType
-{
-  enum cmSPDXProfileIdentifierTypeId
-  {
-    INVALID = -1,
-    NULL_ID = 0,
-    AI,
-    BUILD,
-    CORE,
-    DATASET,
-    EXPANDED_LICENSING,
-    EXTENSION,
-    LITE,
-    SECURITY,
-    SIMPLE_LICENSING,
-    SOFTWARE,
-  };
-
-  cmSPDXProfileIdentifierTypeId TypeId;
-
-  cmSPDXProfileIdentifierType(cmSPDXProfileIdentifierTypeId typeId = NULL_ID);
-
-  Json::Value toJsonLD() const;
-};
-
-struct cmSPDXRelationshipCompletenessType
-{
-  enum cmSPDXRelationshipCompletenessTypeId
-  {
-    INVALID = -1,
-    NULL_ID = 0,
-    COMPLETE,
-    INCOMPLETE,
-    NO_ASSERTION,
-  };
-
-  cmSPDXRelationshipCompletenessTypeId TypeId;
-
-  cmSPDXRelationshipCompletenessType(
-    cmSPDXRelationshipCompletenessTypeId typeId = NULL_ID);
-
-  Json::Value toJsonLD() const;
-};
-
-struct cmSPDXRelationshipType
-{
-  enum cmSPDXRelationshipTypeId
-  {
-    INVALID = -1,
-    NULL_ID = 0,
-    AFFECTS,
-    AMENDED_BY,
-    ANCESTOR_OF,
-    AVAILABLE_FROM,
-    CONFIGURES,
-    CONTAINS,
-    COORDINATED_BY,
-    COPIED_TO,
-    DELEGATED_TO,
-    DEPENDS_ON,
-    DESCENDANT_OF,
-    DESCRIBES,
-    DOES_NOT_AFFECT,
-    EXPANDS_TO,
-    EXPLOIT_CREATED_BY,
-    FIXED_BY,
-    FIXED_IN,
-    FOUND_BY,
-    GENERATES,
-    HAS_ADDED_FILE,
-    HAS_ASSESSMENT_FOR,
-    HAS_ASSOCIATED_VULNERABILITY,
-    HAS_CONCLUDED_LICENSE,
-    HAS_DATA_FILE,
-    HAS_DECLARED_LICENSE,
-    HAS_DELETED_FILE,
-    HAS_DEPENDENCY_MANIFEST,
-    HAS_DISTRIBUTION_ARTIFACT,
-    HAS_DOCUMENTATION,
-    HAS_DYNAMIC_LINK,
-    HAS_EVIDENCE,
-    HAS_EXAMPLE,
-    HAS_HOST,
-    HAS_INPUT,
-    HAS_METADATA,
-    HAS_OPTIONAL_COMPONENT,
-    HAS_OPTIONAL_DEPENDENCY,
-    HAS_OUTPUT,
-    HAS_PREREQUISITE,
-    HAS_PROVIDED_DEPENDENCY,
-    HAS_REQUIREMENT,
-    HAS_SPECIFICATION,
-    HAS_STATIC_LINK,
-    HAS_TEST,
-    HAS_TEST_CASE,
-    HAS_VARIANT,
-    INVOKED_BY,
-    MODIFIED_BY,
-    OTHER,
-    PACKAGED_BY,
-    PATCHED_BY,
-    PUBLISHED_BY,
-    REPORTED_BY,
-    REPUBLISHED_BY,
-    SERIALIZED_IN_ARTIFACT,
-    TESTED_ON,
-    TRAINED_ON,
-    UNDER_INVESTIGATION_FOR,
-    USES_TOOL,
-  };
-
-  cmSPDXRelationshipTypeId TypeId;
-
-  cmSPDXRelationshipType(cmSPDXRelationshipTypeId typeId = NULL_ID);
-
-  Json::Value toJsonLD() const;
-};
-
-struct cmSPDXSupportType
-{
-  enum cmSPDXSupportTypeId
-  {
-    INVALID = -1,
-    NULL_ID = 0,
-    DEPLOYED,
-    DEVELOPMENT,
-    END_OF_SUPPORT,
-    LIMITED_SUPPORT,
-    NO_ASSERTION,
-    NO_SUPPORT,
-    SUPPORT,
-  };
-
-  cmSPDXSupportTypeId TypeId;
-
-  cmSPDXSupportType(cmSPDXSupportTypeId typeId = NULL_ID);
-
-  Json::Value toJsonLD() const;
-};
-
-// SPDX Core NonElement Classes, Abstract
-
-struct cmSPDXIntegrityMethod : cmSPDXNonElementBase
-{
-
-  cm::optional<std::string> Comment;
-
-protected:
-  cmSPDXIntegrityMethod(SPDXTypeId id);
-
-  Json::Value toJsonLD() const;
-};
-
-// SPDX Core NonElement Classes, Concrete
-
-struct cmSPDXCreationInfo : cmSPDXNonElementBase
-{
-  cm::optional<std::string> Comment;
-  cmSPDXDateTime Created;
-  std::vector<cmSPDXIdentifierReference> CreatedBy;
-  cm::optional<std::vector<cmSPDXIdentifierReference>> CreatedUsing;
-
-  cmSPDXCreationInfo();
-
-  Json::Value toJsonLD() const;
-};
-
-struct cmSPDXDictionaryEntry : cmSPDXNonElementBase
-{
-  std::string Key;
-  cm::optional<std::string> Value;
-
-  cmSPDXDictionaryEntry();
-  cmSPDXDictionaryEntry(std::string key);
-  cmSPDXDictionaryEntry(std::string key, std::string val);
-
-  Json::Value toJsonLD() const;
-};
-
-struct cmSPDXExternalIdentifier : cmSPDXNonElementBase
-{
-  cm::optional<std::string> Comment;
-  cmSPDXExternalIdentifierType ExternalIdentifierType;
-  std::string Identifier;
-  cm::optional<std::vector<std::string>> IdentifierLocator;
-  cm::optional<std::string> IssuingAuthority;
-
-  cmSPDXExternalIdentifier();
-
-  Json::Value toJsonLD() const;
-};
-
-struct cmSPDXExternalMap : cmSPDXNonElementBase
-{
-  cm::optional<cmSPDXIdentifierReference> DefiningArtifact;
-  std::string ExternalSpdxId;
-  cm::optional<std::string> LocationHint;
-  cm::optional<std::vector<cmSPDXIdentifierReference>> IntegrityMethod;
-
-  cmSPDXExternalMap();
-
-  Json::Value toJsonLD() const;
-};
-
-struct cmSPDXExternalRef : cmSPDXNonElementBase
-{
-  cm::optional<std::string> Comment;
-  cm::optional<cmSPDXMediaType> ContentType;
-  cm::optional<cmSPDXExternalRefType> ExternalRefType;
-  cm::optional<std::vector<std::string>> Locator;
-
-  cmSPDXExternalRef();
-
-  Json::Value toJsonLD() const;
-};
-
-struct cmSPDXHash : cmSPDXIntegrityMethod
-{
-  cmSPDXHashAlgorithm Algorithm;
-  std::string HashValue;
-
-  cmSPDXHash();
-
-  Json::Value toJsonLD() const;
-};
-
-struct cmSPDXNamespaceMap : cmSPDXNonElementBase
-{
-  std::string Namespace;
-  std::string Prefix;
-
-  cmSPDXNamespaceMap();
-
-  Json::Value toJsonLD() const;
-};
-
-struct cmSPDXPackageVerificationCode : cmSPDXIntegrityMethod
-{
-  cmSPDXHashAlgorithm Algorithm;
-  std::string HashValue;
-  cm::optional<std::vector<std::string>> PackageVerificationCodeExcludedFile;
-
-  cmSPDXPackageVerificationCode();
-
-  Json::Value toJsonLD() const;
-};
-
-struct cmSPDXPositiveIntegerRange : cmSPDXNonElementBase
-{
-  unsigned int BeginIntegerRange;
-  unsigned int EndIntegerRange;
-
-  cmSPDXPositiveIntegerRange(unsigned int beingIntegerRange = 0,
-                             unsigned int endIntegerRange = 0);
-
-  Json::Value toJsonLD() const;
-};
-
-// SPDX Core Element Classes, Abstract
-
-struct cmSPDXElement : cmSPDXSerializationBase
-{
-  cm::optional<std::string> Comment;
-  cmSPDXIdentifierReference CreationInfo;
-  cm::optional<std::string> Description;
-  cm::optional<std::vector<cmSPDXIdentifierReference>> Extension;
-  cm::optional<std::vector<cmSPDXIdentifierReference>> ExternalIdentifier;
-  cm::optional<std::vector<cmSPDXIdentifierReference>> ExternalRef;
-  cm::optional<std::string> Name;
-  // SpdxId is the NodeId
-  cm::optional<std::string> Summary;
-  cm::optional<std::vector<cmSPDXIdentifierReference>> VerifiedUsing;
-
-protected:
-  cmSPDXElement(SPDXTypeId id, cmSPDXCreationInfo const& creationInfo);
-
-  Json::Value toJsonLD() const;
-};
-
-struct cmSPDXArtifact : cmSPDXElement
-{
-  cm::optional<cmSPDXDateTime> BuiltTime;
-  cm::optional<std::vector<cmSPDXIdentifierReference>> OriginatedBy;
-  cm::optional<cmSPDXDateTime> ReleaseTime;
-  cm::optional<std::vector<std::string>> StandardName;
-  cm::optional<cmSPDXIdentifierReference> SuppliedBy;
-  cm::optional<std::vector<cmSPDXSupportType>> SupportType;
-  cm::optional<cmSPDXDateTime> ValidUntilTime;
-
-protected:
-  cmSPDXArtifact(SPDXTypeId id, cmSPDXCreationInfo const& creationInfo);
-
-  Json::Value toJsonLD() const;
-};
-
-struct cmSPDXElementCollection : cmSPDXElement
-{
-  cm::optional<std::vector<cmSPDXIdentifierReference>> Element;
-  cm::optional<std::vector<cmSPDXProfileIdentifierType>> ProfileConformance;
-  cm::optional<std::vector<cmSPDXIdentifierReference>> RootElement;
-
-protected:
-  cmSPDXElementCollection(SPDXTypeId id,
-                          cmSPDXCreationInfo const& creationInfo);
-
-  Json::Value toJsonLD() const;
-};
-
-// SPDX Implicit Core Element Classes, Abstract
-
-// Nominally an inheritable class, but adds nothing to Element
-using cmSPDXAgentAbstract = cmSPDXElement;
-
-struct cmSPDXBundleAbstract : cmSPDXElementCollection
-{
-  std::string Context;
-
-protected:
-  cmSPDXBundleAbstract(SPDXTypeId id, cmSPDXCreationInfo const& creationInfo);
-
-  Json::Value toJsonLD() const;
-};
-
-// Nominally an inheritable class, but adds nothing to Bundle
-using cmSPDXBomAbstract = cmSPDXBundleAbstract;
-
-struct cmSPDXRelationshipAbstract : cmSPDXElement
-{
-  cm::optional<cmSPDXRelationshipCompletenessType> Completeness;
-  cm::optional<cmSPDXDateTime> EndTime;
-  cmSPDXIdentifierReference From;
-  cmSPDXRelationshipType RelationshipType;
-  cm::optional<cmSPDXDateTime> StartTime;
-  std::vector<cmSPDXIdentifierReference> To;
-
-protected:
-  cmSPDXRelationshipAbstract(SPDXTypeId id,
-                             cmSPDXCreationInfo const& creationInfo);
-
-  Json::Value toJsonLD() const;
-};
-
-// SPDX Core Element Classes, Concrete
-
-struct cmSPDXAgent : cmSPDXAgentAbstract
-{
-  cmSPDXAgent(cmSPDXCreationInfo const& creationInfo);
-
-  Json::Value toJsonLD() const;
-};
-
-struct cmSPDXAnnotation : cmSPDXElement
-{
-  cmSPDXAnnotationType AnnotationType;
-  cm::optional<cmSPDXMediaType> ContentType;
-  cm::optional<std::string> Statement;
-  cmSPDXIdentifierReference Subject;
-
-  cmSPDXAnnotation(cmSPDXCreationInfo const& creationInfo,
-                   cmSPDXIdentifierReference subject = {});
-
-  Json::Value toJsonLD() const;
-};
-
-struct cmSPDXBom : cmSPDXBomAbstract
-{
-  cmSPDXBom(cmSPDXCreationInfo const& creationInfo);
-
-  Json::Value toJsonLD() const;
-};
-
-struct cmSPDXBundle : cmSPDXBundleAbstract
-{
-  cmSPDXBundle(cmSPDXCreationInfo const& creationInfo);
-
-  Json::Value toJsonLD() const;
-};
-
-struct cmSPDXIndividualElement : cmSPDXElement
-{
-  cmSPDXIndividualElement(cmSPDXCreationInfo const& creationInfo);
-
-  Json::Value toJsonLD() const;
-};
-
-struct cmSPDXLifecycleScopedRelationship : cmSPDXRelationshipAbstract
-{
-  cm::optional<cmSPDXLifecycleScopeType> Scope;
-
-  cmSPDXLifecycleScopedRelationship(cmSPDXCreationInfo const& creationInfo);
-
-  Json::Value toJsonLD() const;
-};
-
-struct cmSPDXOrganization : cmSPDXAgentAbstract
-{
-  cmSPDXOrganization(cmSPDXCreationInfo const& creationInfo);
-
-  Json::Value toJsonLD() const;
-};
-
-struct cmSPDXPerson : cmSPDXAgentAbstract
-{
-  cmSPDXPerson(cmSPDXCreationInfo const& creationInfo);
-
-  Json::Value toJsonLD() const;
-};
-
-struct cmSPDXRelationship : cmSPDXRelationshipAbstract
-{
-  cmSPDXRelationship(cmSPDXCreationInfo const& creationInfo);
-
-  Json::Value toJsonLD() const;
-};
-
-struct cmSPDXSoftwareAgent : cmSPDXAgentAbstract
-{
-  cmSPDXSoftwareAgent(cmSPDXCreationInfo const& creationInfo);
-
-  Json::Value toJsonLD() const;
-};
-
-struct cmSPDXSpdxDocument : cmSPDXElementCollection
-{
-  cm::optional<cmSPDXIdentifierReference> DataLicense;
-  cm::optional<cmSPDXIdentifierReference> ExternalMap;
-  cm::optional<cmSPDXIdentifierReference> NamespaceMap;
-
-  cmSPDXSpdxDocument(cmSPDXCreationInfo const& creationInfo);
-
-  Json::Value toJsonLD() const;
-};
-
-struct cmSPDXTool : cmSPDXElement
-{
-  cmSPDXTool(cmSPDXCreationInfo const& creationInfo);
-
-  Json::Value toJsonLD() const;
-};
-
-// SPDX Software Enums
-
-struct cmSPDXContentIdentifierType
-{
-  enum cmSPDXContentIdentifierTypeId
-  {
-    INVALID = -1,
-    NULL_ID = 0,
-    GITOID,
-    SWHID,
-  };
-
-  cmSPDXContentIdentifierTypeId TypeId;
-
-  cmSPDXContentIdentifierType(cmSPDXContentIdentifierTypeId typeId = NULL_ID);
-
-  Json::Value toJsonLD() const;
-};
-
-struct cmSPDXFileKindType
-{
-  enum cmSPDXFileKindTypeId
-  {
-    INVALID = -1,
-    NULL_ID = 0,
-    DIRECTORY,
-    FILE,
-  };
-
-  cmSPDXFileKindTypeId TypeId;
-
-  cmSPDXFileKindType(cmSPDXFileKindTypeId typeId = NULL_ID);
-
-  Json::Value toJsonLD() const;
-};
-
-struct cmSPDXSbomType
-{
-  enum cmSPDXSbomTypeId
-  {
-    INVALID = -1,
-    NULL_ID = 0,
-    ANALYZED,
-    BUILD,
-    DEPLOYED,
-    DESIGN,
-    RUNTIME,
-    SOURCE,
-  };
-
-  cmSPDXSbomTypeId TypeId;
-
-  cmSPDXSbomType(cmSPDXSbomTypeId typeId = NULL_ID);
-
-  Json::Value toJsonLD() const;
-};
-
-struct cmSPDXSoftwarePurpose
-{
-  enum cmSPDXSoftwarePurposeId
-  {
-    INVALID = -1,
-    NULL_ID = 0,
-    APPLICATION,
-    ARCHIVE,
-    BOM,
-    CONFIGURATION,
-    CONTAINER,
-    DATA,
-    DEVICE,
-    DEVICE_DRIVER,
-    DISK_IMAGE,
-    DOCUMENTATION,
-    EVIDENCE,
-    EXECUTABLE,
-    FILE,
-    FILESYSTEM_IMAGE,
-    FIRMWARE,
-    FRAMEWORK,
-    INSTALL,
-    LIBRARY,
-    MANIFEST,
-    MODEL,
-    MODULE,
-    OPERATING_SYSTEM,
-    OTHER,
-    PATCH,
-    PLATFORM,
-    REQUIREMENT,
-    SOURCE,
-    SPECIFICATION,
-    TEST,
-  };
-
-  cmSPDXSoftwarePurposeId TypeId;
-
-  cmSPDXSoftwarePurpose(cmSPDXSoftwarePurposeId typeId = NULL_ID);
-
-  Json::Value toJsonLD() const;
-};
-
-// SPDX Software NonElement Classes, Concrete
-
-struct cmSPDXContentIdentifier : cmSPDXIntegrityMethod
-{
-  cmSPDXContentIdentifierType ContentIdentifierType;
-  std::string ContentIdentifierValue;
-
-  cmSPDXContentIdentifier();
-
-  Json::Value toJsonLD() const;
-};
-
-// SPDX Software Element Classes, Abstract
-
-struct cmSPDXSoftwareArtifact : cmSPDXArtifact
-{
-  cm::optional<std::vector<cmSPDXSoftwarePurpose>> AdditionalPurpose;
-  cm::optional<std::string> AttributionText;
-  cm::optional<cmSPDXIdentifierReference> ContentIdentifier;
-  cm::optional<std::string> CopyrightText;
-  cm::optional<cmSPDXSoftwarePurpose> PrimaryPurpose;
-
-protected:
-  cmSPDXSoftwareArtifact(SPDXTypeId id,
-                         cmSPDXCreationInfo const& creationInfo);
-
-  Json::Value toJsonLD() const;
-};
-
-// SPDX Software Element Classes, Concrete
-
-struct cmSPDXFile : cmSPDXSoftwareArtifact
-{
-  cm::optional<cmSPDXMediaType> ContentType;
-  cm::optional<cmSPDXFileKindType> FileKind;
-
-  cmSPDXFile(cmSPDXCreationInfo const& creationInfo);
-
-  Json::Value toJsonLD() const;
-};
-
-struct cmSPDXPackage : cmSPDXSoftwareArtifact
-{
-  cm::optional<std::string> DownloadLocation;
-  cm::optional<std::string> HomePage;
-  cm::optional<std::string> PackageUrl;
-  cm::optional<std::string> PackageVersion;
-  cm::optional<std::string> SourceInfo;
-
-  cmSPDXPackage(cmSPDXCreationInfo const& creationInfo);
-
-  Json::Value toJsonLD() const;
-};
-
-struct cmSPDXSbom : cmSPDXBomAbstract
-{
-  cm::optional<std::vector<cmSPDXSbomType>> SbomType;
-
-  cmSPDXSbom(cmSPDXCreationInfo const& creationInfo);
-
-  Json::Value toJsonLD() const;
-};
-
-struct cmSPDXSnippet : cmSPDXSoftwareArtifact
-{
-  cm::optional<cmSPDXIdentifierReference> ByteRange;
-  cm::optional<cmSPDXIdentifierReference> LineRange;
-  cmSPDXIdentifierReference SnippetFromFile;
-
-  cmSPDXSnippet(cmSPDXCreationInfo const& creationInfo);
-
-  Json::Value toJsonLD() const;
-};
-
-// SPDX SimpleLicensing Element Classes, Abstract
-
-// Nominally an inheritable class, but adds nothing to Element
-using cmSPDXAnyLicenseInfo = cmSPDXElement;
-
-// SPDX SimpleLicensing Element Classes, Concrete
-
-struct cmSPDXLicenseExpression : cmSPDXAnyLicenseInfo
-{
-  cm::optional<std::vector<cmSPDXIdentifierReference>> CustomIdToUri;
-  std::string LicenseExpression;
-  cm::optional<cmSPDXSemVer> LicenseListVersion;
-
-  cmSPDXLicenseExpression(cmSPDXCreationInfo const& CreationInfo);
-
-  Json::Value toJsonLD() const;
-};
-
-struct cmSPDXSimpleLicensingText : cmSPDXElement
-{
-  std::string LicenseText;
-
-  cmSPDXSimpleLicensingText(cmSPDXCreationInfo const& CreationInfo);
-
-  Json::Value toJsonLD() const;
-};
-
-// Graph Manipulation
-
-template <typename T>
-cmSPDXSerializationBase::SPDXTypeId cmSPDXGetTypeId();
-
-template <typename T>
-std::string cmSPDXGetTypeName();
-
-#define X_SPDX(classtype, enumid, member, camel)                              \
-  template <>                                                                 \
-  cmSPDXSerializationBase::SPDXTypeId cmSPDXGetTypeId<classtype>();           \
-                                                                              \
-  template <>                                                                 \
-  std::string cmSPDXGetTypeName<classtype>();
-#include "cmSPDXTypes.def"
-
-template <class T>
-struct cmSPDXTag
-{
-  using type = T;
-};
-
-union cmSPDXObject
-{
-
-  cmSPDXSerializationBase SerializationBase;
-
-  cmSPDXObject();
-  cmSPDXObject(cmSPDXObject const& other);
-  cmSPDXObject(cmSPDXObject&& other) noexcept;
-
-#define X_SPDX(classtype, enumid, member, camel)                              \
-  classtype member;                                                           \
-  cmSPDXObject(classtype val);                                                \
-                                                                              \
-  template <typename... Args>                                                 \
-  cmSPDXObject(cmSPDXTag<classtype>, Args&&... args)                          \
-  {                                                                           \
-    new (&member) classtype(std::forward<Args>(args)...);                     \
-  }
-#include "cmSPDXTypes.def"
-
-  cmSPDXObject& operator=(cmSPDXObject const& other);
-  cmSPDXObject& operator=(cmSPDXObject&& other) noexcept;
-
-  ~cmSPDXObject();
-
-  template <typename T>
-  T* get()
-  {
-    T* ptr;
-    get(&ptr);
-    return ptr;
-  }
-
-  Json::Value toJsonLD() const;
-
-private:
-#define X_SPDX(classtype, enumid, member, camel) void get(classtype** ptr);
-#include "cmSPDXTypes.def"
-};
-
-struct cmSPDXSimpleGraph
-{
-  cmSPDXSimpleGraph(std::string iriBase, cmSPDXCreationInfo creationInfo = {});
-
-  template <typename T, typename... Args>
-  cm::enable_if_t<std::is_base_of<cmSPDXElement, T>::value, T>& insert(
-    Args&&... args)
-  {
-    std::string nodeId = cmStrCat(IRIBase, IRICount++);
-    auto const& it =
-      Graph.emplace(std::piecewise_construct, std::forward_as_tuple(nodeId),
-                    std::forward_as_tuple(cmSPDXTag<T>{}, *CreationInfo,
-                                          std::forward<Args>(args)...));
-    auto& node = *it.first->second.template get<T>();
-    node.NodeId = std::move(nodeId);
-    return node;
-  }
-
-  cmSPDXCreationInfo& getCreationInfo();
-
-  template <typename T, typename... Args>
-  cm::enable_if_t<std::is_base_of<cmSPDXNonElementBase, T>::value, T>& insert(
-    Args&&... args)
-  {
-    std::size_t nodeCount = BlankCounts[cmSPDXGetTypeId<T>()]++;
-    std::string nodeId =
-      cmStrCat("_:", cmSPDXGetTypeName<T>(), "_", nodeCount);
-    auto const& it = Graph.emplace(
-      std::piecewise_construct, std::forward_as_tuple(nodeId),
-      std::forward_as_tuple(cmSPDXTag<T>{}, std::forward<Args>(args)...));
-    auto& node = *it.first->second.template get<T>();
-    node.NodeId = std::move(nodeId);
-    return node;
-  }
-
-  template <typename T>
-  T* get(std::string const& key)
-  {
-    auto it = Graph.find(key);
-    if (it == Graph.end()) {
-      return nullptr;
-    }
-    return it->second.get<T>();
-  }
-
-  template <typename T>
-  T* get(cmSPDXIdentifierReference const& key)
-  {
-    auto it = Graph.find(key.NodeId);
-    if (it == Graph.end()) {
-      return nullptr;
-    }
-    return it->second.get<T>();
-  }
-
-  Json::Value toJsonLD();
-
-private:
-  std::string IRIBase;
-  std::size_t IRICount{ 0 };
-  std::array<std::size_t, cmSPDXSerializationBase::SPDX_TYPE_ID_MAX>
-    BlankCounts{};
-
-  std::map<std::string, cmSPDXObject> Graph;
-  cmSPDXCreationInfo* CreationInfo;
-};
diff --git a/Source/cmSPDXTypes.def b/Source/cmSPDXTypes.def
deleted file mode 100644
index 88d8043..0000000
--- a/Source/cmSPDXTypes.def
+++ /dev/null
@@ -1,54 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
-   file LICENSE.rst or https://cmake.org/licensing for details.  */
-#ifndef X_SPDX
-#  define X_SPDX(classtype, enumid, member, camel)
-#endif
-
-// Convenience
-X_SPDX(cmSPDXIdentifierReference, CM_IDENTIFIER_REFERENCE, IdentifierReference,
-       identifierReference)
-
-// Core
-X_SPDX(cmSPDXAgent, CORE_AGENT, Agent, agent)
-X_SPDX(cmSPDXAnnotation, CORE_ANNOTATION, Annotation, annotation)
-X_SPDX(cmSPDXBom, CORE_BOM, Bom, bom)
-X_SPDX(cmSPDXBundle, CORE_BUNDLE, Bundle, bundle)
-X_SPDX(cmSPDXCreationInfo, CORE_CREATION_INFO, CreationInfo, creationInfo)
-X_SPDX(cmSPDXDictionaryEntry, CORE_DICTIONARY_ENTRY, DictionaryEntry,
-       dictionaryEntry)
-X_SPDX(cmSPDXExternalIdentifier, CORE_EXTERNAL_IDENTIFIER, ExternalIdentifier,
-       externalIdentifier)
-X_SPDX(cmSPDXExternalMap, CORE_EXTERNAL_MAP, ExternalMap, externalMap)
-X_SPDX(cmSPDXExternalRef, CORE_EXTERNAL_REF, ExternalRef, externalRef)
-X_SPDX(cmSPDXHash, CORE_HASH, Hash, hash)
-X_SPDX(cmSPDXIndividualElement, CORE_INDIVIDUAL_ELEMENT, IndividualElement,
-       individualElement)
-X_SPDX(cmSPDXLifecycleScopedRelationship, CORE_LIFECYCLE_SCOPED_RELATIONSHIP,
-       LifecycleScopedRelationship, lifecycleScopedRelationship)
-X_SPDX(cmSPDXNamespaceMap, CORE_NAMESPACE_MAP, NamespaceMap, namespaceMap)
-X_SPDX(cmSPDXOrganization, CORE_ORGANIZATION, Organization, organization)
-X_SPDX(cmSPDXPackageVerificationCode, CORE_PACKAGE_VERIFICATION_CODE,
-       PackageVerificationCode, packageVerificationCode)
-X_SPDX(cmSPDXPerson, CORE_PERSON, Person, person)
-X_SPDX(cmSPDXPositiveIntegerRange, CORE_POSITIVE_INTEGER_RANGE,
-       PositiveIntegerRange, positiveIntegerRange)
-X_SPDX(cmSPDXRelationship, CORE_RELATIONSHIP, Relationship, relationship)
-X_SPDX(cmSPDXSoftwareAgent, CORE_SOFTWARE_AGENT, SoftwareAgent, softwareAgent)
-X_SPDX(cmSPDXSpdxDocument, CORE_SPDX_DOCUMENT, SpdxDocument, spdxDocument)
-X_SPDX(cmSPDXTool, CORE_TOOL, Tool, tool)
-
-// Software
-X_SPDX(cmSPDXContentIdentifier, SOFTWARE_CONTENT_IDENTIFIER, ContentIdentifier,
-       contentIdentifier)
-X_SPDX(cmSPDXFile, SOFTWARE_FILE, File, file)
-X_SPDX(cmSPDXPackage, SOFTWARE_PACKAGE, Package, package)
-X_SPDX(cmSPDXSbom, SOFTWARE_SBOM, Sbom, sbom)
-X_SPDX(cmSPDXSnippet, SOFTWARE_SNIPPET, Snippet, snippet)
-
-// SimpleLicensing
-X_SPDX(cmSPDXLicenseExpression, SIMPLE_LICENSING_LICENSE_EXPRESSION,
-       LicenseExpression, licenseExpression)
-X_SPDX(cmSPDXSimpleLicensingText, SIMPLE_LICENSING_SIMPLE_LICENSING_TEXT,
-       SimpleLicensingText, simpleLicensingText)
-
-#undef X_SPDX
diff --git a/Source/cmSarifLog.cxx b/Source/cmSarifLog.cxx
index 35b67f7..f251b9c 100644
--- a/Source/cmSarifLog.cxx
+++ b/Source/cmSarifLog.cxx
@@ -14,6 +14,7 @@
 
 #include "cmListFileCache.h"
 #include "cmMessageType.h"
+#include "cmState.h"
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
 #include "cmValue.h"
@@ -375,7 +376,7 @@
     // normal mode, the project variable `CMAKE_EXPORT_SARIF` can also enable
     // SARIF logging.
     return cm.GetSarifFilePath().has_value() ||
-      (cm.GetWorkingMode() == cmake::NORMAL_MODE &&
+      (cm.GetState()->GetRole() == cmState::Role::Project &&
        cm.GetCacheDefinition(cmSarif::PROJECT_SARIF_FILE_VARIABLE).IsOn());
   });
 
diff --git a/Source/cmSbomObject.h b/Source/cmSbomObject.h
new file mode 100644
index 0000000..3f42cfb
--- /dev/null
+++ b/Source/cmSbomObject.h
@@ -0,0 +1,270 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file LICENSE.rst or https://cmake.org/licensing for details.  */
+#pragma once
+
+#include <cstddef>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <cm/type_traits>
+
+#include "cmSbomSerializer.h"
+
+class cmSbomObject;
+
+template <typename T>
+inline void SerializeDispatch(T const& t, cmSbomSerializer& serializer)
+{
+  serializer.BeginObject();
+  t.Serialize(serializer);
+  serializer.EndObject();
+}
+
+template <typename T>
+inline void SerializeDispatch(T* p, cmSbomSerializer& serializer)
+{
+  if (p->SpdxId) {
+    serializer.AddReference(*p->SpdxId);
+  }
+}
+
+inline void SerializeDispatch(std::nullptr_t, cmSbomSerializer&)
+{
+}
+
+struct ObjectInterface
+{
+  virtual ObjectInterface* Copy(void* storage) const = 0;
+  virtual ObjectInterface* Move(void* storage) = 0;
+  virtual void* Addr() noexcept = 0;
+  virtual void const* Addr() const noexcept = 0;
+  virtual void SerializeImpl(cmSbomSerializer& os) const = 0;
+  virtual ~ObjectInterface() = default;
+
+  ObjectInterface() = default;
+  ObjectInterface(ObjectInterface const&) = default;
+  ObjectInterface& operator=(ObjectInterface const&) = default;
+  ObjectInterface(ObjectInterface&&) noexcept = default;
+  ObjectInterface& operator=(ObjectInterface&&) noexcept = default;
+};
+
+namespace impl {
+
+#if defined(__GLIBCXX__) && __GLIBCXX__ <= 20150623
+using max_align_t = ::max_align_t;
+#else
+using max_align_t = std::max_align_t;
+#endif
+
+enum class StorageKind
+{
+  Stack,
+  Heap
+};
+
+template <typename, StorageKind>
+struct Storage
+{
+};
+
+template <typename T>
+struct Storage<T, StorageKind::Stack> : ObjectInterface
+{
+  using ValueType = cm::decay_t<T>;
+
+  explicit Storage(T x)
+    : Value(std::move(x))
+  {
+  }
+
+  Storage(Storage&&) noexcept(
+    std::is_nothrow_move_constructible<ValueType>::value) = default;
+  ~Storage() override = default;
+
+  void* Addr() noexcept override { return std::addressof(Value); }
+  void const* Addr() const noexcept override { return std::addressof(Value); }
+
+  ValueType& get() { return Value; }
+  ValueType const& get() const { return Value; }
+
+private:
+  ValueType Value;
+};
+
+template <typename T>
+struct Storage<T, StorageKind::Heap> : ObjectInterface
+{
+  using ValueType = cm::decay_t<T>;
+
+  explicit Storage(T x)
+    : Ptr(new T(std::move(x)))
+  {
+  }
+
+  Storage(Storage&&) noexcept = default;
+  ~Storage() override = default;
+
+  void* Addr() noexcept override { return Ptr.get(); }
+  void const* Addr() const noexcept override { return Ptr.get(); }
+
+  ValueType& get() { return *Ptr; }
+  ValueType const& get() const { return *Ptr; }
+
+private:
+  std::unique_ptr<ValueType> Ptr;
+};
+
+template <>
+struct Storage<std::nullptr_t, StorageKind::Stack> : ObjectInterface
+{
+  explicit Storage(std::nullptr_t) {}
+
+  Storage(Storage&&) noexcept = default;
+  ~Storage() override = default;
+
+  void* Addr() noexcept override { return nullptr; }
+  void const* Addr() const noexcept override { return nullptr; }
+
+  void SerializeImpl(cmSbomSerializer&) const override {}
+
+  std::nullptr_t get() { return nullptr; }
+  std::nullptr_t get() const { return nullptr; }
+};
+
+}
+
+struct ObjectStorage
+{
+  template <typename T>
+  using Stack = impl::Storage<T, impl::StorageKind::Stack>;
+  template <typename T>
+  using Heap = impl::Storage<T, impl::StorageKind::Heap>;
+
+  static constexpr std::size_t BufferSize = 128u;
+
+  static constexpr std::size_t Size = sizeof(Heap<std::nullptr_t>) > BufferSize
+    ? sizeof(Heap<std::nullptr_t>)
+    : BufferSize;
+  static constexpr std::size_t Align = alignof(impl::max_align_t);
+
+  struct Buffer
+  {
+    alignas(Align) unsigned char Data[Size];
+  };
+
+  template <typename Concrete>
+  using Model = cm::conditional_t<sizeof(Stack<Concrete>) <= Size &&
+                                    alignof(Stack<Concrete>) <= Align,
+                                  Stack<Concrete>, Heap<Concrete>>;
+};
+
+class cmSbomObject
+{
+public:
+  template <typename T>
+  struct Instance : ObjectStorage::Model<T>
+  {
+    using Base = ObjectStorage::Model<T>;
+    using Base::Base;
+    Instance(Instance&&) noexcept = default;
+
+    ObjectInterface* Copy(void* storage) const override
+    {
+      return ::new (storage) Instance(this->get());
+    }
+
+    ObjectInterface* Move(void* storage) override
+    {
+      return ::new (storage) Instance(std::move(*this));
+    }
+
+    void SerializeImpl(cmSbomSerializer& os) const override
+    {
+      SerializeDispatch(this->get(), os);
+    }
+  };
+
+  cmSbomObject() { ::new (Storage()) Instance<std::nullptr_t>(nullptr); }
+  cmSbomObject(std::nullptr_t)
+    : cmSbomObject()
+  {
+  }
+
+  template <
+    typename T, typename Decayed = cm::remove_cv_t<cm::remove_reference_t<T>>,
+    typename = cm::enable_if_t<!std::is_same<Decayed, cmSbomObject>::value>>
+  cmSbomObject(T&& x)
+  {
+    ::new (Storage()) Instance<Decayed>(std::forward<T>(x));
+  }
+
+  cmSbomObject(cmSbomObject const& other)
+  {
+    other.Interface().Copy(Storage());
+  }
+  cmSbomObject(cmSbomObject&& other) noexcept
+  {
+    other.Interface().Move(Storage());
+  }
+
+  ~cmSbomObject() noexcept { Interface().~ObjectInterface(); }
+
+  cmSbomObject& operator=(cmSbomObject rhs)
+  {
+    Interface().~ObjectInterface();
+    rhs.Interface().Move(Storage());
+    return *this;
+  }
+
+  bool IsNull() const noexcept { return Interface().Addr() == nullptr; }
+  explicit operator bool() const noexcept { return !IsNull(); }
+
+  void Serialize(cmSbomSerializer& os) const { Interface().SerializeImpl(os); }
+
+  template <typename T>
+  T& CastUnchecked()
+  {
+    return *static_cast<T*>(Interface().Addr());
+  }
+
+  template <typename T>
+  T const& CastUnchecked() const
+  {
+    return *static_cast<T const*>(Interface().Addr());
+  }
+
+  ObjectInterface& Interface()
+  {
+    return *static_cast<ObjectInterface*>(Storage());
+  }
+  ObjectInterface const& Interface() const
+  {
+    return *static_cast<ObjectInterface const*>(Storage());
+  }
+
+  void* Storage() { return &Data.Data; }
+  void const* Storage() const { return &Data.Data; }
+
+  template <typename U>
+  U* ptr() noexcept
+  {
+    return std::addressof(this->template CastUnchecked<U>());
+  }
+
+  template <typename U>
+  U const* ptr() const noexcept
+  {
+    return std::addressof(this->template CastUnchecked<U>());
+  }
+
+private:
+  ObjectStorage::Buffer Data{};
+};
+
+template <typename T, typename U = cm::decay_t<T>>
+U* insert_back(std::vector<cmSbomObject>& vec, T&& obj) noexcept
+{
+  vec.emplace_back(std::forward<U>(obj));
+  return std::addressof(vec.back().CastUnchecked<U>());
+}
diff --git a/Source/cmSbomSerializer.h b/Source/cmSbomSerializer.h
new file mode 100644
index 0000000..019a1c7
--- /dev/null
+++ b/Source/cmSbomSerializer.h
@@ -0,0 +1,38 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file LICENSE.rst or https://cmake.org/licensing for details.  */
+#pragma once
+
+#include <string>
+#include <vector>
+
+#include <cm/optional>
+
+class cmSbomObject;
+class cmSbomSerializer
+{
+public:
+  cmSbomSerializer() = default;
+  cmSbomSerializer(cmSbomSerializer const&) = default;
+  cmSbomSerializer(cmSbomSerializer&&) = default;
+  cmSbomSerializer& operator=(cmSbomSerializer const&) = default;
+  cmSbomSerializer& operator=(cmSbomSerializer&&) = default;
+
+  virtual void BeginObject() {}
+  virtual void EndObject() {}
+  virtual void BeginArray() {}
+  virtual void EndArray() {}
+
+  virtual void AddReference(std::string const& id) = 0;
+
+  virtual void AddString(std::string const& key, std::string const& value) = 0;
+  virtual void AddVisitable(std::string const& key,
+                            cmSbomObject const& visitable) = 0;
+
+  virtual void AddVectorIfPresent(std::string const& key,
+                                  std::vector<cmSbomObject> const& vec) = 0;
+  virtual void AddVectorIfPresent(std::string const& key,
+                                  std::vector<std::string> const& vec) = 0;
+
+  virtual bool WriteSbom(std::ostream& os, cmSbomObject const& document) = 0;
+  virtual ~cmSbomSerializer() = default;
+};
diff --git a/Source/cmSetCommand.cxx b/Source/cmSetCommand.cxx
index 6a346972..88d171b 100644
--- a/Source/cmSetCommand.cxx
+++ b/Source/cmSetCommand.cxx
@@ -81,7 +81,7 @@
 
   // watch for CACHE{} signature
   if (cmHasLiteralPrefix(variable, "CACHE{") && variable.size() > 7 &&
-      cmHasLiteralSuffix(variable, "}")) {
+      cmHasSuffix(variable, '}')) {
     // what is the variable name
     auto const& varName = variable.substr(6, variable.size() - 7);
     // VALUE handling
diff --git a/Source/cmSpdx.cxx b/Source/cmSpdx.cxx
new file mode 100644
index 0000000..6bd37ce
--- /dev/null
+++ b/Source/cmSpdx.cxx
@@ -0,0 +1,520 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file LICENSE.rst or https://cmake.org/licensing for details.  */
+#include "cmSpdx.h"
+
+#include <stdexcept>
+#include <string>
+
+#include "cmSbomSerializer.h"
+
+inline void SerializeIfPresent(cmSbomSerializer& s, std::string const& key,
+                               cm::optional<std::string> const& v)
+{
+  if (v) {
+    s.AddString(key, *v);
+  }
+}
+
+std::string to_string(cmSpdxIntegrityMethod::HashAlgorithmId id)
+{
+  switch (id) {
+    case cmSpdxIntegrityMethod::HashAlgorithmId::ADLER32:
+      return "ADLER32";
+    case cmSpdxIntegrityMethod::HashAlgorithmId::BLAKE2B256:
+      return "BLAKE2B256";
+    case cmSpdxIntegrityMethod::HashAlgorithmId::BLAKE2B384:
+      return "BLAKE2B384";
+    case cmSpdxIntegrityMethod::HashAlgorithmId::BLAKE2B512:
+      return "BLAKE2B512";
+    case cmSpdxIntegrityMethod::HashAlgorithmId::BLAKE3:
+      return "BLAKE3";
+    case cmSpdxIntegrityMethod::HashAlgorithmId::MD2:
+      return "MD2";
+    case cmSpdxIntegrityMethod::HashAlgorithmId::MD4:
+      return "MD4";
+    case cmSpdxIntegrityMethod::HashAlgorithmId::MD5:
+      return "MD5";
+    case cmSpdxIntegrityMethod::HashAlgorithmId::MD6:
+      return "MD6";
+    case cmSpdxIntegrityMethod::HashAlgorithmId::SHA1:
+      return "SHA1";
+    case cmSpdxIntegrityMethod::HashAlgorithmId::SHA224:
+      return "SHA224";
+    case cmSpdxIntegrityMethod::HashAlgorithmId::SHA256:
+      return "SHA256";
+    case cmSpdxIntegrityMethod::HashAlgorithmId::SHA384:
+      return "SHA384";
+    case cmSpdxIntegrityMethod::HashAlgorithmId::SHA512:
+      return "SHA512";
+    case cmSpdxIntegrityMethod::HashAlgorithmId::SHA3_256:
+      return "SHA3_256";
+    case cmSpdxIntegrityMethod::HashAlgorithmId::SHA3_384:
+      return "SHA3_384";
+    case cmSpdxIntegrityMethod::HashAlgorithmId::SHA3_512:
+      return "SHA3_512";
+  }
+  throw std::invalid_argument("Unknown HashAlgorithmId");
+}
+
+std::string to_string(cmSpdxSoftwareArtifact::PurposeId id)
+{
+  switch (id) {
+    case cmSpdxSoftwareArtifact::PurposeId::APPLICATION:
+      return "APPLICATION";
+    case cmSpdxSoftwareArtifact::PurposeId::ARCHIVE:
+      return "ARCHIVE";
+    case cmSpdxSoftwareArtifact::PurposeId::CONTAINER:
+      return "CONTAINER";
+    case cmSpdxSoftwareArtifact::PurposeId::DATA:
+      return "DATA";
+    case cmSpdxSoftwareArtifact::PurposeId::DEVICE:
+      return "DEVICE";
+    case cmSpdxSoftwareArtifact::PurposeId::FIRMWARE:
+      return "FIRMWARE";
+    case cmSpdxSoftwareArtifact::PurposeId::FILE:
+      return "FILE";
+    case cmSpdxSoftwareArtifact::PurposeId::INSTALL:
+      return "INSTALL";
+    case cmSpdxSoftwareArtifact::PurposeId::LIBRARY:
+      return "LIBRARY";
+    case cmSpdxSoftwareArtifact::PurposeId::MODULE:
+      return "MODULE";
+    case cmSpdxSoftwareArtifact::PurposeId::OPERATING_SYSTEM:
+      return "OPERATING_SYSTEM";
+    case cmSpdxSoftwareArtifact::PurposeId::SOURCE:
+      return "SOURCE";
+  }
+  throw std::invalid_argument("Unknown PurposeId");
+}
+
+std::string to_string(cmSpdxSbom::TypeId id)
+{
+  switch (id) {
+    case cmSpdxSbom::TypeId::ANALYZED:
+      return "ANALYZED";
+    case cmSpdxSbom::TypeId::BUILD:
+      return "BUILD";
+    case cmSpdxSbom::TypeId::DEPLOYED:
+      return "DEPLOYED";
+    case cmSpdxSbom::TypeId::DESIGN:
+      return "DESIGN";
+    case cmSpdxSbom::TypeId::RUNTIME:
+      return "RUNTIME";
+    case cmSpdxSbom::TypeId::SOURCE:
+      return "SOURCE";
+    case cmSpdxSbom::TypeId::TEST:
+      return "TEST";
+  }
+  throw std::invalid_argument("Unknown Sbom::TypeId");
+}
+
+std::string to_string(cmSpdxFile::FileKindId id)
+{
+  switch (id) {
+    case cmSpdxFile::FileKindId::DIRECTORY:
+      return "DIRECTORY";
+    case cmSpdxFile::FileKindId::FILE:
+      return "FILE";
+  }
+  throw std::invalid_argument("Unknown File::FileKindId");
+}
+
+std::string to_string(cmSpdxRelationship::RelationshipTypeId id)
+{
+  switch (id) {
+    case cmSpdxRelationship::RelationshipTypeId::DESCRIBES:
+      return "DESCRIBES";
+    case cmSpdxRelationship::RelationshipTypeId::CONTAINS:
+      return "CONTAINS";
+    case cmSpdxRelationship::RelationshipTypeId::DEPENDS_ON:
+      return "DEPENDS_ON";
+    case cmSpdxRelationship::RelationshipTypeId::OTHER:
+      return "OTHER";
+  }
+  throw std::invalid_argument("Unknown RelationshipTypeId");
+}
+
+std::string to_string(cmSpdxLifecycleScopedRelationship::ScopeId id)
+{
+  switch (id) {
+    case cmSpdxLifecycleScopedRelationship::ScopeId::BUILD:
+      return "BUILD";
+    case cmSpdxLifecycleScopedRelationship::ScopeId::DESIGN:
+      return "DESIGN";
+    case cmSpdxLifecycleScopedRelationship::ScopeId::RUNTIME:
+      return "RUNTIME";
+    case cmSpdxLifecycleScopedRelationship::ScopeId::TEST:
+      return "TEST";
+  }
+  throw std::invalid_argument("Unknown Lifecycle ScopeId");
+}
+
+std::string to_string(cmSpdxAnnotation::AnnotationTypeId id)
+{
+  switch (id) {
+    case cmSpdxAnnotation::AnnotationTypeId::REVIEW:
+      return "REVIEW";
+    case cmSpdxAnnotation::AnnotationTypeId::OTHER:
+      return "OTHER";
+  }
+  throw std::invalid_argument("Unknown AnnotationTypeId");
+}
+
+std::string to_string(cmSpdxArtifact::SupportTypeId id)
+{
+  switch (id) {
+    case cmSpdxArtifact::SupportTypeId::COMMUNITY:
+      return "COMMUNITY";
+    case cmSpdxArtifact::SupportTypeId::COMMERCIAL:
+      return "COMMERCIAL";
+    case cmSpdxArtifact::SupportTypeId::NONE:
+      return "NONE";
+  }
+  throw std::invalid_argument("Unknown SupportTypeId");
+}
+
+void cmSpdxExternalIdentifier::Serialize(cmSbomSerializer& serializer) const
+{
+  serializer.AddString("type", "ExternalIdentifier");
+  SerializeIfPresent(serializer, "externalIdentifierType",
+                     ExternalIdentifierType);
+  SerializeIfPresent(serializer, "identifier", Identifier);
+  SerializeIfPresent(serializer, "comment", Comment);
+  SerializeIfPresent(serializer, "identifierLocation", IdentifierLocation);
+  SerializeIfPresent(serializer, "issuingAuthority", IssuingAuthority);
+}
+
+void cmSpdxExternalRef::Serialize(cmSbomSerializer& serializer) const
+{
+  serializer.AddString("type", "ExternalRef");
+  SerializeIfPresent(serializer, "externalRefType", ExternalRefType);
+  SerializeIfPresent(serializer, "locator", Locator);
+  SerializeIfPresent(serializer, "contentType", ContentType);
+  SerializeIfPresent(serializer, "comment", Comment);
+}
+
+void cmSpdxChecksum::Serialize(cmSbomSerializer& serializer) const
+{
+  serializer.AddString("type", "Checksum");
+  serializer.AddString("algorithm", to_string(Algorithm));
+  serializer.AddString("checksumValue", ChecksumValue);
+}
+
+void cmSpdxCreationInfo::Serialize(cmSbomSerializer& serializer) const
+{
+  serializer.AddString("type", "CreationInfo");
+  SerializeIfPresent(serializer, "@id", SpdxId);
+  if (SpecVersion) {
+    serializer.AddString("specVersion", *SpecVersion);
+  }
+  SerializeIfPresent(serializer, "comment", Comment);
+  SerializeIfPresent(serializer, "created", Created);
+  if (!CreatedBy.empty()) {
+    serializer.AddVectorIfPresent("createdBy", CreatedBy);
+  }
+  if (!CreatedUsing.empty()) {
+    serializer.AddVectorIfPresent("createdUsing", CreatedUsing);
+  }
+}
+
+void cmSpdxIntegrityMethod::Serialize(cmSbomSerializer& serializer) const
+{
+  serializer.AddString("type", "IntegrityMethod");
+  SerializeIfPresent(serializer, "comment", Comment);
+}
+
+void cmSpdxElement::Serialize(cmSbomSerializer& serializer) const
+{
+  serializer.AddString("type", "Element");
+  SerializeIfPresent(serializer, "@id", SpdxId);
+  SerializeIfPresent(serializer, "name", Name);
+  SerializeIfPresent(serializer, "summary", Summary);
+  SerializeIfPresent(serializer, "description", Description);
+  SerializeIfPresent(serializer, "comment", Comment);
+  if (CreationInfo) {
+    serializer.AddVisitable("creationInfo", *CreationInfo);
+  }
+  if (VerifiedUsing) {
+    serializer.AddVisitable("verifiedUsing", *VerifiedUsing);
+  }
+  if (!ExternalRef.empty()) {
+    serializer.AddVectorIfPresent("externalRef", ExternalRef);
+  }
+  if (!ExternalIdentifier.empty()) {
+    serializer.AddVectorIfPresent("externalIdentifier", ExternalIdentifier);
+  }
+  if (Extension) {
+    serializer.AddVisitable("extension", *Extension);
+  }
+}
+
+void cmSpdxTool::Serialize(cmSbomSerializer& serializer) const
+{
+  cmSpdxElement::Serialize(serializer);
+  serializer.AddString("type", "Tool");
+}
+
+void cmSpdxAgent::Serialize(cmSbomSerializer& serializer) const
+{
+  cmSpdxElement::Serialize(serializer);
+  serializer.AddString("type", "Agent");
+}
+
+void cmSpdxOrganization::Serialize(cmSbomSerializer& serializer) const
+{
+  cmSpdxAgent::Serialize(serializer);
+  serializer.AddString("type", "Organization");
+}
+
+void cmSpdxPerson::Serialize(cmSbomSerializer& serializer) const
+{
+  cmSpdxAgent::Serialize(serializer);
+  serializer.AddString("type", "Person");
+}
+
+void cmSpdxSoftwareAgent::Serialize(cmSbomSerializer& serializer) const
+{
+  cmSpdxAgent::Serialize(serializer);
+  serializer.AddString("type", "SoftwareAgent");
+}
+
+void cmSpdxPositiveIntegerRange::Serialize(cmSbomSerializer& serializer) const
+{
+  serializer.AddString("type", "PositiveIntegerRange");
+  SerializeIfPresent(serializer, "beginIntegerRange", BeginIntegerRange);
+  SerializeIfPresent(serializer, "endIntegerRange", EndIntegerRange);
+}
+
+void cmSpdxRelationship::Serialize(cmSbomSerializer& serializer) const
+{
+  cmSpdxElement::Serialize(serializer);
+  serializer.AddString("type", "Relationship");
+  if (From) {
+    serializer.AddVisitable("from", *From);
+  }
+  if (!To.empty()) {
+    serializer.AddVectorIfPresent("to", To);
+  }
+  if (RelationshipType) {
+    serializer.AddString("relationshipType", to_string(*RelationshipType));
+  }
+  SerializeIfPresent(serializer, "startTime", StartTime);
+  SerializeIfPresent(serializer, "endTime", EndTime);
+}
+
+void cmSpdxLifecycleScopedRelationship::Serialize(
+  cmSbomSerializer& serializer) const
+{
+  cmSpdxRelationship::Serialize(serializer);
+  serializer.AddString("type", "LifecycleScopedRelationship");
+  if (Scope) {
+    serializer.AddString("scope", to_string(*Scope));
+  }
+}
+
+void cmSpdxArtifact::Serialize(cmSbomSerializer& serializer) const
+{
+  cmSpdxElement::Serialize(serializer);
+  serializer.AddString("type", "Artifact");
+  if (!OriginatedBy.empty()) {
+    serializer.AddVectorIfPresent("originatedBy", OriginatedBy);
+  }
+  if (SuppliedBy) {
+    serializer.AddVisitable("suppliedBy", *SuppliedBy);
+  }
+  SerializeIfPresent(serializer, "builtTime", BuiltTime);
+  SerializeIfPresent(serializer, "releaseTime", ReleaseTime);
+  SerializeIfPresent(serializer, "validUntilTime", ValidUntilTime);
+  SerializeIfPresent(serializer, "standardName", StandardName);
+  if (Support) {
+    serializer.AddString("support", to_string(*Support));
+  }
+}
+
+void cmSpdxIndividualElement::Serialize(cmSbomSerializer& serializer) const
+{
+  cmSpdxElement::Serialize(serializer);
+  serializer.AddString("type", "IndividualElement");
+}
+
+void cmSpdxAnnotation::Serialize(cmSbomSerializer& serializer) const
+{
+  cmSpdxElement::Serialize(serializer);
+  serializer.AddString("type", "Annotation");
+  if (AnnotationType) {
+    serializer.AddString("annotationType", to_string(*AnnotationType));
+  }
+  SerializeIfPresent(serializer, "contentType", ContentType);
+  SerializeIfPresent(serializer, "statement", Statement);
+  if (Element) {
+    serializer.AddVisitable("element", *Element);
+  }
+}
+
+void cmSpdxExternalMap::Serialize(cmSbomSerializer& serializer) const
+{
+  serializer.AddString("type", "ExternalMap");
+  SerializeIfPresent(serializer, "externalSpdxId", ExternalSpdxId);
+  if (VerifiedUsing) {
+    serializer.AddVisitable("verifiedUsing", *VerifiedUsing);
+  }
+  SerializeIfPresent(serializer, "locationHistory", LocationHistory);
+  if (DefiningArtifact) {
+    serializer.AddVisitable("definingArtifact", *DefiningArtifact);
+  }
+}
+
+void cmSpdxNamespaceMap::Serialize(cmSbomSerializer& serializer) const
+{
+  serializer.AddString("type", "NamespaceMap");
+  SerializeIfPresent(serializer, "prefix", Prefix);
+  SerializeIfPresent(serializer, "namespace", Namespace);
+}
+
+void cmSpdxElementCollection::Serialize(cmSbomSerializer& serializer) const
+{
+  cmSpdxElement::Serialize(serializer);
+  serializer.AddString("type", "ElementCollection");
+  if (!Elements.empty()) {
+    serializer.AddVectorIfPresent("element", Elements);
+  }
+  if (!RootElements.empty()) {
+    serializer.AddVectorIfPresent("rootElement", RootElements);
+  }
+  if (!ProfileConformance.empty()) {
+    serializer.AddVectorIfPresent("profileConformance", ProfileConformance);
+  }
+}
+
+void cmSpdxPackageVerificationCode::Serialize(
+  cmSbomSerializer& serializer) const
+{
+  serializer.AddString("type", "PackageVerificationCode");
+  if (Algorithm) {
+    serializer.AddString("algorithm", to_string(*Algorithm));
+  }
+  SerializeIfPresent(serializer, "hashValue", HashValue);
+  SerializeIfPresent(serializer, "packageVerificationCodeExcludedFile",
+                     PackageVerificationCodeExcludedFile);
+}
+
+void cmSpdxHash::Serialize(cmSbomSerializer& serializer) const
+{
+  serializer.AddString("type", "Hash");
+  serializer.AddString("hashAlgorithm", to_string(HashAlgorithm));
+  serializer.AddString("hashValue", HashValue);
+}
+
+void cmSpdxBundle::Serialize(cmSbomSerializer& serializer) const
+{
+  cmSpdxElementCollection::Serialize(serializer);
+  serializer.AddString("type", "Bundle");
+  SerializeIfPresent(serializer, "context", Context);
+}
+
+void cmSpdxBom::Serialize(cmSbomSerializer& serializer) const
+{
+  cmSpdxBundle::Serialize(serializer);
+  serializer.AddString("type", "Bom");
+}
+
+void cmSpdxSbom::Serialize(cmSbomSerializer& serializer) const
+{
+  cmSpdxBom::Serialize(serializer);
+  serializer.AddString("type", "software_Sbom");
+  if (Types) {
+    for (auto const& t : *Types) {
+      serializer.AddString("sbomType", to_string(t));
+    }
+  }
+  if (LifecycleScope) {
+    serializer.AddString("lifecycleScope", to_string(*LifecycleScope));
+  }
+}
+
+void cmSpdxSoftwareArtifact::Serialize(cmSbomSerializer& serializer) const
+{
+  cmSpdxArtifact::Serialize(serializer);
+  serializer.AddString("type", "software_SoftwareArtifact");
+  if (PrimaryPurpose) {
+    serializer.AddString("primaryPurpose", to_string(*PrimaryPurpose));
+  }
+  if (AdditionalPurpose) {
+    for (auto const& p : *AdditionalPurpose) {
+      serializer.AddString("additionalPurpose", to_string(p));
+    }
+  }
+  SerializeIfPresent(serializer, "copyrightText", CopyrightText);
+  SerializeIfPresent(serializer, "attributionText", AttributionText);
+  if (ContentIdentifier) {
+    serializer.AddVisitable("contentIdentifier", *ContentIdentifier);
+  }
+  SerializeIfPresent(serializer, "artifactSize", ArtifactSize);
+}
+
+void cmSpdxPackage::Serialize(cmSbomSerializer& serializer) const
+{
+  cmSpdxSoftwareArtifact::Serialize(serializer);
+  serializer.AddString("type", "software_Package");
+  SerializeIfPresent(serializer, "downloadLocation", DownloadLocation);
+  SerializeIfPresent(serializer, "homePage", Homepage);
+  SerializeIfPresent(serializer, "packageVersion", PackageVersion);
+  SerializeIfPresent(serializer, "packageUrl", PackageUrl);
+  SerializeIfPresent(serializer, "sourceInfo", SourceInfo);
+}
+
+void cmSpdxFile::Serialize(cmSbomSerializer& serializer) const
+{
+  cmSpdxArtifact::Serialize(serializer);
+  serializer.AddString("type", "software_File");
+  if (ContentType) {
+    serializer.AddString("contentType", *ContentType);
+  }
+  if (FileType) {
+    serializer.AddString("fileType", to_string(*FileType));
+  }
+}
+
+void cmSpdxContentIdentifier::Serialize(cmSbomSerializer& serializer) const
+{
+  cmSpdxIntegrityMethod::Serialize(serializer);
+  serializer.AddString("type", "software_ContentIdentifier");
+  SerializeIfPresent(serializer, "contentIdentifierType",
+                     ContentIdentifierType);
+  SerializeIfPresent(serializer, "contentValue", ContentValue);
+}
+
+void cmSpdxSnippet::Serialize(cmSbomSerializer& serializer) const
+{
+  cmSpdxSoftwareArtifact::Serialize(serializer);
+  serializer.AddString("type", "software_Snippet");
+  SerializeIfPresent(serializer, "byteRange", ByteRange);
+  SerializeIfPresent(serializer, "lineRange", LineRange);
+  if (SnippetFromFile) {
+    serializer.AddVisitable("snippetFromFile", *SnippetFromFile);
+  }
+}
+
+void cmSpdxDocument::Serialize(cmSbomSerializer& serializer) const
+{
+  cmSpdxElementCollection::Serialize(serializer);
+
+  serializer.AddString("type", "SpdxDocument");
+  if (ExternalMap) {
+    serializer.AddVisitable("externalMap", *ExternalMap);
+  }
+  if (NamespaceMap) {
+    serializer.AddVisitable("namespaceMap", *NamespaceMap);
+  }
+  SerializeIfPresent(serializer, "dataLicense", DataLicense);
+}
+
+void cmSbomDocument::Serialize(cmSbomSerializer& serializer) const
+{
+  serializer.AddString(
+    "@context",
+    Context.value_or("https://spdx.org/rdf/3.0.1/spdx-context.jsonld"));
+  if (!Graph.empty()) {
+    serializer.AddVectorIfPresent("@graph", Graph);
+  }
+}
diff --git a/Source/cmSpdx.h b/Source/cmSpdx.h
new file mode 100644
index 0000000..9b37828
--- /dev/null
+++ b/Source/cmSpdx.h
@@ -0,0 +1,390 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file LICENSE.rst or https://cmake.org/licensing for details.  */
+#pragma once
+#include <string>
+#include <vector>
+
+#include <cm/optional>
+
+#include "cmSbomObject.h"
+
+class cmSbomSerializer;
+
+using Datetime = std::string;
+using MediaType = std::string;
+using SemVer = std::string;
+
+struct cmSpdxExternalIdentifier
+{
+  cm::optional<std::string> SpdxId;
+  cm::optional<std::string> ExternalIdentifierType;
+  cm::optional<std::string> Identifier;
+  cm::optional<std::string> Comment;
+  cm::optional<std::string> IdentifierLocation;
+  cm::optional<std::string> IssuingAuthority;
+
+  void Serialize(cmSbomSerializer&) const;
+};
+
+struct cmSpdxExternalRef
+{
+  cm::optional<std::string> SpdxId;
+  cm::optional<std::string> ExternalRefType;
+  cm::optional<std::string> Locator;
+  cm::optional<std::string> ContentType;
+  cm::optional<std::string> Comment;
+
+  void Serialize(cmSbomSerializer&) const;
+};
+
+struct cmSpdxCreationInfo
+{
+  cm::optional<std::string> SpdxId;
+  cm::optional<SemVer> SpecVersion;
+  cm::optional<std::string> Comment;
+  cm::optional<Datetime> Created;
+  std::vector<cmSbomObject> CreatedBy;
+  std::vector<cmSbomObject> CreatedUsing;
+
+  void Serialize(cmSbomSerializer&) const;
+};
+
+struct cmSpdxIntegrityMethod
+{
+  cm::optional<std::string> SpdxId;
+  cm::optional<std::string> Comment;
+
+  enum HashAlgorithmId
+  {
+    ADLER32,
+    BLAKE2B256,
+    BLAKE2B384,
+    BLAKE2B512,
+    BLAKE3,
+    MD2,
+    MD4,
+    MD5,
+    MD6,
+    SHA1,
+    SHA224,
+    SHA256,
+    SHA384,
+    SHA512,
+    SHA3_256,
+    SHA3_384,
+    SHA3_512,
+  };
+
+  cmSpdxIntegrityMethod() = default;
+  cmSpdxIntegrityMethod(cmSpdxIntegrityMethod const&) = default;
+  cmSpdxIntegrityMethod(cmSpdxIntegrityMethod&&) = default;
+  cmSpdxIntegrityMethod& operator=(cmSpdxIntegrityMethod const&) = default;
+  cmSpdxIntegrityMethod& operator=(cmSpdxIntegrityMethod&&) = default;
+
+  virtual void Serialize(cmSbomSerializer&) const;
+  virtual ~cmSpdxIntegrityMethod() = default;
+};
+
+struct cmSpdxChecksum
+{
+  cm::optional<std::string> SpdxId;
+  cmSpdxIntegrityMethod::HashAlgorithmId Algorithm;
+  std::string ChecksumValue;
+
+  void Serialize(cmSbomSerializer&) const;
+};
+
+struct cmSpdxElement
+{
+  cm::optional<std::string> SpdxId;
+  cm::optional<std::string> Name;
+  cm::optional<std::string> Summary;
+  cm::optional<std::string> Description;
+  cm::optional<std::string> Comment;
+  cm::optional<cmSbomObject> CreationInfo;
+  cm::optional<cmSbomObject> VerifiedUsing;
+  std::vector<cmSbomObject> ExternalRef;
+  std::vector<cmSbomObject> ExternalIdentifier;
+  cm::optional<cmSbomObject> Extension;
+
+  cmSpdxElement() = default;
+  cmSpdxElement(cmSpdxElement const&) = default;
+  cmSpdxElement(cmSpdxElement&&) = default;
+  cmSpdxElement& operator=(cmSpdxElement const&) = default;
+  cmSpdxElement& operator=(cmSpdxElement&&) = default;
+
+  virtual ~cmSpdxElement() = default;
+  virtual void Serialize(cmSbomSerializer&) const;
+};
+
+struct cmSpdxTool final : cmSpdxElement
+{
+  void Serialize(cmSbomSerializer&) const override;
+};
+
+struct cmSpdxAgent : cmSpdxElement
+{
+  void Serialize(cmSbomSerializer&) const override;
+};
+
+struct cmSpdxOrganization final : cmSpdxAgent
+{
+  void Serialize(cmSbomSerializer&) const override;
+};
+
+struct cmSpdxPerson final : cmSpdxAgent
+{
+  void Serialize(cmSbomSerializer&) const override;
+};
+
+struct cmSpdxSoftwareAgent final : cmSpdxAgent
+{
+  void Serialize(cmSbomSerializer&) const override;
+};
+
+struct cmSpdxPositiveIntegerRange
+{
+  cm::optional<std::string> SpdxId;
+  cm::optional<std::string> BeginIntegerRange;
+  cm::optional<std::string> EndIntegerRange;
+
+  void Serialize(cmSbomSerializer&) const;
+};
+
+struct cmSpdxRelationship : cmSpdxElement
+{
+  enum RelationshipTypeId
+  {
+    DESCRIBES,
+    CONTAINS,
+    DEPENDS_ON,
+    OTHER
+  };
+
+  cm::optional<cmSbomObject> From;
+  std::vector<cmSbomObject> To;
+  cm::optional<RelationshipTypeId> RelationshipType;
+  cm::optional<Datetime> StartTime;
+  cm::optional<Datetime> EndTime;
+
+  void Serialize(cmSbomSerializer&) const override;
+};
+
+struct cmSpdxLifecycleScopedRelationship final : cmSpdxRelationship
+{
+  enum ScopeId
+  {
+    BUILD,
+    DESIGN,
+    RUNTIME,
+    TEST
+  };
+
+  cm::optional<ScopeId> Scope;
+
+  void Serialize(cmSbomSerializer&) const override;
+};
+
+struct cmSpdxArtifact : cmSpdxElement
+{
+  enum SupportTypeId
+  {
+    COMMUNITY,
+    COMMERCIAL,
+    NONE
+  };
+
+  std::vector<cmSbomObject> OriginatedBy;
+  cm::optional<cmSbomObject> SuppliedBy;
+  cm::optional<Datetime> BuiltTime;
+  cm::optional<Datetime> ReleaseTime;
+  cm::optional<Datetime> ValidUntilTime;
+  cm::optional<std::string> StandardName;
+  cm::optional<SupportTypeId> Support;
+
+  void Serialize(cmSbomSerializer&) const override;
+};
+
+struct cmSpdxIndividualElement final : cmSpdxElement
+{
+  void Serialize(cmSbomSerializer&) const override;
+};
+
+struct cmSpdxAnnotation final : cmSpdxElement
+{
+  enum AnnotationTypeId
+  {
+    REVIEW,
+    OTHER
+  };
+
+  cm::optional<AnnotationTypeId> AnnotationType;
+  cm::optional<MediaType> ContentType;
+  cm::optional<std::string> Statement;
+  cm::optional<cmSbomObject> Element;
+
+  void Serialize(cmSbomSerializer&) const override;
+};
+
+struct cmSpdxExternalMap
+{
+  cm::optional<std::string> SpdxId;
+  cm::optional<std::string> ExternalSpdxId;
+  cm::optional<cmSbomObject> VerifiedUsing;
+  cm::optional<std::string> LocationHistory;
+  cm::optional<cmSbomObject> DefiningArtifact;
+
+  void Serialize(cmSbomSerializer&) const;
+};
+
+struct cmSpdxNamespaceMap
+{
+  cm::optional<std::string> SpdxId;
+  cm::optional<std::string> Prefix;
+  cm::optional<std::string> Namespace;
+
+  void Serialize(cmSbomSerializer&) const;
+};
+
+struct cmSpdxElementCollection : cmSpdxElement
+{
+  std::vector<cmSbomObject> Elements;
+  std::vector<cmSbomObject> RootElements;
+  std::vector<std::string> ProfileConformance;
+
+  void Serialize(cmSbomSerializer&) const override;
+};
+
+struct cmSpdxPackageVerificationCode final : cmSpdxIntegrityMethod
+{
+  cm::optional<HashAlgorithmId> Algorithm;
+  cm::optional<std::string> HashValue;
+  cm::optional<std::string> PackageVerificationCodeExcludedFile;
+
+  void Serialize(cmSbomSerializer&) const override;
+};
+
+struct cmSpdxHash final : cmSpdxIntegrityMethod
+{
+  HashAlgorithmId HashAlgorithm;
+  std::string HashValue;
+
+  void Serialize(cmSbomSerializer&) const override;
+};
+
+struct cmSpdxBundle : cmSpdxElementCollection
+{
+  cm::optional<std::string> Context;
+
+  void Serialize(cmSbomSerializer&) const override;
+};
+
+struct cmSpdxBom : cmSpdxBundle
+{
+  void Serialize(cmSbomSerializer&) const override;
+};
+
+struct cmSpdxSbom final : cmSpdxBom
+{
+  enum TypeId
+  {
+    ANALYZED,
+    BUILD,
+    DEPLOYED,
+    DESIGN,
+    RUNTIME,
+    SOURCE,
+    TEST
+  };
+
+  cm::optional<std::vector<TypeId>> Types;
+  cm::optional<TypeId> LifecycleScope;
+
+  void Serialize(cmSbomSerializer&) const override;
+};
+
+struct cmSpdxSoftwareArtifact : cmSpdxArtifact
+{
+  enum PurposeId
+  {
+    APPLICATION,
+    ARCHIVE,
+    CONTAINER,
+    DATA,
+    DEVICE,
+    FIRMWARE,
+    FILE,
+    INSTALL,
+    LIBRARY,
+    MODULE,
+    OPERATING_SYSTEM,
+    SOURCE
+  };
+
+  cm::optional<PurposeId> PrimaryPurpose;
+  cm::optional<std::vector<PurposeId>> AdditionalPurpose;
+  cm::optional<std::string> CopyrightText;
+  cm::optional<std::string> AttributionText;
+  cm::optional<cmSbomObject> ContentIdentifier;
+  cm::optional<std::string> ArtifactSize;
+
+  void Serialize(cmSbomSerializer&) const override;
+};
+
+struct cmSpdxPackage final : cmSpdxSoftwareArtifact
+{
+  cm::optional<std::string> DownloadLocation;
+  cm::optional<std::string> Homepage;
+  cm::optional<std::string> PackageVersion;
+  cm::optional<std::string> PackageUrl;
+  cm::optional<std::string> SourceInfo;
+
+  void Serialize(cmSbomSerializer&) const override;
+};
+
+struct cmSpdxDocument final : cmSpdxElementCollection
+{
+  cm::optional<cmSbomObject> ExternalMap;
+  cm::optional<cmSbomObject> NamespaceMap;
+  std::string DataLicense;
+
+  void Serialize(cmSbomSerializer& serializer) const override;
+};
+
+struct cmSpdxContentIdentifier final : cmSpdxIntegrityMethod
+{
+  cm::optional<std::string> ContentIdentifierType;
+  cm::optional<std::string> ContentValue;
+
+  void Serialize(cmSbomSerializer&) const override;
+};
+
+struct cmSpdxFile final : cmSpdxArtifact
+{
+  enum FileKindId
+  {
+    DIRECTORY,
+    FILE
+  };
+  cm::optional<MediaType> ContentType;
+  cm::optional<FileKindId> FileType;
+
+  void Serialize(cmSbomSerializer&) const override;
+};
+
+struct cmSpdxSnippet final : cmSpdxSoftwareArtifact
+{
+  cm::optional<std::string> ByteRange;
+  cm::optional<std::string> LineRange;
+  cm::optional<cmSbomObject> SnippetFromFile;
+
+  void Serialize(cmSbomSerializer&) const override;
+};
+
+struct cmSbomDocument
+{
+  cm::optional<std::string> Context;
+  std::vector<cmSbomObject> Graph;
+
+  void Serialize(cmSbomSerializer&) const;
+};
diff --git a/Source/cmSpdxSerializer.cxx b/Source/cmSpdxSerializer.cxx
new file mode 100644
index 0000000..9ba1d15
--- /dev/null
+++ b/Source/cmSpdxSerializer.cxx
@@ -0,0 +1,120 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file LICENSE.rst or https://cmake.org/licensing for details.  */
+#include "cmSpdxSerializer.h"
+
+#include <utility>
+#include <vector>
+
+#include <cm3p/json/writer.h>
+
+#include "cmSbomObject.h"
+
+cmSpdxSerializer::cmSpdxSerializer()
+{
+  Json::StreamWriterBuilder builder = Json::StreamWriterBuilder();
+  builder["indentation"] = "  ";
+  Writer.reset(builder.newStreamWriter());
+}
+
+void cmSpdxSerializer::BeginObject()
+{
+  CurrentValue = Json::objectValue;
+}
+
+void cmSpdxSerializer::BeginArray()
+{
+  CurrentValue = Json::arrayValue;
+}
+
+void cmSpdxSerializer::EndObject()
+{
+}
+
+void cmSpdxSerializer::EndArray()
+{
+}
+
+void cmSpdxSerializer::AddReference(std::string const& id)
+{
+  CurrentValue = id;
+}
+
+void cmSpdxSerializer::AddString(std::string const& key,
+                                 std::string const& value)
+{
+  if (!value.empty()) {
+    CurrentValue[key] = value;
+  }
+}
+
+void cmSpdxSerializer::AddVisitable(std::string const& key,
+                                    cmSbomObject const& visitable)
+{
+  if (visitable.IsNull()) {
+    return;
+  }
+
+  Json::Value parentValue = std::move(CurrentValue);
+  visitable.Serialize(*this);
+  Json::Value childValue = std::move(CurrentValue);
+
+  CurrentValue = std::move(parentValue);
+  CurrentValue[key] = std::move(childValue);
+}
+
+void cmSpdxSerializer::AddVectorIfPresent(std::string const& key,
+                                          std::vector<cmSbomObject> const& vec)
+{
+  if (vec.empty()) {
+    return;
+  }
+  Json::Value parentValue = std::move(CurrentValue);
+  Json::Value childValue(Json::arrayValue);
+
+  for (auto const& item : vec) {
+    if (item.IsNull()) {
+      continue;
+    }
+
+    item.Serialize(*this);
+
+    if (!CurrentValue.isNull()) {
+      childValue.append(std::move(CurrentValue));
+    }
+  }
+
+  CurrentValue = std::move(parentValue);
+  CurrentValue[key] = std::move(childValue);
+}
+
+void cmSpdxSerializer::AddVectorIfPresent(std::string const& key,
+                                          std::vector<std::string> const& vec)
+{
+  if (vec.empty()) {
+    return;
+  }
+  Json::Value parentValue = std::move(CurrentValue);
+  Json::Value childValue(Json::arrayValue);
+
+  for (auto const& item : vec) {
+    if (item.empty()) {
+      continue;
+    }
+    childValue.append(item);
+  }
+
+  CurrentValue = std::move(parentValue);
+  CurrentValue[key] = std::move(childValue);
+}
+
+bool cmSpdxSerializer::WriteSbom(std::ostream& os,
+                                 cmSbomObject const& document)
+{
+  if (document.IsNull()) {
+    return false;
+  }
+
+  document.Serialize(*this);
+  Writer->write(CurrentValue, &os);
+  return os.good();
+}
diff --git a/Source/cmSpdxSerializer.h b/Source/cmSpdxSerializer.h
new file mode 100644
index 0000000..5bcbce1
--- /dev/null
+++ b/Source/cmSpdxSerializer.h
@@ -0,0 +1,49 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file LICENSE.rst or https://cmake.org/licensing for details.  */
+#pragma once
+
+#include <memory>
+#include <ostream>
+#include <string>
+
+#include <cm3p/json/value.h>
+#include <cm3p/json/writer.h>
+
+#include "cmSbomSerializer.h"
+
+struct cmSpdxSerializer final : cmSbomSerializer
+{
+  cmSpdxSerializer();
+
+  ~cmSpdxSerializer() override = default;
+
+  void BeginObject() override;
+
+  void BeginArray() override;
+
+  void EndObject() override;
+
+  void EndArray() override;
+
+  void AddReference(std::string const& id) override;
+
+  void AddString(std::string const& key, std::string const& value) override;
+
+  void AddVisitable(std::string const& key,
+                    cmSbomObject const& visitable) override;
+
+  void AddVectorIfPresent(std::string const& key,
+                          std::vector<cmSbomObject> const& vec) override;
+
+  void AddVectorIfPresent(std::string const& key,
+                          std::vector<std::string> const& vec) override;
+
+  bool WriteSbom(std::ostream& os, cmSbomObject const& document) override;
+
+  Json::Value GetJson() { return CurrentValue; }
+
+private:
+  Json::Value CurrentValue;
+  std::string CurrentKey;
+  std::unique_ptr<Json::StreamWriter> Writer;
+};
diff --git a/Source/cmState.cxx b/Source/cmState.cxx
index e694a28..3255650 100644
--- a/Source/cmState.cxx
+++ b/Source/cmState.cxx
@@ -31,9 +31,9 @@
 std::string const PropertySentinel = std::string{};
 } // namespace cmStateDetail
 
-cmState::cmState(Mode mode, ProjectKind projectKind)
-  : StateMode(mode)
-  , StateProjectKind(projectKind)
+cmState::cmState(Role role, TryCompile isTryCompile)
+  : StateRole(role)
+  , IsTryCompile(isTryCompile)
 {
   this->CacheManager = cm::make_unique<cmCacheManager>();
   this->GlobVerificationManager = cm::make_unique<cmGlobVerificationManager>();
@@ -603,9 +603,8 @@
     std::vector<std::string> commands = this->GetCommandNames();
     this->SetGlobalProperty("COMMANDS", cmList::to_string(commands));
   } else if (prop == "IN_TRY_COMPILE") {
-    this->SetGlobalProperty(
-      "IN_TRY_COMPILE",
-      this->StateProjectKind == ProjectKind::TryCompile ? "1" : "0");
+    this->SetGlobalProperty("IN_TRY_COMPILE",
+                            this->IsTryCompile == TryCompile::Yes ? "1" : "0");
   } else if (prop == "GENERATOR_IS_MULTI_CONFIG") {
     this->SetGlobalProperty("GENERATOR_IS_MULTI_CONFIG",
                             this->IsGeneratorMultiConfig ? "1" : "0");
@@ -613,8 +612,7 @@
     auto langs = cmList::to_string(this->EnabledLanguages);
     this->SetGlobalProperty("ENABLED_LANGUAGES", langs);
   } else if (prop == "CMAKE_ROLE") {
-    std::string mode = this->GetModeString();
-    this->SetGlobalProperty("CMAKE_ROLE", mode);
+    this->SetGlobalProperty("CMAKE_ROLE", this->GetRoleString());
   }
 #define STRING_LIST_ELEMENT(F) ";" #F
   if (prop == "CMAKE_C_KNOWN_FEATURES") {
@@ -814,40 +812,50 @@
   return this->CacheManager->GetCacheMinorVersion();
 }
 
-cmState::Mode cmState::GetMode() const
+void cmState::SetRoleToProjectForCMakeBuildVsReconfigure()
 {
-  return this->StateMode;
+  this->StateRole = Role::Project;
 }
 
-std::string cmState::GetModeString() const
+void cmState::SetRoleToHelpForListPresets()
 {
-  return ModeToString(this->StateMode);
+  this->StateRole = Role::Help;
 }
 
-std::string cmState::ModeToString(cmState::Mode mode)
+cmState::Role cmState::GetRole() const
+{
+  return this->StateRole;
+}
+
+std::string cmState::GetRoleString() const
+{
+  return RoleToString(this->StateRole);
+}
+
+std::string cmState::RoleToString(cmState::Role mode)
 {
   switch (mode) {
-    case Project:
+    case Role::Project:
       return "PROJECT";
-    case Script:
+    case Role::Script:
       return "SCRIPT";
-    case FindPackage:
+    case Role::FindPackage:
       return "FIND_PACKAGE";
-    case CTest:
+    case Role::CTest:
       return "CTEST";
-    case CPack:
+    case Role::CPack:
       return "CPACK";
-    case Help:
+    case Role::Help:
       return "HELP";
-    case Unknown:
-      return "UNKNOWN";
+    case Role::Internal:
+      return "INTERNAL";
   }
   return "UNKNOWN";
 }
 
-cmState::ProjectKind cmState::GetProjectKind() const
+cmState::TryCompile cmState::GetIsTryCompile() const
 {
-  return this->StateProjectKind;
+  return this->IsTryCompile;
 }
 
 std::string const& cmState::GetBinaryDirectory() const
diff --git a/Source/cmState.h b/Source/cmState.h
index 4775b74..885ade5 100644
--- a/Source/cmState.h
+++ b/Source/cmState.h
@@ -44,24 +44,24 @@
   friend class cmStateSnapshot;
 
 public:
-  enum Mode
+  enum class Role
   {
-    Unknown,
+    Internal,
     Project,
     Script,
     FindPackage,
     CTest,
     CPack,
-    Help
+    Help,
   };
 
-  enum class ProjectKind
+  enum class TryCompile
   {
-    Normal,
-    TryCompile,
+    No,
+    Yes,
   };
 
-  cmState(Mode mode, ProjectKind projectKind = ProjectKind::Normal);
+  cmState(Role role, TryCompile isTryCompile = TryCompile::No);
   ~cmState();
 
   cmState(cmState const&) = delete;
@@ -231,12 +231,14 @@
   unsigned int GetCacheMajorVersion() const;
   unsigned int GetCacheMinorVersion() const;
 
-  Mode GetMode() const;
-  std::string GetModeString() const;
+  void SetRoleToProjectForCMakeBuildVsReconfigure();
+  void SetRoleToHelpForListPresets();
+  Role GetRole() const;
+  std::string GetRoleString() const;
 
-  static std::string ModeToString(Mode mode);
+  static std::string RoleToString(Role role);
 
-  ProjectKind GetProjectKind() const;
+  TryCompile GetIsTryCompile() const;
 
   void ClearDependencyProvider() { this->DependencyProvider.reset(); }
   void SetDependencyProvider(cmDependencyProvider provider)
@@ -304,8 +306,8 @@
   bool Ninja = false;
   bool NinjaMulti = false;
   bool FastbuildMake = false;
-  Mode StateMode = Unknown;
-  ProjectKind StateProjectKind = ProjectKind::Normal;
+  Role StateRole = Role::Internal;
+  TryCompile IsTryCompile = TryCompile::No;
   cm::optional<cmDependencyProvider> DependencyProvider;
   bool ProcessingTopLevelIncludes = false;
 };
diff --git a/Source/cmString.hxx b/Source/cmString.hxx
index c346230..f7dcb2b 100644
--- a/Source/cmString.hxx
+++ b/Source/cmString.hxx
@@ -425,6 +425,16 @@
     r.append(v.data(), v.size());
     return *this = std::move(r);
   }
+  template <typename T>
+  typename std::enable_if<AsStringView<T>::value, String&>::type append(T&& s)
+  {
+    string_view v = AsStringView<T>::view(std::forward<T>(s));
+    std::string r;
+    r.reserve(this->size() + v.size());
+    r.assign(this->data(), this->size());
+    r.append(v.data(), v.size());
+    return *this = std::move(r);
+  }
 
   /** Assign to an empty string.  */
   void clear() { *this = ""_s; }
@@ -432,6 +442,20 @@
   /** Insert 'count' copies of 'ch' at position 'index'.  */
   String& insert(size_type index, size_type count, char ch);
 
+  /** Insert into the string using any type that implements the
+      AsStringView trait.  */
+  template <typename T>
+  typename std::enable_if<AsStringView<T>::value, String&>::type insert(
+    size_type index, T&& s)
+  {
+    string_view v = AsStringView<T>::view(std::forward<T>(s));
+    std::string r;
+    r.reserve(this->size() + v.size());
+    r.assign(this->data(), this->size());
+    r.insert(index, v.data(), v.size());
+    return *this = std::move(r);
+  }
+
   /** Erase 'count' characters starting at position 'index'.  */
   String& erase(size_type index = 0, size_type count = npos);
 
diff --git a/Source/cmStringCommand.cxx b/Source/cmStringCommand.cxx
index 0503033..1631b02 100644
--- a/Source/cmStringCommand.cxx
+++ b/Source/cmStringCommand.cxx
@@ -5,9 +5,9 @@
 
 #include "cmStringCommand.h"
 
-#include <algorithm>
 #include <cstdio>
 #include <cstdlib>
+#include <exception>
 #include <limits>
 #include <memory>
 #include <stdexcept>
@@ -22,22 +22,14 @@
 #include <cm3p/json/value.h>
 #include <cm3p/json/writer.h>
 
-#include "cmsys/RegularExpression.hxx"
-
-#include "cmCryptoHash.h"
+#include "cmCMakeString.hxx"
 #include "cmExecutionStatus.h"
-#include "cmGeneratorExpression.h"
+#include "cmList.h"
 #include "cmMakefile.h"
 #include "cmMessageType.h"
-#include "cmPolicies.h"
 #include "cmRange.h"
 #include "cmStringAlgorithms.h"
-#include "cmStringReplaceHelper.h"
 #include "cmSubcommandTable.h"
-#include "cmSystemTools.h"
-#include "cmTimestamp.h"
-#include "cmUuid.h"
-#include "cmValue.h"
 
 namespace {
 
@@ -62,13 +54,16 @@
     return false;
   }
 
-  std::unique_ptr<cmCryptoHash> hash(cmCryptoHash::New(args[0]));
-  if (hash) {
-    std::string out = hash->HashString(args[2]);
-    status.GetMakefile().AddDefinition(args[1], out);
+  cm::CMakeString data{ args[2] };
+
+  try {
+    data.Hash(args[0]);
+    status.GetMakefile().AddDefinition(args[1], data);
     return true;
+  } catch (std::exception const& e) {
+    status.SetError(e.what());
+    return false;
   }
-  return false;
 }
 
 bool HandleToUpperLowerCommand(std::vector<std::string> const& args,
@@ -80,16 +75,16 @@
   }
 
   std::string const& outvar = args[2];
-  std::string output;
+  cm::CMakeString data{ args[1] };
 
   if (toUpper) {
-    output = cmSystemTools::UpperCase(args[1]);
+    data.ToUpper();
   } else {
-    output = cmSystemTools::LowerCase(args[1]);
+    data.ToLower();
   }
 
   // Store the output in the provided variable.
-  status.GetMakefile().AddDefinition(outvar, output);
+  status.GetMakefile().AddDefinition(outvar, data);
   return true;
 }
 
@@ -112,23 +107,17 @@
     status.SetError("No output variable specified");
     return false;
   }
-  std::string::size_type cc;
-  std::string const& outvar = args.back();
-  std::string output;
-  for (cc = 1; cc < args.size() - 1; cc++) {
-    int ch = atoi(args[cc].c_str());
-    if (ch > 0 && ch < 256) {
-      output += static_cast<char>(ch);
-    } else {
-      std::string error =
-        cmStrCat("Character with code ", args[cc], " does not exist.");
-      status.SetError(error);
-      return false;
-    }
+
+  try {
+    std::string const& outvar = args.back();
+    cm::CMakeString data;
+    data.FromASCII(cmMakeRange(args).advance(1).retreat(1));
+    status.GetMakefile().AddDefinition(outvar, data);
+    return true;
+  } catch (std::exception const& e) {
+    status.SetError(e.what());
+    return false;
   }
-  // Store the output in the provided variable.
-  status.GetMakefile().AddDefinition(outvar, output);
-  return true;
 }
 
 bool HandleHexCommand(std::vector<std::string> const& args,
@@ -138,17 +127,13 @@
     status.SetError("Incorrect number of arguments");
     return false;
   }
-  auto const& instr = args[1];
+
   auto const& outvar = args[2];
-  std::string output(instr.size() * 2, ' ');
+  cm::CMakeString data{ args[1] };
 
-  std::string::size_type hexIndex = 0;
-  for (auto const& c : instr) {
-    snprintf(&output[hexIndex], 3, "%.2x", c & 0xFFu);
-    hexIndex += 2;
-  }
+  data.ToHexadecimal();
 
-  status.GetMakefile().AddDefinition(outvar, output);
+  status.GetMakefile().AddDefinition(outvar, data);
   return true;
 }
 
@@ -239,33 +224,21 @@
 {
   //"STRING(REGEX MATCH <regular_expression> <output variable>
   // <input> [<input>...])\n";
-  std::string const& regex = args[2];
-  std::string const& outvar = args[3];
+  try {
+    std::string const& regex = args[2];
+    std::string const& outvar = args[3];
+    cm::CMakeString data{ cmMakeRange(args).advance(4) };
 
-  status.GetMakefile().ClearMatches();
-  // Compile the regular expression.
-  cmsys::RegularExpression re;
-  if (!re.compile(regex)) {
-    std::string e =
-      "sub-command REGEX, mode MATCH failed to compile regex \"" + regex +
-      "\".";
-    status.SetError(e);
+    auto result = data.Match(regex, cm::CMakeString::MatchItems::Once,
+                             &status.GetMakefile());
+    // Store the result in the provided variable.
+    status.GetMakefile().AddDefinition(outvar, result.to_string());
+    return true;
+  } catch (std::exception const& e) {
+    status.SetError(
+      cmStrCat("sub-command REGEX, mode MATCH: ", e.what(), '.'));
     return false;
   }
-
-  // Concatenate all the last arguments together.
-  std::string input = cmJoin(cmMakeRange(args).advance(4), std::string());
-
-  // Scan through the input for all matches.
-  std::string output;
-  if (re.find(input)) {
-    status.GetMakefile().StoreMatches(re);
-    output = re.match();
-  }
-
-  // Store the output in the provided variable.
-  status.GetMakefile().AddDefinition(outvar, output);
-  return true;
 }
 
 bool RegexMatchAll(std::vector<std::string> const& args,
@@ -273,55 +246,21 @@
 {
   //"STRING(REGEX MATCHALL <regular_expression> <output variable> <input>
   // [<input>...])\n";
-  std::string const& regex = args[2];
-  std::string const& outvar = args[3];
+  try {
+    std::string const& regex = args[2];
+    std::string const& outvar = args[3];
+    cm::CMakeString data{ cmMakeRange(args).advance(4) };
 
-  status.GetMakefile().ClearMatches();
-  // Compile the regular expression.
-  cmsys::RegularExpression re;
-  if (!re.compile(regex)) {
-    std::string e =
-      "sub-command REGEX, mode MATCHALL failed to compile regex \"" + regex +
-      "\".";
-    status.SetError(e);
+    auto result = data.Match(regex, cm::CMakeString::MatchItems::All,
+                             &status.GetMakefile());
+    // Store the result in the provided variable.
+    status.GetMakefile().AddDefinition(outvar, result.to_string());
+    return true;
+  } catch (std::exception const& e) {
+    status.SetError(
+      cmStrCat("sub-command REGEX, mode MATCHALL: ", e.what(), '.'));
     return false;
   }
-
-  // Concatenate all the last arguments together.
-  std::string input = cmJoin(cmMakeRange(args).advance(4), std::string());
-
-  unsigned optAnchor = 0;
-  if (status.GetMakefile().GetPolicyStatus(cmPolicies::CMP0186) !=
-      cmPolicies::NEW) {
-    optAnchor = cmsys::RegularExpression::BOL_AT_OFFSET;
-  }
-
-  // Scan through the input for all matches.
-  std::string output;
-  std::string::size_type base = 0;
-  unsigned optNonEmpty = 0;
-  while (re.find(input, base, optAnchor | optNonEmpty)) {
-    status.GetMakefile().ClearMatches();
-    status.GetMakefile().StoreMatches(re);
-    if (!output.empty() || optNonEmpty) {
-      output += ";";
-    }
-    output += re.match();
-    base = re.end();
-
-    if (re.start() == input.length()) {
-      break;
-    }
-    if (re.start() == re.end()) {
-      optNonEmpty = cmsys::RegularExpression::NONEMPTY_AT_OFFSET;
-    } else {
-      optNonEmpty = 0;
-    }
-  }
-
-  // Store the output in the provided variable.
-  status.GetMakefile().AddDefinition(outvar, output);
-  return true;
 }
 
 bool RegexReplace(std::vector<std::string> const& args,
@@ -332,38 +271,20 @@
   std::string const& regex = args[2];
   std::string const& replace = args[3];
   std::string const& outvar = args[4];
-  cmStringReplaceHelper replaceHelper(regex, replace, &status.GetMakefile());
 
-  if (!replaceHelper.IsReplaceExpressionValid()) {
+  try {
+    cm::CMakeString data{ cmMakeRange(args).advance(5) };
+
+    data.Replace(regex, replace, cm::CMakeString::Regex::Yes,
+                 &status.GetMakefile());
+    // Store the result in the provided variable.
+    status.GetMakefile().AddDefinition(outvar, data);
+    return true;
+  } catch (std::exception const& e) {
     status.SetError(
-      "sub-command REGEX, mode REPLACE: " + replaceHelper.GetError() + ".");
+      cmStrCat("sub-command REGEX, mode REPLACE: ", e.what(), '.'));
     return false;
   }
-
-  status.GetMakefile().ClearMatches();
-
-  if (!replaceHelper.IsRegularExpressionValid()) {
-    std::string e =
-      "sub-command REGEX, mode REPLACE failed to compile regex \"" + regex +
-      "\".";
-    status.SetError(e);
-    return false;
-  }
-
-  // Concatenate all the last arguments together.
-  std::string const input =
-    cmJoin(cmMakeRange(args).advance(5), std::string());
-  std::string output;
-
-  if (!replaceHelper.Replace(input, output)) {
-    status.SetError(
-      "sub-command REGEX, mode REPLACE: " + replaceHelper.GetError() + ".");
-    return false;
-  }
-
-  // Store the output in the provided variable.
-  status.GetMakefile().AddDefinition(outvar, output);
-  return true;
 }
 
 bool RegexQuote(std::vector<std::string> const& args,
@@ -371,21 +292,19 @@
 {
   //"STRING(REGEX QUOTE <output variable> <input> [<input>...]\n"
   std::string const& outvar = args[2];
-  std::string const input =
-    cmJoin(cmMakeRange(args).advance(3), std::string());
-  std::string output;
+  cm::CMakeString data{ cmMakeRange(args).advance(3) };
 
-  // Escape all regex special characters
-  cmStringReplaceHelper replaceHelper("([][()+*^.$?|\\\\])", R"(\\\1)");
-  if (!replaceHelper.Replace(input, output)) {
+  try {
+    // Escape all regex special characters
+    data.Quote();
+    // Store the output in the provided variable.
+    status.GetMakefile().AddDefinition(outvar, data);
+    return true;
+  } catch (std::exception const& e) {
     status.SetError(
-      "sub-command REGEX, mode QUOTE: " + replaceHelper.GetError() + ".");
+      cmStrCat("sub-command REGEX, mode QUOTE: ", e.what(), '.'));
     return false;
   }
-
-  // Store the output in the provided variable.
-  status.GetMakefile().AddDefinition(outvar, output);
-  return true;
 }
 
 bool HandleFindCommand(std::vector<std::string> const& args,
@@ -423,19 +342,14 @@
   }
 
   // try to find the character and return its position
-  size_t pos;
-  if (!reverseMode) {
-    pos = sstring.find(schar);
-  } else {
-    pos = sstring.rfind(schar);
-  }
-  if (std::string::npos != pos) {
-    status.GetMakefile().AddDefinition(outvar, std::to_string(pos));
-    return true;
-  }
+  auto pos = cm::CMakeString{ sstring }.Find(
+    schar,
+    reverseMode ? cm::CMakeString::FindFrom::End
+                : cm::CMakeString::FindFrom::Begin);
 
-  // the character was not found, but this is not really an error
-  status.GetMakefile().AddDefinition(outvar, "-1");
+  status.GetMakefile().AddDefinition(
+    outvar, pos != cm::CMakeString::npos ? std::to_string(pos) : "-1");
+
   return true;
 }
 
@@ -462,25 +376,22 @@
     std::string const& right = args[3];
     std::string const& outvar = args[4];
     bool result;
+    cm::CMakeString::CompOperator op = cm::CMakeString::CompOperator::EQUAL;
     if (mode == "LESS") {
-      result = (left < right);
+      op = cm::CMakeString::CompOperator::LESS;
     } else if (mode == "LESS_EQUAL") {
-      result = (left <= right);
+      op = cm::CMakeString::CompOperator::LESS_EQUAL;
     } else if (mode == "GREATER") {
-      result = (left > right);
+      op = cm::CMakeString::CompOperator::GREATER;
     } else if (mode == "GREATER_EQUAL") {
-      result = (left >= right);
-    } else if (mode == "EQUAL") {
-      result = (left == right);
-    } else // if(mode == "NOTEQUAL")
-    {
-      result = !(left == right);
+      op = cm::CMakeString::CompOperator::GREATER_EQUAL;
     }
-    if (result) {
-      status.GetMakefile().AddDefinition(outvar, "1");
-    } else {
-      status.GetMakefile().AddDefinition(outvar, "0");
+    result = cm::CMakeString{ left }.Compare(op, right);
+    if (mode == "NOTEQUAL") {
+      result = !result;
     }
+
+    status.GetMakefile().AddDefinition(outvar, result ? "1" : "0");
     return true;
   }
   std::string e = "sub-command COMPARE does not recognize mode " + mode;
@@ -496,17 +407,19 @@
     return false;
   }
 
-  std::string const& matchExpression = args[1];
-  std::string const& replaceExpression = args[2];
-  std::string const& variableName = args[3];
+  try {
+    std::string const& matchExpression = args[1];
+    std::string const& replaceExpression = args[2];
+    std::string const& variableName = args[3];
+    cm::CMakeString data{ cmMakeRange(args).advance(4) };
 
-  std::string input = cmJoin(cmMakeRange(args).advance(4), std::string());
-
-  cmsys::SystemTools::ReplaceString(input, matchExpression.c_str(),
-                                    replaceExpression.c_str());
-
-  status.GetMakefile().AddDefinition(variableName, input);
-  return true;
+    data.Replace(matchExpression, replaceExpression);
+    status.GetMakefile().AddDefinition(variableName, data);
+    return true;
+  } catch (std::exception const& e) {
+    status.SetError(cmStrCat("sub-command REPLACE: ", e.what(), '.'));
+    return false;
+  }
 }
 
 bool HandleSubstringCommand(std::vector<std::string> const& args,
@@ -517,25 +430,19 @@
     return false;
   }
 
-  std::string const& stringValue = args[1];
-  int begin = atoi(args[2].c_str());
-  int end = atoi(args[3].c_str());
-  std::string const& variableName = args[4];
+  try {
+    std::string const& stringValue = args[1];
+    int begin = atoi(args[2].c_str());
+    int end = atoi(args[3].c_str());
+    std::string const& variableName = args[4];
 
-  size_t stringLength = stringValue.size();
-  int intStringLength = static_cast<int>(stringLength);
-  if (begin < 0 || begin > intStringLength) {
-    status.SetError(
-      cmStrCat("begin index: ", begin, " is out of range 0 - ", stringLength));
+    cm::CMakeString data{ stringValue };
+    status.GetMakefile().AddDefinition(variableName,
+                                       data.Substring(begin, end));
+  } catch (std::exception const& e) {
+    status.SetError(e.what());
     return false;
   }
-  if (end < -1) {
-    status.SetError(cmStrCat("end index: ", end, " should be -1 or greater"));
-    return false;
-  }
-
-  status.GetMakefile().AddDefinition(variableName,
-                                     stringValue.substr(begin, end));
   return true;
 }
 
@@ -550,11 +457,8 @@
   std::string const& stringValue = args[1];
   std::string const& variableName = args[2];
 
-  size_t length = stringValue.size();
-  char buffer[1024];
-  snprintf(buffer, sizeof(buffer), "%d", static_cast<int>(length));
-
-  status.GetMakefile().AddDefinition(variableName, buffer);
+  status.GetMakefile().AddDefinition(
+    variableName, std::to_string(cm::CMakeString{ stringValue }.Length()));
   return true;
 }
 
@@ -572,12 +476,10 @@
   }
 
   auto const& variableName = args[1];
+  cm::CMakeString data{ status.GetMakefile().GetDefinition(variableName) };
 
-  cm::string_view oldView{ status.GetMakefile().GetSafeDefinition(
-    variableName) };
-
-  auto const newValue = cmJoin(cmMakeRange(args).advance(2), {}, oldView);
-  status.GetMakefile().AddDefinition(variableName, newValue);
+  data.Append(cmMakeRange(args).advance(2));
+  status.GetMakefile().AddDefinition(variableName, data);
 
   return true;
 }
@@ -596,13 +498,10 @@
   }
 
   std::string const& variable = args[1];
+  cm::CMakeString data{ status.GetMakefile().GetDefinition(variable) };
 
-  std::string value = cmJoin(cmMakeRange(args).advance(2), std::string());
-  cmValue oldValue = status.GetMakefile().GetDefinition(variable);
-  if (oldValue) {
-    value += *oldValue;
-  }
-  status.GetMakefile().AddDefinition(variable, value);
+  data.Prepend(cmMakeRange(args).advance(2));
+  status.GetMakefile().AddDefinition(variable, data);
   return true;
 }
 
@@ -634,9 +533,9 @@
   std::string const& variableName = args[varIdx];
   // NOTE Items to concat/join placed right after the variable for
   // both `CONCAT` and `JOIN` sub-commands.
-  std::string value = cmJoin(cmMakeRange(args).advance(varIdx + 1), glue);
+  cm::CMakeString data{ cmMakeRange(args).advance(varIdx + 1), glue };
 
-  makefile.AddDefinition(variableName, value);
+  makefile.AddDefinition(variableName, data);
   return true;
 }
 
@@ -652,7 +551,7 @@
   std::string const& variableName = args[2];
 
   status.GetMakefile().AddDefinition(variableName,
-                                     cmSystemTools::MakeCidentifier(input));
+                                     cm::CMakeString{}.MakeCIdentifier(input));
   return true;
 }
 
@@ -664,14 +563,11 @@
     return false;
   }
 
-  std::string const& input = args[1];
-
-  std::string result = cmGeneratorExpression::Preprocess(
-    input, cmGeneratorExpression::StripAllGeneratorExpressions);
-
+  cm::CMakeString data{ args[1] };
   std::string const& variableName = args[2];
 
-  status.GetMakefile().AddDefinition(variableName, result);
+  status.GetMakefile().AddDefinition(
+    variableName, data.Strip(cm::CMakeString::StripItems::Genex));
   return true;
 }
 
@@ -683,36 +579,10 @@
     return false;
   }
 
-  std::string const& stringValue = args[1];
+  cm::CMakeString data{ args[1] };
   std::string const& variableName = args[2];
-  size_t inStringLength = stringValue.size();
-  size_t startPos = inStringLength + 1;
-  size_t endPos = 0;
-  char const* ptr = stringValue.c_str();
-  size_t cc;
-  for (cc = 0; cc < inStringLength; ++cc) {
-    if (!cmIsSpace(*ptr)) {
-      if (startPos > inStringLength) {
-        startPos = cc;
-      }
-      endPos = cc;
-    }
-    ++ptr;
-  }
 
-  size_t outLength = 0;
-
-  // if the input string didn't contain any non-space characters, return
-  // an empty string
-  if (startPos > inStringLength) {
-    outLength = 0;
-    startPos = 0;
-  } else {
-    outLength = endPos - startPos + 1;
-  }
-
-  status.GetMakefile().AddDefinition(variableName,
-                                     stringValue.substr(startPos, outLength));
+  status.GetMakefile().AddDefinition(variableName, data.Strip());
   return true;
 }
 
@@ -744,30 +614,12 @@
     return true;
   }
 
-  auto const& stringValue = args[ArgPos::VALUE];
+  cm::CMakeString data{ args[ArgPos::VALUE] };
+  data.Repeat(times);
+
   auto const& variableName = args[ArgPos::OUTPUT_VARIABLE];
-  auto const inStringLength = stringValue.size();
 
-  std::string result;
-  switch (inStringLength) {
-    case 0u:
-      // Nothing to do for zero length input strings
-      break;
-    case 1u:
-      // NOTE If the string to repeat consists of the only character,
-      // use the appropriate constructor.
-      result = std::string(times, stringValue[0]);
-      break;
-    default:
-      result = std::string(inStringLength * times, char{});
-      for (auto i = 0u; i < times; ++i) {
-        std::copy(cm::cbegin(stringValue), cm::cend(stringValue),
-                  &result[i * inStringLength]);
-      }
-      break;
-  }
-
-  makefile.AddDefinition(variableName, result);
+  makefile.AddDefinition(variableName, data);
   return true;
 }
 
@@ -779,14 +631,10 @@
     return false;
   }
 
-  static bool seeded = false;
+  int length = 5;
+  cm::string_view alphabet;
   bool force_seed = false;
   unsigned int seed = 0;
-  int length = 5;
-  char const cmStringCommandDefaultAlphabet[] = "qwertyuiopasdfghjklzxcvbnm"
-                                                "QWERTYUIOPASDFGHJKLZXCVBNM"
-                                                "0123456789";
-  std::string alphabet;
 
   if (args.size() > 3) {
     size_t i = 1;
@@ -806,37 +654,22 @@
       }
     }
   }
-  if (alphabet.empty()) {
-    alphabet = cmStringCommandDefaultAlphabet;
-  }
 
-  double sizeofAlphabet = static_cast<double>(alphabet.size());
-  if (sizeofAlphabet < 1) {
-    status.SetError("sub-command RANDOM invoked with bad alphabet.");
+  try {
+    cm::CMakeString data;
+    std::string const& variableName = args.back();
+
+    if (force_seed) {
+      data.Random(seed, length, alphabet);
+    } else {
+      data.Random(length, alphabet);
+    }
+    status.GetMakefile().AddDefinition(variableName, data);
+    return true;
+  } catch (std::exception const& e) {
+    status.SetError(cmStrCat("sub-command RANDOM: ", e.what(), '.'));
     return false;
   }
-  if (length < 1) {
-    status.SetError("sub-command RANDOM invoked with bad length.");
-    return false;
-  }
-  std::string const& variableName = args.back();
-
-  std::vector<char> result;
-
-  if (!seeded || force_seed) {
-    seeded = true;
-    srand(force_seed ? seed : cmSystemTools::RandomSeed());
-  }
-
-  char const* alphaPtr = alphabet.c_str();
-  for (int cc = 0; cc < length; cc++) {
-    int idx = static_cast<int>(sizeofAlphabet * rand() / (RAND_MAX + 1.0));
-    result.push_back(*(alphaPtr + idx));
-  }
-  result.push_back(0);
-
-  status.GetMakefile().AddDefinition(variableName, result.data());
-  return true;
 }
 
 bool HandleTimestampCommand(std::vector<std::string> const& args,
@@ -855,26 +688,28 @@
 
   std::string const& outputVariable = args[argsIndex++];
 
-  std::string formatString;
+  cm::string_view formatString;
   if (args.size() > argsIndex && args[argsIndex] != "UTC") {
     formatString = args[argsIndex++];
   }
 
-  bool utcFlag = false;
+  cm::CMakeString::UTC utcFlag = cm::CMakeString::UTC::No;
   if (args.size() > argsIndex) {
     if (args[argsIndex] == "UTC") {
-      utcFlag = true;
+      utcFlag = cm::CMakeString::UTC::Yes;
     } else {
-      std::string e = " TIMESTAMP sub-command does not recognize option " +
-        args[argsIndex] + ".";
+      std::string e =
+        cmStrCat(" TIMESTAMP sub-command does not recognize option ",
+                 args[argsIndex], '.');
       status.SetError(e);
       return false;
     }
   }
 
-  cmTimestamp timestamp;
-  std::string result = timestamp.CurrentTime(formatString, utcFlag);
-  status.GetMakefile().AddDefinition(outputVariable, result);
+  cm::CMakeString data;
+
+  status.GetMakefile().AddDefinition(outputVariable,
+                                     data.Timestamp(formatString, utcFlag));
 
   return true;
 }
@@ -892,10 +727,10 @@
 
   std::string const& outputVariable = args[argsIndex++];
 
-  std::string uuidNamespaceString;
-  std::string uuidName;
-  std::string uuidType;
-  bool uuidUpperCase = false;
+  cm::string_view uuidNamespaceString;
+  cm::string_view uuidName;
+  cm::CMakeString::UUIDType uuidType = cm::CMakeString::UUIDType::MD5;
+  cm::CMakeString::Case uuidCase = cm::CMakeString::Case::Lower;
 
   while (args.size() > argsIndex) {
     if (args[argsIndex] == "NAMESPACE") {
@@ -918,50 +753,39 @@
         status.SetError("UUID sub-command, TYPE requires a value.");
         return false;
       }
-      uuidType = args[argsIndex++];
+      if (args[argsIndex] == "MD5") {
+        uuidType = cm::CMakeString::UUIDType::MD5;
+      } else if (args[argsIndex] == "SHA1") {
+        uuidType = cm::CMakeString::UUIDType::SHA1;
+      } else {
+        status.SetError(
+          cmStrCat("UUID sub-command, unknown TYPE '", args[argsIndex], "'."));
+        return false;
+      }
+      argsIndex++;
     } else if (args[argsIndex] == "UPPER") {
       ++argsIndex;
-      uuidUpperCase = true;
+      uuidCase = cm::CMakeString::Case::Upper;
     } else {
-      std::string e =
-        "UUID sub-command does not recognize option " + args[argsIndex] + ".";
+      std::string e = cmStrCat("UUID sub-command does not recognize option ",
+                               args[argsIndex], '.');
       status.SetError(e);
       return false;
     }
   }
 
-  std::string uuid;
-  cmUuid uuidGenerator;
+  try {
+    cm::CMakeString data;
 
-  std::vector<unsigned char> uuidNamespace;
-  if (!uuidGenerator.StringToBinary(uuidNamespaceString, uuidNamespace)) {
-    status.SetError("UUID sub-command, malformed NAMESPACE UUID.");
+    data.UUID(uuidNamespaceString, uuidName, uuidType, uuidCase);
+    status.GetMakefile().AddDefinition(outputVariable, data);
+    return true;
+  } catch (std::exception const& e) {
+    status.SetError(cmStrCat("UUID sub-command, ", e.what(), '.'));
     return false;
   }
-
-  if (uuidType == "MD5") {
-    uuid = uuidGenerator.FromMd5(uuidNamespace, uuidName);
-  } else if (uuidType == "SHA1") {
-    uuid = uuidGenerator.FromSha1(uuidNamespace, uuidName);
-  } else {
-    std::string e = "UUID sub-command, unknown TYPE '" + uuidType + "'.";
-    status.SetError(e);
-    return false;
-  }
-
-  if (uuid.empty()) {
-    status.SetError("UUID sub-command, generation failed.");
-    return false;
-  }
-
-  if (uuidUpperCase) {
-    uuid = cmSystemTools::UpperCase(uuid);
-  }
-
-  status.GetMakefile().AddDefinition(outputVariable, uuid);
-  return true;
 #else
-  status.SetError(cmStrCat(args[0], " not available during bootstrap"));
+  status.SetError("UUID sub-command not available during bootstrap.");
   return false;
 #endif
 }
diff --git a/Source/cmStringReplaceHelper.cxx b/Source/cmStringReplaceHelper.cxx
index 6dad0b0..0e18457 100644
--- a/Source/cmStringReplaceHelper.cxx
+++ b/Source/cmStringReplaceHelper.cxx
@@ -20,8 +20,7 @@
   this->ParseReplaceExpression();
 }
 
-bool cmStringReplaceHelper::Replace(std::string const& input,
-                                    std::string& output)
+bool cmStringReplaceHelper::Replace(cm::string_view input, std::string& output)
 {
   output.clear();
 
@@ -36,7 +35,7 @@
   auto& re = this->RegularExpression;
   std::string::size_type base = 0;
   unsigned optNonEmpty = 0;
-  while (re.find(input, base, optAnchor | optNonEmpty)) {
+  while (re.find(input.data(), base, optAnchor | optNonEmpty)) {
     if (this->Makefile) {
       this->Makefile->ClearMatches();
       this->Makefile->StoreMatches(re);
diff --git a/Source/cmStringReplaceHelper.h b/Source/cmStringReplaceHelper.h
index ffe9983..ef1c259 100644
--- a/Source/cmStringReplaceHelper.h
+++ b/Source/cmStringReplaceHelper.h
@@ -6,6 +6,8 @@
 #include <utility>
 #include <vector>
 
+#include <cm/string_view>
+
 #include "cmsys/RegularExpression.hxx"
 
 class cmMakefile;
@@ -25,7 +27,7 @@
     return this->ValidReplaceExpression;
   }
 
-  bool Replace(std::string const& input, std::string& output);
+  bool Replace(cm::string_view input, std::string& output);
 
   std::string const& GetError() { return this->ErrorString; }
 
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index ae050da..ee1dba4 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -642,7 +642,7 @@
 {
   std::vector<std::string> arg_full;
   for (std::string const& arg : cmMakeRange(argBeg, argEnd)) {
-    if (cmHasLiteralPrefix(arg, "@")) {
+    if (cmHasPrefix(arg, '@')) {
       cmsys::ifstream responseFile(arg.substr(1).c_str(), std::ios::in);
       if (!responseFile) {
         std::string error = cmStrCat("failed to open for reading (",
@@ -1646,20 +1646,6 @@
   return CopyResult::Success;
 }
 
-bool cmSystemTools::CopyFileIfNewer(std::string const& source,
-                                    std::string const& destination)
-{
-  return cmsys::SystemTools::CopyFileIfNewer(source, destination).IsSuccess();
-}
-
-bool cmSystemTools::CopyADirectory(std::string const& source,
-                                   std::string const& destination,
-                                   CopyWhen when)
-{
-  return cmsys::SystemTools::CopyADirectory(source, destination, when)
-    .IsSuccess();
-}
-
 bool cmSystemTools::RenameFile(std::string const& oldname,
                                std::string const& newname)
 {
@@ -2036,7 +2022,7 @@
   if (in == top) {
     out = ".";
   } else if (cmSystemTools::IsSubDirectory(in, top)) {
-    out = in.substr(top.size() + 1);
+    out = in.substr(top.size() + (top.back() == '/' ? 0 : 1));
   } else {
     out = in;
   }
@@ -4197,21 +4183,21 @@
   return newRPath.empty();
 }
 
-bool cmSystemTools::RepeatedRemoveDirectory(std::string const& dir)
+cmsys::Status cmSystemTools::RepeatedRemoveDirectory(std::string const& dir)
 {
 #ifdef _WIN32
   // Windows sometimes locks files temporarily so try a few times.
   WindowsFileRetry retry = cmSystemTools::GetWindowsFileRetry();
 
-  for (unsigned int i = 0; i < retry.Count; ++i) {
-    if (cmSystemTools::RemoveADirectory(dir)) {
-      return true;
-    }
+  cmsys::Status status;
+  unsigned int tries = 0;
+  while (!(status = cmSystemTools::RemoveADirectory(dir)) &&
+         ++tries < retry.Count) {
     cmSystemTools::Delay(retry.Delay);
   }
-  return false;
+  return status;
 #else
-  return static_cast<bool>(cmSystemTools::RemoveADirectory(dir));
+  return cmSystemTools::RemoveADirectory(dir);
 #endif
 }
 
diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h
index 53b2592..946dea9 100644
--- a/Source/cmSystemTools.h
+++ b/Source/cmSystemTools.h
@@ -205,15 +205,6 @@
                                    CopyInputRecent inputRecent,
                                    std::string* err = nullptr);
 
-  /** Copy a file if it is newer than the destination. */
-  static bool CopyFileIfNewer(std::string const& source,
-                              std::string const& destination);
-
-  /** Copy directory contents with specified copy behavior. */
-  static bool CopyADirectory(std::string const& source,
-                             std::string const& destination,
-                             CopyWhen when = CopyWhen::Always);
-
   enum class Replace
   {
     Yes,
@@ -644,7 +635,7 @@
   static bool CheckRPath(std::string const& file, std::string const& newRPath);
 
   /** Remove a directory; repeat a few times in case of locked files.  */
-  static bool RepeatedRemoveDirectory(std::string const& dir);
+  static cmsys::Status RepeatedRemoveDirectory(std::string const& dir);
 
   /** Encode a string as a URL.  */
   static std::string EncodeURL(std::string const& in,
diff --git a/Source/cmTargetLinkLibrariesCommand.cxx b/Source/cmTargetLinkLibrariesCommand.cxx
index 0d6cb7c..2c68392 100644
--- a/Source/cmTargetLinkLibrariesCommand.cxx
+++ b/Source/cmTargetLinkLibrariesCommand.cxx
@@ -283,7 +283,7 @@
           if (cmHasLiteralPrefix(cur, "$<")) {
             ++genexNesting;
             ++pos;
-          } else if (genexNesting > 0 && cmHasLiteralPrefix(cur, ">")) {
+          } else if (genexNesting > 0 && cmHasPrefix(cur, '>')) {
             --genexNesting;
           }
         }
diff --git a/Source/cmTargetPrecompileHeadersCommand.cxx b/Source/cmTargetPrecompileHeadersCommand.cxx
index 5a57c06..7313089 100644
--- a/Source/cmTargetPrecompileHeadersCommand.cxx
+++ b/Source/cmTargetPrecompileHeadersCommand.cxx
@@ -28,7 +28,7 @@
     // Use '<foo.h>' and '"foo.h"' includes and absolute paths as-is.
     // Interpret relative paths with respect to the source directory.
     // If the path starts in a generator expression, assume it is absolute.
-    if (cmHasLiteralPrefix(src, "<") || cmHasLiteralPrefix(src, "\"") ||
+    if (cmHasPrefix(src, '<') || cmHasPrefix(src, '"') ||
         cmSystemTools::FileIsFullPath(src) ||
         cmGeneratorExpression::Find(src) == 0) {
       absoluteSrc = src;
diff --git a/Source/cmTimestamp.cxx b/Source/cmTimestamp.cxx
index b76dd66..9c029f5 100644
--- a/Source/cmTimestamp.cxx
+++ b/Source/cmTimestamp.cxx
@@ -36,7 +36,7 @@
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
 
-std::string cmTimestamp::CurrentTime(std::string const& formatString,
+std::string cmTimestamp::CurrentTime(cm::string_view formatString,
                                      bool utcFlag) const
 {
   // get current time with microsecond resolution
@@ -63,11 +63,12 @@
   }
 
   return this->CreateTimestampFromTimeT(currentTimeT, microseconds,
-                                        formatString, utcFlag);
+                                        static_cast<std::string>(formatString),
+                                        utcFlag);
 }
 
 std::string cmTimestamp::FileModificationTime(char const* path,
-                                              std::string const& formatString,
+                                              cm::string_view formatString,
                                               bool utcFlag) const
 {
   std::string real_path =
@@ -89,8 +90,8 @@
   }
   uv_fs_req_cleanup(&req);
 
-  return this->CreateTimestampFromTimeT(mtime, microseconds, formatString,
-                                        utcFlag);
+  return this->CreateTimestampFromTimeT(
+    mtime, microseconds, static_cast<std::string>(formatString), utcFlag);
 }
 
 std::string cmTimestamp::CreateTimestampFromTimeT(time_t timeT,
diff --git a/Source/cmTimestamp.h b/Source/cmTimestamp.h
index 1057cc9..f6bff01 100644
--- a/Source/cmTimestamp.h
+++ b/Source/cmTimestamp.h
@@ -8,6 +8,8 @@
 #include <ctime>
 #include <string>
 
+#include <cm/string_view>
+
 /** \class cmTimestamp
  * \brief Utility class to generate string representation of a timestamp
  *
@@ -15,10 +17,10 @@
 class cmTimestamp
 {
 public:
-  std::string CurrentTime(std::string const& formatString, bool utcFlag) const;
+  std::string CurrentTime(cm::string_view formatString, bool utcFlag) const;
 
   std::string FileModificationTime(char const* path,
-                                   std::string const& formatString,
+                                   cm::string_view formatString,
                                    bool utcFlag) const;
 
   std::string CreateTimestampFromTimeT(time_t timeT, std::string formatString,
diff --git a/Source/cmTryCompileCommand.cxx b/Source/cmTryCompileCommand.cxx
index 40d3d8a..b830792 100644
--- a/Source/cmTryCompileCommand.cxx
+++ b/Source/cmTryCompileCommand.cxx
@@ -45,7 +45,8 @@
     return false;
   }
 
-  if (mf.GetCMakeInstance()->GetWorkingMode() == cmake::FIND_PACKAGE_MODE) {
+  if (mf.GetCMakeInstance()->GetState()->GetRole() ==
+      cmState::Role::FindPackage) {
     mf.IssueMessage(
       MessageType::FATAL_ERROR,
       "The try_compile() command is not supported in --find-package mode.");
diff --git a/Source/cmTryRunCommand.cxx b/Source/cmTryRunCommand.cxx
index 0889ff0..5c46d7d 100644
--- a/Source/cmTryRunCommand.cxx
+++ b/Source/cmTryRunCommand.cxx
@@ -548,7 +548,8 @@
     return false;
   }
 
-  if (mf.GetCMakeInstance()->GetWorkingMode() == cmake::FIND_PACKAGE_MODE) {
+  if (mf.GetCMakeInstance()->GetState()->GetRole() ==
+      cmState::Role::FindPackage) {
     mf.IssueMessage(
       MessageType::FATAL_ERROR,
       "The try_run() command is not supported in --find-package mode.");
diff --git a/Source/cmUnsetCommand.cxx b/Source/cmUnsetCommand.cxx
index 117118c..fdb1b06 100644
--- a/Source/cmUnsetCommand.cxx
+++ b/Source/cmUnsetCommand.cxx
@@ -30,7 +30,7 @@
   }
   // unset(CACHE{VAR})
   if (cmHasLiteralPrefix(variable, "CACHE{") && variable.size() > 7 &&
-      cmHasLiteralSuffix(variable, "}")) {
+      cmHasSuffix(variable, '}')) {
     // get the variable name
     auto const& varName = variable.substr(6, variable.size() - 7);
     status.GetMakefile().RemoveCacheDefinition(varName);
diff --git a/Source/cmUuid.cxx b/Source/cmUuid.cxx
index bc2ff59..4f1f9a3 100644
--- a/Source/cmUuid.cxx
+++ b/Source/cmUuid.cxx
@@ -10,7 +10,7 @@
 static std::array<int, 5> const kUuidGroups = { { 4, 2, 2, 2, 6 } };
 
 std::string cmUuid::FromMd5(std::vector<unsigned char> const& uuidNamespace,
-                            std::string const& name) const
+                            cm::string_view name) const
 {
   std::vector<unsigned char> hashInput;
   this->CreateHashInput(uuidNamespace, name, hashInput);
@@ -24,7 +24,7 @@
 }
 
 std::string cmUuid::FromSha1(std::vector<unsigned char> const& uuidNamespace,
-                             std::string const& name) const
+                             cm::string_view name) const
 {
   std::vector<unsigned char> hashInput;
   this->CreateHashInput(uuidNamespace, name, hashInput);
@@ -38,7 +38,7 @@
 }
 
 void cmUuid::CreateHashInput(std::vector<unsigned char> const& uuidNamespace,
-                             std::string const& name,
+                             cm::string_view name,
                              std::vector<unsigned char>& output) const
 {
   output = uuidNamespace;
@@ -46,7 +46,7 @@
   if (!name.empty()) {
     output.resize(output.size() + name.size());
 
-    memcpy(output.data() + uuidNamespace.size(), name.c_str(), name.size());
+    memcpy(output.data() + uuidNamespace.size(), name.data(), name.size());
   }
 }
 
@@ -67,7 +67,7 @@
   return this->BinaryToString(uuid);
 }
 
-bool cmUuid::StringToBinary(std::string const& input,
+bool cmUuid::StringToBinary(cm::string_view input,
                             std::vector<unsigned char>& output) const
 {
   output.clear();
@@ -126,7 +126,7 @@
   return result;
 }
 
-bool cmUuid::StringToBinaryImpl(std::string const& input,
+bool cmUuid::StringToBinaryImpl(cm::string_view input,
                                 std::vector<unsigned char>& output) const
 {
   if (input.size() % 2) {
diff --git a/Source/cmUuid.h b/Source/cmUuid.h
index cf51ece..f6d7067 100644
--- a/Source/cmUuid.h
+++ b/Source/cmUuid.h
@@ -7,6 +7,8 @@
 #include <string>
 #include <vector>
 
+#include <cm/string_view>
+
 /** \class cmUuid
  * \brief Utility class to generate UUIDs as defined by RFC4122
  *
@@ -15,25 +17,25 @@
 {
 public:
   std::string FromMd5(std::vector<unsigned char> const& uuidNamespace,
-                      std::string const& name) const;
+                      cm::string_view name) const;
 
   std::string FromSha1(std::vector<unsigned char> const& uuidNamespace,
-                       std::string const& name) const;
+                       cm::string_view name) const;
 
-  bool StringToBinary(std::string const& input,
+  bool StringToBinary(cm::string_view input,
                       std::vector<unsigned char>& output) const;
 
 private:
   std::string ByteToHex(unsigned char byte) const;
 
   void CreateHashInput(std::vector<unsigned char> const& uuidNamespace,
-                       std::string const& name,
+                       cm::string_view name,
                        std::vector<unsigned char>& output) const;
 
   std::string FromDigest(unsigned char const* digest,
                          unsigned char version) const;
 
-  bool StringToBinaryImpl(std::string const& input,
+  bool StringToBinaryImpl(cm::string_view input,
                           std::vector<unsigned char>& output) const;
 
   std::string BinaryToString(unsigned char const* input) const;
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 3cd9c62..23d7fd6 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -3872,7 +3872,8 @@
   auto cudaVersion = this->GlobalGenerator->GetPlatformToolsetCudaString();
 
   // Get compile flags for CUDA in this directory.
-  std::string flags;
+  std::string flags =
+    this->Makefile->GetSafeDefinition("_CMAKE_CUDA_EXTRA_FLAGS");
   this->LocalGenerator->AddLanguageFlags(
     flags, this->GeneratorTarget, cmBuildStep::Compile, "CUDA", configName);
   this->LocalGenerator->AddCompileOptions(flags, this->GeneratorTarget, "CUDA",
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index 3f2710d..af6e6c7 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -4,6 +4,7 @@
 
 #include <algorithm>
 #include <array>
+#include <cassert>
 #include <chrono>
 #include <cstdio>
 #include <cstdlib>
@@ -298,13 +299,13 @@
     "not errors." }
 };
 
-cmake::cmake(Role role, cmState::Mode mode, cmState::ProjectKind projectKind)
+cmake::cmake(cmState::Role role, cmState::TryCompile isTryCompile)
   : CMakeWorkingDirectory(cmSystemTools::GetLogicalWorkingDirectory())
   , FileTimeCache(cm::make_unique<cmFileTimeCache>())
 #ifndef CMAKE_BOOTSTRAP
   , VariableWatch(cm::make_unique<cmVariableWatch>())
 #endif
-  , State(cm::make_unique<cmState>(mode, projectKind))
+  , State(cm::make_unique<cmState>(role, isTryCompile))
   , Messenger(cm::make_unique<cmMessenger>())
 {
   this->TraceFile.close();
@@ -322,14 +323,16 @@
 
   this->AddDefaultGenerators();
   this->AddDefaultExtraGenerators();
-  if (role == RoleScript || role == RoleProject) {
+  if (role == cmState::Role::Project || role == cmState::Role::FindPackage ||
+      role == cmState::Role::Script || role == cmState::Role::CTest ||
+      role == cmState::Role::CPack) {
     this->AddScriptingCommands();
   }
-  if (role == RoleProject) {
+  if (role == cmState::Role::Project || role == cmState::Role::FindPackage) {
     this->AddProjectCommands();
   }
 
-  if (mode == cmState::Project || mode == cmState::Help) {
+  if (role == cmState::Role::Project || role == cmState::Role::Help) {
     this->LoadEnvironmentPresets();
   }
 
@@ -449,6 +452,23 @@
   return result;
 }
 
+bool cmake::RoleSupportsExitCode() const
+{
+  cmState::Role const role = this->State->GetRole();
+  return role == cmState::Role::Script || role == cmState::Role::CTest;
+}
+
+cmake::CommandFailureAction cmake::GetCommandFailureAction() const
+{
+  switch (this->State->GetRole()) {
+    case cmState::Role::Project:
+    case cmState::Role::CTest:
+      return CommandFailureAction::EXIT_CODE;
+    default:
+      return CommandFailureAction::FATAL_ERROR;
+  }
+}
+
 void cmake::CleanupCommandsAndMacros()
 {
   this->CurrentSnapshot = this->State->Reset();
@@ -653,6 +673,7 @@
   };
 
   auto ScriptLambda = [&](std::string const& path, cmake* state) -> bool {
+    assert(this->State->GetRole() == cmState::Role::Script);
 #ifdef CMake_ENABLE_DEBUGGER
     // Script mode doesn't hit the usual code path in cmake::Run() that starts
     // the debugger, so start it manually here instead.
@@ -664,8 +685,6 @@
     GetProjectCommandsInScriptMode(state->GetState());
     // Documented behavior of CMAKE{,_CURRENT}_{SOURCE,BINARY}_DIR is to be
     // set to $PWD for -P mode.
-    state->SetWorkingMode(SCRIPT_MODE,
-                          cmake::CommandFailureAction::FATAL_ERROR);
     state->SetHomeDirectory(cmSystemTools::GetLogicalWorkingDirectory());
     state->SetHomeOutputDirectory(cmSystemTools::GetLogicalWorkingDirectory());
     state->ReadListFile(args, path);
@@ -737,7 +756,7 @@
   for (decltype(args.size()) i = 1; i < args.size(); ++i) {
     std::string const& arg = args[i];
 
-    if (arg == "--" && this->GetWorkingMode() == SCRIPT_MODE) {
+    if (arg == "--" && this->State->GetRole() == cmState::Role::Script) {
       // Stop processing CMake args and avoid possible errors
       // when arbitrary args are given to CMake script.
       break;
@@ -752,7 +771,7 @@
     }
   }
 
-  if (this->GetWorkingMode() == FIND_PACKAGE_MODE) {
+  if (this->State->GetRole() == cmState::Role::FindPackage) {
     return this->FindPackage(args);
   }
 
@@ -806,7 +825,7 @@
     snapshot.GetDirectory().SetCurrentSource(this->GetHomeDirectory());
     snapshot.SetDefaultDefinitions();
     cmMakefile mf(gg, snapshot);
-    if (this->GetWorkingMode() != NORMAL_MODE) {
+    if (this->State->GetRole() == cmState::Role::Script) {
       mf.SetScriptModeFile(cmSystemTools::ToNormalizedPathOnDisk(path));
       mf.SetArgcArgv(args);
     }
@@ -1428,7 +1447,7 @@
     // iterate each argument
     std::string const& arg = args[i];
 
-    if (this->GetWorkingMode() == SCRIPT_MODE && arg == "--") {
+    if (this->State->GetRole() == cmState::Role::Script && arg == "--") {
       // Stop processing CMake args and avoid possible errors
       // when arbitrary args are given to CMake script.
       break;
@@ -1464,7 +1483,7 @@
     if (!parsedCorrectly) {
       cmSystemTools::Error("Run 'cmake --help' for all supported options.");
       exit(1);
-    } else if (!matched && cmHasLiteralPrefix(arg, "-")) {
+    } else if (!matched && cmHasPrefix(arg, '-')) {
       possibleUnknownArg = arg;
     } else if (!matched) {
       bool parsedDirectory = this->SetDirectoriesFromFile(arg);
@@ -1474,12 +1493,14 @@
     }
   }
 
-  if (!extraProvidedPath.empty() && this->GetWorkingMode() == NORMAL_MODE) {
+  if (!extraProvidedPath.empty() &&
+      this->State->GetRole() == cmState::Role::Project) {
     this->IssueMessage(MessageType::WARNING,
                        cmStrCat("Ignoring extra path from command line:\n \"",
                                 extraProvidedPath, '"'));
   }
-  if (!possibleUnknownArg.empty() && this->GetWorkingMode() != SCRIPT_MODE) {
+  if (!possibleUnknownArg.empty() &&
+      this->State->GetRole() != cmState::Role::Script) {
     cmSystemTools::Error(cmStrCat("Unknown argument ", possibleUnknownArg));
     cmSystemTools::Error("Run 'cmake --help' for all supported options.");
     exit(1);
@@ -1528,7 +1549,7 @@
     !presetName.empty();
 #endif
 
-  if (this->CurrentWorkingMode == cmake::NORMAL_MODE && !haveSourceDir &&
+  if (this->State->GetRole() == cmState::Role::Project && !haveSourceDir &&
       !haveBinaryDir && !havePreset) {
     this->IssueMessage(
       MessageType::WARNING,
@@ -1571,8 +1592,7 @@
         presetsGraph.PrintAllPresets();
       }
 
-      this->SetWorkingMode(WorkingMode::HELP_MODE,
-                           cmake::CommandFailureAction::FATAL_ERROR);
+      this->State->SetRoleToHelpForListPresets();
       return;
     }
 
@@ -1891,7 +1911,7 @@
     if (this->LoadCache(cachePath)) {
       cmValue existingValue =
         this->State->GetCacheEntryValue("CMAKE_HOME_DIRECTORY");
-      if (existingValue) {
+      if (existingValue && !existingValue.IsEmpty()) {
         this->SetHomeOutputDirectory(cachePath);
         this->SetHomeDirectory(*existingValue);
         return true;
@@ -2139,7 +2159,7 @@
 
   auto prev_path = this->GetHomeDirectory();
   if (prev_path != path && !prev_path.empty() &&
-      this->GetWorkingMode() == NORMAL_MODE) {
+      this->State->GetRole() == cmState::Role::Project) {
     this->IssueMessage(
       MessageType::WARNING,
       cmStrCat("Ignoring extra path from command line:\n \"", prev_path, '"'));
@@ -2149,12 +2169,13 @@
 
 void cmake::SetHomeDirectory(std::string const& dir)
 {
+  assert(!dir.empty());
   this->State->SetSourceDirectory(dir);
   if (this->CurrentSnapshot.IsValid()) {
     this->CurrentSnapshot.SetDefinition("CMAKE_SOURCE_DIR", dir);
   }
 
-  if (this->State->GetProjectKind() == cmState::ProjectKind::Normal) {
+  if (this->State->GetIsTryCompile() == cmState::TryCompile::No) {
     this->Messenger->SetTopSource(this->GetHomeDirectory());
   } else {
     this->Messenger->SetTopSource(cm::nullopt);
@@ -2168,6 +2189,7 @@
 
 void cmake::SetHomeOutputDirectory(std::string const& dir)
 {
+  assert(!dir.empty());
   this->State->SetBinaryDirectory(dir);
   if (this->CurrentSnapshot.IsValid()) {
     this->CurrentSnapshot.SetDefinition("CMAKE_BINARY_DIR", dir);
@@ -2707,7 +2729,7 @@
   auto endTime = std::chrono::steady_clock::now();
 
   // configure result
-  if (this->GetWorkingMode() == cmake::NORMAL_MODE) {
+  if (this->State->GetRole() == cmState::Role::Project) {
     std::ostringstream msg;
     if (cmSystemTools::GetErrorOccurredFlag()) {
       msg << "Configuring incomplete, errors occurred!";
@@ -2938,7 +2960,7 @@
   if (cmSystemTools::GetErrorOccurredFlag()) {
     return -1;
   }
-  if (this->GetWorkingMode() == HELP_MODE) {
+  if (this->State->GetRole() == cmState::Role::Help) {
     return 0;
   }
 
@@ -2968,7 +2990,7 @@
     return 0;
   }
 
-  if (this->GetWorkingMode() == NORMAL_MODE) {
+  if (this->State->GetRole() == cmState::Role::Project) {
     if (this->FreshCache) {
       this->DeleteCache(this->GetHomeOutputDirectory());
     }
@@ -3015,7 +3037,7 @@
 #endif
 
   // In script mode we terminate after running the script.
-  if (this->GetWorkingMode() != NORMAL_MODE) {
+  if (this->State->GetRole() != cmState::Role::Project) {
     if (cmSystemTools::GetErrorOccurredFlag()) {
       return -1;
     }
@@ -3385,7 +3407,7 @@
 
 bool cmake::GetIsInTryCompile() const
 {
-  return this->State->GetProjectKind() == cmState::ProjectKind::TryCompile;
+  return this->State->GetIsTryCompile() == cmState::TryCompile::Yes;
 }
 
 void cmake::AppendGlobalGeneratorsDocumentation(
@@ -3475,9 +3497,7 @@
   // Read the rerun check file and use it to decide whether to do the
   // global generate.
   // Actually, all we need is the `set` command.
-  cmake cm(RoleScript, cmState::Unknown);
-  cm.SetHomeDirectory("");
-  cm.SetHomeOutputDirectory("");
+  cmake cm(cmState::Role::Script);
   cm.GetCurrentSnapshot().SetDefaultDefinitions();
   cmGlobalGenerator gg(&cm);
   cmMakefile mf(&gg, cm.GetCurrentSnapshot());
@@ -3818,9 +3838,6 @@
                  std::string const& presetName, bool listPresets,
                  std::vector<std::string> const& args)
 {
-  this->SetHomeDirectory("");
-  this->SetHomeOutputDirectory("");
-
 #if !defined(CMAKE_BOOTSTRAP)
   if (!presetName.empty() || listPresets) {
     this->SetHomeDirectory(cmSystemTools::GetLogicalWorkingDirectory());
@@ -3900,7 +3917,7 @@
       return 1;
     }
 
-    if (!expandedConfigurePreset->BinaryDir.empty()) {
+    if (dir.empty() && !expandedConfigurePreset->BinaryDir.empty()) {
       dir = expandedConfigurePreset->BinaryDir;
     }
 
@@ -4015,39 +4032,32 @@
     cmGlobalVisualStudio14Generator::GetGenerateStampList();
 
   // Note that the stampList file only exists for VS generators.
-  if (cmSystemTools::FileExists(stampList)) {
-
+  if (cmSystemTools::FileExists(stampList) &&
+      !cmakeCheckStampList(stampList)) {
+    // Upgrade cmake role from --build to reconfigure the project.
+    this->State->SetRoleToProjectForCMakeBuildVsReconfigure();
     this->AddScriptingCommands();
+    this->AddProjectCommands();
 
-    if (!cmakeCheckStampList(stampList)) {
-      // Correctly initialize the home (=source) and home output (=binary)
-      // directories, which is required for running the generation step.
-      std::string homeOrig = this->GetHomeDirectory();
-      std::string homeOutputOrig = this->GetHomeOutputDirectory();
-      this->SetDirectoriesFromFile(cachePath);
+    // Correctly initialize the home (=source) and home output (=binary)
+    // directories, which is required for running the generation step.
+    this->SetDirectoriesFromFile(cachePath);
 
-      this->AddProjectCommands();
-
-      int ret = this->Configure();
-      if (ret) {
-        cmSystemTools::Message("CMake Configure step failed.  "
-                               "Build files cannot be regenerated correctly.");
-        return ret;
-      }
-      ret = this->Generate();
-      if (ret) {
-        cmSystemTools::Message("CMake Generate step failed.  "
-                               "Build files cannot be regenerated correctly.");
-        return ret;
-      }
-      std::string message = cmStrCat("Build files have been written to: ",
-                                     this->GetHomeOutputDirectory());
-      this->UpdateProgress(message, -1);
-
-      // Restore the previously set directories to their original value.
-      this->SetHomeDirectory(homeOrig);
-      this->SetHomeOutputDirectory(homeOutputOrig);
+    int ret = this->Configure();
+    if (ret) {
+      cmSystemTools::Message("CMake Configure step failed.  "
+                             "Build files cannot be regenerated correctly.");
+      return ret;
     }
+    ret = this->Generate();
+    if (ret) {
+      cmSystemTools::Message("CMake Generate step failed.  "
+                             "Build files cannot be regenerated correctly.");
+      return ret;
+    }
+    std::string message = cmStrCat("Build files have been written to: ",
+                                   this->GetHomeOutputDirectory());
+    this->UpdateProgress(message, -1);
   }
 #endif
 
@@ -4095,8 +4105,6 @@
 
 bool cmake::Open(std::string const& dir, DryRun dryRun)
 {
-  this->SetHomeDirectory("");
-  this->SetHomeOutputDirectory("");
   if (!cmSystemTools::FileIsDirectory(dir)) {
     if (dryRun == DryRun::No) {
       std::cerr << "Error: " << dir << " is not a directory\n";
@@ -4511,10 +4519,14 @@
 
 std::string cmake::GetCMakeListFile(std::string const& dir) const
 {
-  std::string listFile = cmStrCat(dir, '/', this->CMakeListName);
-  if (this->CMakeListName.empty() ||
-      !cmSystemTools::FileExists(listFile, true)) {
-    return cmStrCat(dir, "/CMakeLists.txt");
+  assert(!dir.empty());
+  cm::string_view const slash = dir.back() != '/' ? "/"_s : ""_s;
+  std::string listFile;
+  if (!this->CMakeListName.empty()) {
+    listFile = cmStrCat(dir, slash, this->CMakeListName);
+  }
+  if (listFile.empty() || !cmSystemTools::FileExists(listFile, true)) {
+    listFile = cmStrCat(dir, slash, "CMakeLists.txt");
   }
   return listFile;
 }
diff --git a/Source/cmake.h b/Source/cmake.h
index f4c9ed4..4874566 100644
--- a/Source/cmake.h
+++ b/Source/cmake.h
@@ -84,13 +84,6 @@
 class cmake
 {
 public:
-  enum Role
-  {
-    RoleInternal, // no commands
-    RoleScript,   // script commands
-    RoleProject   // all commands
-  };
-
   enum DiagLevel
   {
     DIAG_IGNORE,
@@ -169,8 +162,8 @@
   static int const DEFAULT_BUILD_PARALLEL_LEVEL = 0;
 
   /// Default constructor
-  cmake(Role role, cmState::Mode mode,
-        cmState::ProjectKind projectKind = cmState::ProjectKind::Normal);
+  cmake(cmState::Role role,
+        cmState::TryCompile isTryCompile = cmState::TryCompile::No);
   /// Destructor
   ~cmake();
 
@@ -450,18 +443,9 @@
   //! Do all the checks before running configure
   int DoPreConfigureChecks();
 
-  void SetWorkingMode(WorkingMode mode, CommandFailureAction policy)
-  {
-    this->CurrentWorkingMode = mode;
-    this->CurrentCommandFailureAction = policy;
-  }
+  bool RoleSupportsExitCode() const;
 
-  WorkingMode GetWorkingMode() const { return this->CurrentWorkingMode; }
-
-  CommandFailureAction GetCommandFailureAction() const
-  {
-    return this->CurrentCommandFailureAction;
-  }
+  CommandFailureAction GetCommandFailureAction() const;
 
   //! Debug the try compile stuff by not deleting the files
   bool GetDebugTryCompile() const { return this->DebugTryCompile; }
@@ -813,9 +797,6 @@
   std::vector<std::string> cmdArgs;
   std::string CMakeWorkingDirectory;
   ProgressCallbackType ProgressCallback;
-  WorkingMode CurrentWorkingMode = NORMAL_MODE;
-  CommandFailureAction CurrentCommandFailureAction =
-    CommandFailureAction::FATAL_ERROR;
   bool DebugOutput = false;
   bool DebugFindOutput = false;
   // Elements of `cmakeLangTraceCmdStack` are "trace requests" pushed
diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx
index d8a753f..d3ccf56 100644
--- a/Source/cmakemain.cxx
+++ b/Source/cmakemain.cxx
@@ -221,9 +221,7 @@
   doc.addCMakeStandardDocSections();
   if (doc.CheckOptions(ac, av, "--")) {
     // Construct and print requested documentation.
-    cmake hcm(cmake::RoleInternal, cmState::Help);
-    hcm.SetHomeDirectory("");
-    hcm.SetHomeOutputDirectory("");
+    cmake hcm(cmState::Role::Help);
     hcm.AddCMakePaths();
 
     // the command line args are processed here so that you can do
@@ -262,7 +260,7 @@
   // (Regex) Filter on the cached variable(s) to print.
   std::string filter_var_name;
   bool view_only = false;
-  cmake::WorkingMode workingMode = cmake::NORMAL_MODE;
+  cmState::Role role = cmState::Role::Project;
   std::vector<std::string> parsedArgs;
 
   using CommandArgument =
@@ -308,20 +306,20 @@
                      CommandArgument::Values::One,
                      CommandArgument::RequiresSeparator::No,
                      [&](std::string const& value) -> bool {
-                       workingMode = cmake::SCRIPT_MODE;
+                       role = cmState::Role::Script;
                        parsedArgs.emplace_back("-P");
                        parsedArgs.push_back(value);
                        return true;
                      } },
     CommandArgument{ "--find-package", CommandArgument::Values::Zero,
                      [&](std::string const&) -> bool {
-                       workingMode = cmake::FIND_PACKAGE_MODE;
+                       role = cmState::Role::FindPackage;
                        parsedArgs.emplace_back("--find-package");
                        return true;
                      } },
     CommandArgument{ "--list-presets", CommandArgument::Values::ZeroOrOne,
                      [&](std::string const& value) -> bool {
-                       workingMode = cmake::HELP_MODE;
+                       role = cmState::Role::Help;
                        parsedArgs.emplace_back("--list-presets");
                        parsedArgs.emplace_back(value);
                        return true;
@@ -338,7 +336,7 @@
 
     // Only in script mode do we stop parsing instead
     // of preferring the last mode flag provided
-    if (arg == "--" && workingMode == cmake::SCRIPT_MODE) {
+    if (arg == "--" && role == cmState::Role::Script) {
       parsedArgs = inputArgs;
       break;
     }
@@ -361,33 +359,11 @@
   }
 
   if (sysinfo) {
-    cmake cm(cmake::RoleProject, cmState::Project);
-    cm.SetHomeDirectory("");
-    cm.SetHomeOutputDirectory("");
+    cmake cm(cmState::Role::Project);
     int ret = cm.GetSystemInformation(parsedArgs);
     return ret;
   }
-  cmake::Role const role =
-    workingMode == cmake::SCRIPT_MODE ? cmake::RoleScript : cmake::RoleProject;
-  cmState::Mode mode = cmState::Unknown;
-  switch (workingMode) {
-    case cmake::NORMAL_MODE:
-    case cmake::HELP_MODE:
-      mode = cmState::Project;
-      break;
-    case cmake::SCRIPT_MODE:
-      mode = cmState::Script;
-      break;
-    case cmake::FIND_PACKAGE_MODE:
-      mode = cmState::FindPackage;
-      break;
-  }
-  auto const failurePolicy = workingMode == cmake::NORMAL_MODE
-    ? cmake::CommandFailureAction::EXIT_CODE
-    : cmake::CommandFailureAction::FATAL_ERROR;
-  cmake cm(role, mode);
-  cm.SetHomeDirectory("");
-  cm.SetHomeOutputDirectory("");
+  cmake cm(role);
   cmSystemTools::SetMessageCallback(
     [&cm](std::string const& msg, cmMessageMetadata const& md) {
       cmakemainMessageCallback(msg, md, &cm);
@@ -395,7 +371,6 @@
   cm.SetProgressCallback([&cm](std::string const& msg, float prog) {
     cmakemainProgressCallback(msg, prog, &cm);
   });
-  cm.SetWorkingMode(workingMode, failurePolicy);
 
   int res = cm.Run(parsedArgs, view_only);
   if (list_cached || list_all_cached) {
@@ -685,7 +660,7 @@
     return 1;
   }
 
-  cmake cm(cmake::RoleInternal, cmState::Project);
+  cmake cm(cmState::Role::Internal);
   cmSystemTools::SetMessageCallback(
     [&cm](std::string const& msg, cmMessageMetadata const& md) {
       cmakemainMessageCallback(msg, md, &cm);
@@ -967,7 +942,7 @@
     } else {
       for (auto const& script : handler.GetScripts()) {
         std::vector<std::string> cmd = script.command;
-        cmake cm(cmake::RoleScript, cmState::Script);
+        cmake cm(cmState::Role::Script);
         cmSystemTools::SetMessageCallback(
           [&cm](std::string const& msg, cmMessageMetadata const& md) {
             cmakemainMessageCallback(msg, md, &cm);
@@ -975,11 +950,7 @@
         cm.SetProgressCallback([&cm](std::string const& msg, float prog) {
           cmakemainProgressCallback(msg, prog, &cm);
         });
-        cm.SetHomeDirectory("");
-        cm.SetHomeOutputDirectory("");
         cm.SetDebugOutputOn(verbose);
-        cm.SetWorkingMode(cmake::SCRIPT_MODE,
-                          cmake::CommandFailureAction::FATAL_ERROR);
         ret_ = int(bool(cm.Run(cmd)));
       }
     }
@@ -1072,7 +1043,7 @@
     return 1;
   }
 
-  cmake cm(cmake::RoleInternal, cmState::Project);
+  cmake cm(cmState::Role::Internal);
   cmSystemTools::SetMessageCallback(
     [&cm](std::string const& msg, cmMessageMetadata const& md) {
       cmakemainMessageCallback(msg, md, &cm);
@@ -1116,7 +1087,7 @@
     return 1;
   }
 
-  cmake cm(cmake::RoleInternal, cmState::Unknown);
+  cmake cm(cmState::Role::Internal);
   cmSystemTools::SetMessageCallback(
     [&cm](std::string const& msg, cmMessageMetadata const& md) {
       cmakemainMessageCallback(msg, md, &cm);
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx
index 3195353..09c35c0 100644
--- a/Source/cmcmd.cxx
+++ b/Source/cmcmd.cxx
@@ -180,7 +180,7 @@
     }
     if (cmHasLiteralPrefix(line, "--add-file=")) {
       files.push_back(line.substr(11));
-    } else if (cmHasLiteralPrefix(line, "-")) {
+    } else if (cmHasPrefix(line, '-')) {
       cmSystemTools::Error(cmStrCat("-E tar --files-from='", file,
                                     "' file invalid line:\n", line, '\n'));
       return false;
@@ -749,9 +749,11 @@
       // If error occurs we want to continue copying next files.
       bool return_value = false;
       for (auto const& file : files) {
-        if (!cmsys::SystemTools::CopyFileAlways(file, *targetArg)) {
+        cmsys::SystemTools::CopyStatus const status =
+          cmSystemTools::CopyFileAlways(file, *targetArg);
+        if (!status) {
           std::cerr << "Error copying file \"" << file << "\" to \""
-                    << *targetArg << "\".\n";
+                    << *targetArg << "\": " << status.GetString() << '\n';
           return_value = true;
         }
       }
@@ -771,9 +773,12 @@
       // If error occurs we want to continue copying next files.
       bool return_value = false;
       for (auto const& arg : cmMakeRange(args).advance(2).retreat(1)) {
-        if (!cmSystemTools::CopyFileIfDifferent(arg, args.back())) {
+        cmsys::SystemTools::CopyStatus const status =
+          cmSystemTools::CopyFileIfDifferent(arg, args.back());
+        if (!status) {
           std::cerr << "Error copying file (if different) from \"" << arg
-                    << "\" to \"" << args.back() << "\".\n";
+                    << "\" to \"" << args.back()
+                    << "\": " << status.GetString() << '\n';
           return_value = true;
         }
       }
@@ -793,9 +798,12 @@
       // If error occurs we want to continue copying next files.
       bool return_value = false;
       for (auto const& arg : cmMakeRange(args).advance(2).retreat(1)) {
-        if (!cmSystemTools::CopyFileIfNewer(arg, args.back())) {
+        cmsys::SystemTools::CopyStatus const status =
+          cmSystemTools::CopyFileIfNewer(arg, args.back());
+        if (!status) {
           std::cerr << "Error copying file (if newer) from \"" << arg
-                    << "\" to \"" << args.back() << "\".\n";
+                    << "\" to \"" << args.back()
+                    << "\": " << status.GetString() << '\n';
           return_value = true;
         }
       }
@@ -818,9 +826,11 @@
       }
 
       for (auto const& arg : cmMakeRange(args).advance(2).retreat(1)) {
-        if (!cmSystemTools::CopyADirectory(arg, args.back(), when)) {
+        cmsys::Status const status =
+          cmSystemTools::CopyADirectory(arg, args.back(), when);
+        if (!status) {
           std::cerr << "Error copying directory from \"" << arg << "\" to \""
-                    << args.back() << "\".\n";
+                    << args.back() << "\": " << status.GetString() << '\n';
           return_value = true;
         }
       }
@@ -1023,8 +1033,10 @@
       // If an error occurs, we want to continue making directories.
       bool return_value = false;
       for (auto const& arg : cmMakeRange(args).advance(2)) {
-        if (!cmSystemTools::MakeDirectory(arg)) {
-          std::cerr << "Error creating directory \"" << arg << "\".\n";
+        cmsys::Status const status = cmSystemTools::MakeDirectory(arg);
+        if (!status) {
+          std::cerr << "Error creating directory \"" << arg
+                    << "\": " << status.GetString() << '\n';
           return_value = true;
         }
       }
@@ -1072,7 +1084,7 @@
       bool doing_options = true;
       bool at_least_one_file = false;
       for (auto const& arg : cmMakeRange(args).advance(2)) {
-        if (doing_options && cmHasLiteralPrefix(arg, "-")) {
+        if (doing_options && cmHasPrefix(arg, '-')) {
           if (arg == "--") {
             doing_options = false;
           }
@@ -1150,7 +1162,7 @@
         std::cerr << "-E capabilities accepts no additional arguments\n";
         return 1;
       }
-      cmake cm(cmake::RoleInternal, cmState::Unknown);
+      cmake cm(cmState::Role::Internal);
       std::cout << cm.ReportCapabilities();
       return 0;
     }
@@ -1227,7 +1239,7 @@
           // Destroy console buffers to drop cout/cerr encoding transform.
           console.reset();
           cmCatFile(arg);
-        } else if (doing_options && cmHasLiteralPrefix(arg, "-")) {
+        } else if (doing_options && cmHasPrefix(arg, '-')) {
           if (arg == "--") {
             doing_options = false;
           } else {
@@ -1398,7 +1410,7 @@
 
       // Create a cmake object instance to process dependencies.
       // All we need is the `set` command.
-      cmake cm(cmake::RoleScript, cmState::Unknown);
+      cmake cm(cmState::Role::Script);
       std::string gen;
       std::string homeDir;
       std::string startDir;
@@ -1752,7 +1764,7 @@
       }
       // Create a cmake object instance to process dependencies.
       // All we need is the `set` command.
-      cmake cm(cmake::RoleScript, cmState::Unknown);
+      cmake cm(cmState::Role::Script);
       std::string homeDir;
       std::string startDir;
       std::string homeOutDir;
@@ -2404,13 +2416,13 @@
   // Parse our own arguments.
   std::string intDir;
   auto arg = argBeg;
-  while (arg != argEnd && cmHasLiteralPrefix(*arg, "-")) {
+  while (arg != argEnd && cmHasPrefix(*arg, '-')) {
     if (*arg == "--") {
       ++arg;
       break;
     }
     if (*arg == "--manifests") {
-      for (++arg; arg != argEnd && !cmHasLiteralPrefix(*arg, "-"); ++arg) {
+      for (++arg; arg != argEnd && !cmHasPrefix(*arg, '-'); ++arg) {
         this->UserManifests.push_back(*arg);
       }
     } else if (cmHasLiteralPrefix(*arg, "--intdir=")) {
diff --git a/Source/kwsys/Directory.cxx b/Source/kwsys/Directory.cxx
index b23c624..fae7761 100644
--- a/Source/kwsys/Directory.cxx
+++ b/Source/kwsys/Directory.cxx
@@ -184,7 +184,7 @@
   delete[] buf;
 
   if (srchHandle == INVALID_HANDLE_VALUE) {
-    Status status = Status::POSIX_errno();
+    Status status = Status::Windows_GetLastError();
     if (errorMessage) {
       *errorMessage = status.GetString();
     }
@@ -198,7 +198,7 @@
   } while (FindNextFileW(srchHandle, &data));
   this->Internal->Path = name;
   if (!FindClose(srchHandle)) {
-    Status status = Status::POSIX_errno();
+    Status status = Status::Windows_GetLastError();
     if (errorMessage) {
       *errorMessage = status.GetString();
     }
diff --git a/Source/kwsys/SystemInformation.cxx b/Source/kwsys/SystemInformation.cxx
index a11487d..5f67f16 100644
--- a/Source/kwsys/SystemInformation.cxx
+++ b/Source/kwsys/SystemInformation.cxx
@@ -4131,6 +4131,10 @@
   this->TotalPhysicalMemory = tp >> 10 >> 10;
   this->AvailableVirtualMemory = av >> 10 >> 10;
   this->AvailablePhysicalMemory = ap >> 10 >> 10;
+
+  // The virtual WinAPI memory contains both physical memory and page file.
+  this->TotalVirtualMemory -= this->TotalPhysicalMemory;
+  this->AvailableVirtualMemory -= this->AvailablePhysicalMemory;
   return true;
 #else
   return false;
diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx
index 9d4e40b..ff1dfe6 100644
--- a/Source/kwsys/SystemTools.cxx
+++ b/Source/kwsys/SystemTools.cxx
@@ -2273,7 +2273,7 @@
   // source and destination are files so do a copy if source is newer
   // Check if source file exists first
   if (!SystemTools::FileExists(source)) {
-    return CopyStatus{ Status::POSIX_errno(), CopyStatus::SourcePath };
+    return CopyStatus{ Status::POSIX(ENOENT), CopyStatus::SourcePath };
   }
   // If destination doesn't exist, always copy
   if (!SystemTools::FileExists(destination)) {
diff --git a/Tests/CMakeGUI/CMakeGUITest.cmake b/Tests/CMakeGUI/CMakeGUITest.cmake
index 9e2c8cc..1049e31 100644
--- a/Tests/CMakeGUI/CMakeGUITest.cmake
+++ b/Tests/CMakeGUI/CMakeGUITest.cmake
@@ -1,3 +1,6 @@
+# Avoid QtTest library timeouts before ctest's timeout.
+set(ENV{QTEST_FUNCTION_TIMEOUT} 3600000)
+
 function(run_cmake_gui_test name)
   if(DEFINED ENV{CMakeGUITest_TEST_FILTER} AND NOT name MATCHES "$ENV{CMakeGUITest_TEST_FILTER}")
     return()
diff --git a/Tests/CMakeLib/CMakeLists.txt b/Tests/CMakeLib/CMakeLists.txt
index a50936e..dee4731 100644
--- a/Tests/CMakeLib/CMakeLists.txt
+++ b/Tests/CMakeLib/CMakeLists.txt
@@ -25,7 +25,7 @@
   testRange.cxx
   testOptional.cxx
   testPathResolver.cxx
-  testSPDXSerializer.cxx
+  testSpdxSerializer.cxx
   testStdIo.cxx
   testString.cxx
   testStringAlgorithms.cxx
diff --git a/Tests/CMakeLib/testDebuggerVariablesHelper.cxx b/Tests/CMakeLib/testDebuggerVariablesHelper.cxx
index 7359231..82bb745 100644
--- a/Tests/CMakeLib/testDebuggerVariablesHelper.cxx
+++ b/Tests/CMakeLib/testDebuggerVariablesHelper.cxx
@@ -54,8 +54,7 @@
   std::string currentBinaryDirectory = "c:/CurrentBinaryDirectory")
 {
   Dummies dummies;
-  dummies.CMake =
-    std::make_shared<cmake>(cmake::RoleProject, cmState::Project);
+  dummies.CMake = std::make_shared<cmake>(cmState::Role::Project);
   cmState* state = dummies.CMake->GetState();
   dummies.GlobalGenerator =
     std::make_shared<cmGlobalGenerator>(dummies.CMake.get());
@@ -501,7 +500,7 @@
   auto variablesManager =
     std::make_shared<cmDebugger::cmDebuggerVariablesManager>();
 
-  cmake cm(cmake::RoleScript, cmState::Unknown);
+  cmake cm(cmState::Role::Internal);
   cmFileSet fileSet(cm, "Foo", "HEADERS", cmFileSetVisibility::Public);
   BT<std::string> directory;
   directory.Value = "c:/";
@@ -545,7 +544,7 @@
   auto variablesManager =
     std::make_shared<cmDebugger::cmDebuggerVariablesManager>();
 
-  cmake cm(cmake::RoleScript, cmState::Unknown);
+  cmake cm(cmState::Role::Internal);
   cmFileSet fileSet(cm, "Foo", "HEADERS", cmFileSetVisibility::Public);
   BT<std::string> directory;
   directory.Value = "c:/";
diff --git a/Tests/CMakeLib/testSPDXSerializer.cxx b/Tests/CMakeLib/testSPDXSerializer.cxx
deleted file mode 100644
index 14f9f7e..0000000
--- a/Tests/CMakeLib/testSPDXSerializer.cxx
+++ /dev/null
@@ -1,648 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
-   file LICENSE.rst or https://cmake.org/licensing for details.  */
-#include <iostream>
-#include <string>
-#include <vector>
-
-#include <cm/optional>
-
-#include <cm3p/json/reader.h>
-#include <cm3p/json/value.h>
-
-#include "cmSPDXSerializer.h"
-
-namespace {
-
-std::string const nonOptional(R"================({
-  "@context": "https://spdx.org/rdf/3.0.1/spdx-context.jsonld",
-  "@graph": [
-    {
-      "@id": "_:contentIdentifier_0",
-      "contentIdentifierType": "INVALID_CONTENT_IDENTIFIER_TYPE_ID",
-      "contentIdentifierValue": "",
-      "type": "ContentIdentifier"
-    },
-    {
-      "@id": "_:creationInfo_0",
-      "created": "",
-      "createdBy": [],
-      "type": "CreationInfo"
-    },
-    {
-      "@id": "_:creationInfo_1",
-      "created": "",
-      "createdBy": [],
-      "type": "CreationInfo"
-    },
-    {
-      "@id": "_:dictionaryEntry_0",
-      "key": "",
-      "type": "DictionaryEntry"
-    },
-    {
-      "@id": "_:externalIdentifier_0",
-      "externalIdentifierType": "INVALID_EXTERNAL_IDENTIFIER_TYPE_ID",
-      "identifier": "",
-      "type": "ExternalIdentifier"
-    },
-    {
-      "@id": "_:externalMap_0",
-      "externalSpdxId": "",
-      "type": "ExternalMap"
-    },
-    {
-      "@id": "_:externalRef_0",
-      "type": "ExternalRef"
-    },
-    {
-      "@id": "_:hash_0",
-      "algorithm": "INVALID_HASH_TYPE_ID",
-      "hashValue": "",
-      "type": "Hash"
-    },
-    {
-      "@id": "_:namespaceMap_0",
-      "namespace": "",
-      "prefix": "",
-      "type": "NamespaceMap"
-    },
-    {
-      "@id": "_:packageVerificationCode_0",
-      "algorithm": "INVALID_HASH_TYPE_ID",
-      "hashValue": "",
-      "type": "PackageVerificationCode"
-    },
-    {
-      "@id": "_:positiveIntegerRange_0",
-      "beginIntegerRange": 0,
-      "endIntegerRange": 0,
-      "type": "PositiveIntegerRange"
-    },
-    {
-      "creationInfo": "_:creationInfo_0",
-      "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd0",
-      "type": "Agent"
-    },
-    {
-      "annotationType": "INVALID_ANNOTATION_TYPE_ID",
-      "creationInfo": "_:creationInfo_0",
-      "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd1",
-      "subject": "",
-      "type": "Annotation"
-    },
-    {
-      "creationInfo": "_:creationInfo_0",
-      "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd10",
-      "type": "SpdxDocument"
-    },
-    {
-      "creationInfo": "_:creationInfo_0",
-      "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd11",
-      "type": "Tool"
-    },
-    {
-      "creationInfo": "_:creationInfo_0",
-      "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd12",
-      "type": "File"
-    },
-    {
-      "creationInfo": "_:creationInfo_0",
-      "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd13",
-      "type": "Package"
-    },
-    {
-      "context": "",
-      "creationInfo": "_:creationInfo_0",
-      "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd14",
-      "type": "Sbom"
-    },
-    {
-      "creationInfo": "_:creationInfo_0",
-      "snippetFromFile": "",
-      "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd15",
-      "type": "Snippet"
-    },
-    {
-      "creationInfo": "_:creationInfo_0",
-      "licenseExpression": "",
-      "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd16",
-      "type": "LicenseExpression"
-    },
-    {
-      "creationInfo": "_:creationInfo_0",
-      "licenseText": "",
-      "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd17",
-      "type": "SimpleLicensingText"
-    },
-    {
-      "context": "",
-      "creationInfo": "_:creationInfo_0",
-      "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd2",
-      "type": "Bom"
-    },
-    {
-      "context": "",
-      "creationInfo": "_:creationInfo_0",
-      "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd3",
-      "type": "Bundle"
-    },
-    {
-      "creationInfo": "_:creationInfo_0",
-      "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd4",
-      "type": "IndividualElement"
-    },
-    {
-      "creationInfo": "_:creationInfo_0",
-      "from": "",
-      "relationshipType": "INVALID_RELATIONSHIP_TYPE_ID",
-      "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd5",
-      "to": [],
-      "type": "LifecycleScopedRelationship"
-    },
-    {
-      "creationInfo": "_:creationInfo_0",
-      "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd6",
-      "type": "Organization"
-    },
-    {
-      "creationInfo": "_:creationInfo_0",
-      "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd7",
-      "type": "Person"
-    },
-    {
-      "creationInfo": "_:creationInfo_0",
-      "from": "",
-      "relationshipType": "INVALID_RELATIONSHIP_TYPE_ID",
-      "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd8",
-      "to": [],
-      "type": "Relationship"
-    },
-    {
-      "creationInfo": "_:creationInfo_0",
-      "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd9",
-      "type": "SoftwareAgent"
-    }
-  ]
-})================");
-
-std::string const Optional(R"================({
-  "@context": "https://spdx.org/rdf/3.0.1/spdx-context.jsonld",
-  "@graph": [
-    {
-      "@id": "_:contentIdentifier_0",
-      "contentIdentifierType": "gitoid",
-      "contentIdentifierValue": "ContentIdentifierValue",
-      "type": "ContentIdentifier"
-    },
-    {
-      "@id": "_:creationInfo_0",
-      "created": "",
-      "createdBy": [],
-      "type": "CreationInfo"
-    },
-    {
-      "@id": "_:creationInfo_1",
-      "Comment": "Comment",
-      "created": "Created",
-      "createdBy": [
-        "testRef"
-      ],
-      "createdUsing": [
-        "testRef"
-      ],
-      "type": "CreationInfo"
-    },
-    {
-      "@id": "_:dictionaryEntry_0",
-      "key": "Key",
-      "type": "DictionaryEntry",
-      "value": "Value"
-    },
-    {
-      "@id": "_:externalIdentifier_0",
-      "comment": "Comment",
-      "externalIdentifierType": "other",
-      "identifier": "Identifier",
-      "identifierLocator": [
-        "IdentifierLocator"
-      ],
-      "issuingAuthority": "IssuingAuthority",
-      "type": "ExternalIdentifier"
-    },
-    {
-      "@id": "_:externalMap_0",
-      "definingArtifact": "testRef",
-      "externalSpdxId": "ExternalSpdxId",
-      "integrityMethod": [
-        "testRef"
-      ],
-      "locationHint": "LocationHint",
-      "type": "ExternalMap"
-    },
-    {
-      "@id": "_:externalRef_0",
-      "comment": "Comment",
-      "contentType": "ContentType",
-      "externalRefType": "other",
-      "locator": [
-        "Locator"
-      ],
-      "type": "ExternalRef"
-    },
-    {
-      "@id": "_:hash_0",
-      "algorithm": "other",
-      "hashValue": "HashValue",
-      "type": "Hash"
-    },
-    {
-      "@id": "_:namespaceMap_0",
-      "namespace": "Namespace",
-      "prefix": "Namespace",
-      "type": "NamespaceMap"
-    },
-    {
-      "@id": "_:packageVerificationCode_0",
-      "algorithm": "other",
-      "hashValue": "HashValue",
-      "type": "PackageVerificationCode"
-    },
-    {
-      "@id": "_:positiveIntegerRange_0",
-      "beginIntegerRange": 1,
-      "endIntegerRange": 2,
-      "type": "PositiveIntegerRange"
-    },
-    {
-      "comment": "Comment",
-      "creationInfo": "_:creationInfo_0",
-      "description": "Description",
-      "extension": [
-        "testRef"
-      ],
-      "externalIdentifier": [
-        "testRef"
-      ],
-      "externalRef": [
-        "testRef"
-      ],
-      "name": "Name",
-      "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd0",
-      "summary": "Summary",
-      "type": "Agent",
-      "verifiedUsing": [
-        "testRef"
-      ]
-    },
-    {
-      "annotationType": "other",
-      "contentType": "ContentType",
-      "creationInfo": "_:creationInfo_0",
-      "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd1",
-      "statement": "Statement",
-      "subject": "testRef",
-      "type": "Annotation"
-    },
-    {
-      "creationInfo": "_:creationInfo_0",
-      "dataLicense": "testRef",
-      "externalMap": "testRef",
-      "namespaceMap": "testRef",
-      "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd10",
-      "type": "SpdxDocument"
-    },
-    {
-      "creationInfo": "_:creationInfo_0",
-      "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd11",
-      "type": "Tool"
-    },
-    {
-      "additionalPurpose": [
-        "other"
-      ],
-      "attributionText": "AttributionText",
-      "contentIdentifier": "testRef",
-      "contentType": "ContentType",
-      "copyrightText": "CopyrightText",
-      "creationInfo": "_:creationInfo_0",
-      "fileKind": "file",
-      "primaryPurpose": "file",
-      "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd12",
-      "type": "File"
-    },
-    {
-      "creationInfo": "_:creationInfo_0",
-      "downloadLocation": "DownloadLocation",
-      "homePage": "HomePage",
-      "packageUrl": "PackageUrl",
-      "packageVersion": "PackageVersion",
-      "sourceInfo": "SourceInfo",
-      "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd13",
-      "type": "Package"
-    },
-    {
-      "context": "",
-      "creationInfo": "_:creationInfo_0",
-      "sbomType": [
-        "build"
-      ],
-      "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd14",
-      "type": "Sbom"
-    },
-    {
-      "byteRange": "testRef",
-      "creationInfo": "_:creationInfo_0",
-      "lineRange": "testRef",
-      "snippetFromFile": "testRef",
-      "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd15",
-      "type": "Snippet"
-    },
-    {
-      "creationInfo": "_:creationInfo_0",
-      "customIdToUri": [
-        "testRef"
-      ],
-      "licenseExpression": "LicenseExpression",
-      "licenseListVersion": "LicenseListVersion",
-      "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd16",
-      "type": "LicenseExpression"
-    },
-    {
-      "creationInfo": "_:creationInfo_0",
-      "licenseText": "LicenseText",
-      "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd17",
-      "type": "SimpleLicensingText"
-    },
-    {
-      "context": "Context",
-      "creationInfo": "_:creationInfo_0",
-      "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd2",
-      "type": "Bom"
-    },
-    {
-      "context": "",
-      "creationInfo": "_:creationInfo_0",
-      "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd3",
-      "type": "Bundle"
-    },
-    {
-      "creationInfo": "_:creationInfo_0",
-      "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd4",
-      "type": "IndividualElement"
-    },
-    {
-      "completeness": "noAssertion",
-      "creationInfo": "_:creationInfo_0",
-      "endTime": "EndTime",
-      "from": "testRef",
-      "relationshipType": "other",
-      "scope": "other",
-      "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd5",
-      "startTime": "StartTime",
-      "to": [
-        "testRef"
-      ],
-      "type": "LifecycleScopedRelationship"
-    },
-    {
-      "creationInfo": "_:creationInfo_0",
-      "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd6",
-      "type": "Organization"
-    },
-    {
-      "creationInfo": "_:creationInfo_0",
-      "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd7",
-      "type": "Person"
-    },
-    {
-      "creationInfo": "_:creationInfo_0",
-      "from": "",
-      "relationshipType": "INVALID_RELATIONSHIP_TYPE_ID",
-      "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd8",
-      "to": [],
-      "type": "Relationship"
-    },
-    {
-      "creationInfo": "_:creationInfo_0",
-      "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd9",
-      "type": "SoftwareAgent"
-    }
-  ]
-})================");
-}
-
-int testNonOptional()
-{
-  cmSPDXSimpleGraph graph("https://cmake.org/testSPDXSerialization-gnrtd");
-
-  // Core
-  graph.insert<cmSPDXAgent>();
-  graph.insert<cmSPDXAnnotation>();
-  graph.insert<cmSPDXBom>();
-  graph.insert<cmSPDXBundle>();
-  graph.insert<cmSPDXCreationInfo>();
-  graph.insert<cmSPDXDictionaryEntry>();
-  graph.insert<cmSPDXExternalIdentifier>();
-  graph.insert<cmSPDXExternalMap>();
-  graph.insert<cmSPDXExternalRef>();
-  graph.insert<cmSPDXHash>();
-  graph.insert<cmSPDXIndividualElement>();
-  graph.insert<cmSPDXLifecycleScopedRelationship>();
-  graph.insert<cmSPDXNamespaceMap>();
-  graph.insert<cmSPDXOrganization>();
-  graph.insert<cmSPDXPackageVerificationCode>();
-  graph.insert<cmSPDXPerson>();
-  graph.insert<cmSPDXPositiveIntegerRange>();
-  graph.insert<cmSPDXRelationship>();
-  graph.insert<cmSPDXSoftwareAgent>();
-  graph.insert<cmSPDXSpdxDocument>();
-  graph.insert<cmSPDXTool>();
-
-  // Software
-  graph.insert<cmSPDXContentIdentifier>();
-  graph.insert<cmSPDXFile>();
-  graph.insert<cmSPDXPackage>();
-  graph.insert<cmSPDXSbom>();
-  graph.insert<cmSPDXSnippet>();
-
-  // SimpleLicensing
-  graph.insert<cmSPDXLicenseExpression>();
-  graph.insert<cmSPDXSimpleLicensingText>();
-
-  Json::Value root;
-  Json::Reader().parse(nonOptional.c_str(), root);
-
-  std::cout << "NonOptional SPDX:";
-  std::cout << "\nConstructed Graph: " << graph.toJsonLD().toStyledString();
-  std::cout << "\nComparison Graph:" << root.toStyledString() << "\n";
-
-  // Convert to string to disregard differences in number signedness
-  return root.toStyledString() == graph.toJsonLD().toStyledString();
-};
-
-int testOptional()
-{
-  cmSPDXSimpleGraph graph("https://cmake.org/testSPDXSerialization-gnrtd");
-
-  cmSPDXIdentifierReference ident("testRef");
-
-  // Core
-  auto& agent = graph.insert<cmSPDXAgent>();
-  agent.Comment = "Comment";
-  agent.Description = "Description";
-  agent.Extension.emplace().push_back(ident);
-  agent.ExternalIdentifier.emplace().push_back(ident);
-  agent.ExternalRef.emplace().push_back(ident);
-  agent.Name = "Name";
-  agent.Summary = "Summary";
-  agent.VerifiedUsing.emplace().push_back(ident);
-
-  auto& annotation = graph.insert<cmSPDXAnnotation>();
-  annotation.AnnotationType = cmSPDXAnnotationType::OTHER;
-  annotation.ContentType = "ContentType";
-  annotation.Statement = "Statement";
-  annotation.Subject = ident;
-
-  auto& bom = graph.insert<cmSPDXBom>();
-  bom.Context = "Context";
-
-  graph.insert<cmSPDXBundle>();
-
-  auto& creationInfo = graph.insert<cmSPDXCreationInfo>();
-  creationInfo.Comment = "Comment";
-  creationInfo.Created = "Created";
-  creationInfo.CreatedBy.push_back(ident);
-  creationInfo.CreatedUsing.emplace().push_back(ident);
-
-  auto& dictionaryEntry = graph.insert<cmSPDXDictionaryEntry>();
-  dictionaryEntry.Key = "Key";
-  dictionaryEntry.Value = "Value";
-
-  auto& externalIdentifier = graph.insert<cmSPDXExternalIdentifier>();
-  externalIdentifier.Comment = "Comment";
-  externalIdentifier.ExternalIdentifierType =
-    cmSPDXExternalIdentifierType::OTHER;
-  externalIdentifier.Identifier = "Identifier";
-  externalIdentifier.IdentifierLocator.emplace().push_back(
-    "IdentifierLocator");
-  externalIdentifier.IssuingAuthority = "IssuingAuthority";
-
-  auto& externalMap = graph.insert<cmSPDXExternalMap>();
-  externalMap.DefiningArtifact = ident;
-  externalMap.ExternalSpdxId = "ExternalSpdxId";
-  externalMap.LocationHint = "LocationHint";
-  externalMap.IntegrityMethod.emplace().push_back(ident);
-
-  auto& externalRef = graph.insert<cmSPDXExternalRef>();
-  externalRef.Comment = "Comment";
-  externalRef.ContentType = "ContentType";
-  externalRef.ExternalRefType = cmSPDXExternalRefType::OTHER;
-  externalRef.Locator.emplace().push_back("Locator");
-
-  auto& hash = graph.insert<cmSPDXHash>();
-  hash.Algorithm = cmSPDXHashAlgorithm::OTHER;
-  hash.HashValue = "HashValue";
-
-  graph.insert<cmSPDXIndividualElement>();
-
-  auto& lifecycleScopedRelationship =
-    graph.insert<cmSPDXLifecycleScopedRelationship>();
-  lifecycleScopedRelationship.Completeness =
-    cmSPDXRelationshipCompletenessType::NO_ASSERTION;
-  lifecycleScopedRelationship.EndTime = "EndTime";
-  lifecycleScopedRelationship.From = ident;
-  lifecycleScopedRelationship.RelationshipType = cmSPDXRelationshipType::OTHER;
-  lifecycleScopedRelationship.StartTime = "StartTime";
-  lifecycleScopedRelationship.To.push_back(ident);
-  lifecycleScopedRelationship.Scope = cmSPDXLifecycleScopeType::OTHER;
-
-  auto& namespaceMap = graph.insert<cmSPDXNamespaceMap>();
-  namespaceMap.Namespace = "Namespace";
-  namespaceMap.Prefix = "Prefix";
-
-  graph.insert<cmSPDXOrganization>();
-
-  auto& packageVerificationCode =
-    graph.insert<cmSPDXPackageVerificationCode>();
-  packageVerificationCode.Algorithm = cmSPDXHashAlgorithm::OTHER;
-  packageVerificationCode.HashValue = "HashValue";
-  packageVerificationCode.PackageVerificationCodeExcludedFile.emplace()
-    .push_back("PacakgeVerificationCodeExcludeFile");
-
-  graph.insert<cmSPDXPerson>();
-
-  auto& positiveIntegerRange = graph.insert<cmSPDXPositiveIntegerRange>();
-  positiveIntegerRange.BeginIntegerRange = 1;
-  positiveIntegerRange.EndIntegerRange = 2;
-
-  graph.insert<cmSPDXRelationship>();
-
-  graph.insert<cmSPDXSoftwareAgent>();
-
-  auto& spdxDocument = graph.insert<cmSPDXSpdxDocument>();
-  spdxDocument.DataLicense = ident;
-  spdxDocument.ExternalMap = ident;
-  spdxDocument.NamespaceMap = ident;
-
-  graph.insert<cmSPDXTool>();
-
-  // Software
-  auto& contentIdentifier = graph.insert<cmSPDXContentIdentifier>();
-  contentIdentifier.ContentIdentifierType =
-    cmSPDXContentIdentifierType::GITOID;
-  contentIdentifier.ContentIdentifierValue = "ContentIdentifierValue";
-
-  auto& file = graph.insert<cmSPDXFile>();
-  file.AdditionalPurpose.emplace().push_back(cmSPDXSoftwarePurpose::OTHER);
-  file.AttributionText = "AttributionText";
-  file.ContentIdentifier = ident;
-  file.CopyrightText = "CopyrightText";
-  file.PrimaryPurpose = cmSPDXSoftwarePurpose::FILE;
-  file.ContentType = "ContentType";
-  file.FileKind = cmSPDXFileKindType::FILE;
-
-  auto& package = graph.insert<cmSPDXPackage>();
-  package.DownloadLocation = "DownloadLocation";
-  package.HomePage = "HomePage";
-  package.PackageUrl = "PackageUrl";
-  package.PackageVersion = "PackageVersion";
-  package.SourceInfo = "SourceInfo";
-
-  auto& sbom = graph.insert<cmSPDXSbom>();
-  sbom.SbomType.emplace().push_back(cmSPDXSbomType::BUILD);
-
-  auto& snippet = graph.insert<cmSPDXSnippet>();
-  snippet.ByteRange = ident;
-  snippet.LineRange = ident;
-  snippet.SnippetFromFile = ident;
-
-  // SimpleLicensing
-  auto& licenseExpression = graph.insert<cmSPDXLicenseExpression>();
-  licenseExpression.CustomIdToUri.emplace().push_back(ident);
-  licenseExpression.LicenseExpression = "LicenseExpression";
-  licenseExpression.LicenseListVersion = "LicenseListVersion";
-
-  auto& simpleLicensingText = graph.insert<cmSPDXSimpleLicensingText>();
-  simpleLicensingText.LicenseText = "LicenseText";
-
-  Json::Value root;
-  Json::Reader().parse(Optional.c_str(), root);
-
-  std::cout << "Optional SPDX:";
-  std::cout << "\nConstructed Graph: " << graph.toJsonLD().toStyledString();
-  std::cout << "\nComparison Graph:" << root.toStyledString() << "\n";
-
-  // Convert to string to disregard differences in number signedness
-  return root.toStyledString() == graph.toJsonLD().toStyledString();
-};
-
-int testSPDXSerializer(int /* argc */, char* /* argv */[])
-{
-  if (!testNonOptional())
-    return -1;
-
-  if (!testOptional())
-    return -1;
-
-  return 0;
-}
diff --git a/Tests/CMakeLib/testSpdxSerializer.cxx b/Tests/CMakeLib/testSpdxSerializer.cxx
new file mode 100644
index 0000000..ab394cb
--- /dev/null
+++ b/Tests/CMakeLib/testSpdxSerializer.cxx
@@ -0,0 +1,84 @@
+
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file LICENSE.rst or https://cmake.org/licensing for details.  */
+
+#include <string>
+#include <utility>
+#include <vector>
+
+#include <cm/optional>
+
+#include <cm3p/json/value.h>
+
+#include "cmSbomObject.h"
+#include "cmSpdx.h"
+#include "cmSpdxSerializer.h"
+
+#include "testCommon.h"
+
+namespace {
+
+bool testSerializeSpdxJson()
+{
+
+  auto constexpr contextUrl = "https://spdx.org/rdf/3.0.1/spdx-context.jsonld";
+
+  cmSbomDocument doc;
+  doc.Context = contextUrl;
+
+  cmSpdxDocument spdxValue;
+  spdxValue.SpdxId = "_:SPDXRef-Document";
+  spdxValue.DataLicense = "CC0-1.0";
+  auto spdx = insert_back(doc.Graph, std::move(spdxValue));
+
+  {
+    cmSpdxCreationInfo ci;
+    ci.SpdxId = "_:SPDXRef-CreationInfo";
+    ci.SpecVersion = "3.0.1";
+    spdx->CreationInfo = std::move(ci);
+  }
+
+  {
+    cmSpdxPackage pkg;
+    pkg.Name = "sample-package";
+    pkg.SpdxId = "_:SPDXRef-Package";
+
+    spdx->RootElements.emplace_back(std::move(pkg));
+  }
+
+  {
+    cmSpdxSerializer serializer;
+    doc.Serialize(serializer);
+    auto value = serializer.GetJson();
+
+    ASSERT_TRUE(value.isObject());
+
+    Json::Value const& context = value["@context"];
+    ASSERT_EQUAL(context.asString(), contextUrl);
+
+    Json::Value const& graph = value["@graph"];
+    ASSERT_TRUE(graph.isArray());
+
+    Json::Value const& docValue = graph[0];
+    ASSERT_TRUE(docValue.isObject());
+    ASSERT_EQUAL(docValue["type"].asString(), "SpdxDocument");
+    ASSERT_EQUAL(docValue["@id"].asString(), "_:SPDXRef-Document");
+
+    auto const& creationInfo = docValue["creationInfo"];
+    ASSERT_EQUAL(creationInfo["@id"].asString(), "_:SPDXRef-CreationInfo");
+    ASSERT_EQUAL(creationInfo["type"].asString(), "CreationInfo");
+
+    auto const& package = docValue["rootElement"][0];
+    ASSERT_EQUAL(package["type"].asString(), "software_Package");
+    ASSERT_EQUAL(package["@id"].asString(), "_:SPDXRef-Package");
+  }
+
+  return true;
+}
+
+} // namespace
+
+int testSpdxSerializer(int /*unused*/, char* /*unused*/[])
+{
+  return runTests({ testSerializeSpdxJson });
+}
diff --git a/Tests/CMakeLib/testSystemTools.cxx b/Tests/CMakeLib/testSystemTools.cxx
index 3581474..d34f710 100644
--- a/Tests/CMakeLib/testSystemTools.cxx
+++ b/Tests/CMakeLib/testSystemTools.cxx
@@ -96,6 +96,50 @@
   return true;
 }
 
+static bool testRelativeIfUnder()
+{
+  std::cout << "testRelativeIfUnder()\n";
+
+  std::string result = cmSystemTools::RelativeIfUnder("/a/b", "/a/b");
+  if (result != ".") {
+    std::cout << "cmSystemTools::RelativeIfUnder failed on /a/b, /a/b: "
+              << result << "\n";
+    return false;
+  }
+  result = cmSystemTools::RelativeIfUnder("/a/b", "/a/b/c/d");
+  if (result != "c/d") {
+    std::cout << "cmSystemTools::RelativeIfUnder failed on /a/b, /a/b/c/d: "
+              << result << "\n";
+    return false;
+  }
+  result = cmSystemTools::RelativeIfUnder("/d/f/", "/a/b/c/d");
+  if (result != "/a/b/c/d") {
+    std::cout << "cmSystemTools::RelativeIfUnder failed on /d/f/, /a/b/c/d: "
+              << result << "\n";
+    return false;
+  }
+  result = cmSystemTools::RelativeIfUnder("/", "/a/b");
+  if (result != "a/b") {
+    std::cout << "cmSystemTools::RelativeIfUnder failed on /, /a/b: " << result
+              << "\n";
+    return false;
+  }
+  result = cmSystemTools::RelativeIfUnder("I:/", "I:/CMakeLists.txt");
+  if (result != "CMakeLists.txt") {
+    std::cout
+      << "cmSystemTools::RelativeIfUnder failed on I:/, I:/CMakeLists.txt: "
+      << result << "\n";
+    return false;
+  }
+  result = cmSystemTools::RelativeIfUnder("", "/a/b");
+  if (result != "/a/b") {
+    std::cout << "cmSystemTools::RelativeIfUnder failed on \"\", /a/b: "
+              << result << "\n";
+    return false;
+  }
+  return true;
+}
+
 static bool testMakeTempDirectory()
 {
   std::cout << "testMakeTempDirectory()\n";
@@ -124,6 +168,7 @@
     testUpperCase,
     testVersionCompare,
     testStrVersCmp,
+    testRelativeIfUnder,
     testMakeTempDirectory,
   });
 }
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index 2ead810..22b99ba 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -3283,6 +3283,11 @@
     set(JavaExportImport_BUILD_OPTIONS -DCMake_TEST_NESTED_MAKE_PROGRAM:FILEPATH=${CMake_TEST_EXPLICIT_MAKE_PROGRAM})
     ADD_TEST_MACRO(JavaExportImport JavaExportImport)
 
+    if("${Java_VERSION}" VERSION_GREATER_EQUAL 9)
+      set(JavaModExportImport_BUILD_OPTIONS -DCMake_TEST_NESTED_MAKE_PROGRAM:FILEPATH=${CMake_TEST_EXPLICIT_MAKE_PROGRAM})
+      ADD_TEST_MACRO(JavaModExportImport JavaModExportImport)
+    endif()
+
     get_filename_component(JAVACPATH ${Java_JAVAC_EXECUTABLE} REALPATH)
     get_filename_component(JNIPATH ${JAVACPATH} PATH)
     find_file(JNI_H jni.h
diff --git a/Tests/ExportImport/Import/install-RUNTIME_DEPENDENCIES/CMakeLists.txt b/Tests/ExportImport/Import/install-RUNTIME_DEPENDENCIES/CMakeLists.txt
index d1c4ff2..4f6a953 100644
--- a/Tests/ExportImport/Import/install-RUNTIME_DEPENDENCIES/CMakeLists.txt
+++ b/Tests/ExportImport/Import/install-RUNTIME_DEPENDENCIES/CMakeLists.txt
@@ -1,4 +1,5 @@
 set(CMAKE_SKIP_RPATH OFF)
+cmake_policy(SET CMP0207 NEW)
 
 # Import targets from the install tree.
 include(${Import_BINARY_DIR}/../Root/install-RUNTIME_DEPENDENCY_SET/targets.cmake)
diff --git a/Tests/JavaModExportImport/BuildExport/CMakeLists.txt b/Tests/JavaModExportImport/BuildExport/CMakeLists.txt
new file mode 100644
index 0000000..f818f44
--- /dev/null
+++ b/Tests/JavaModExportImport/BuildExport/CMakeLists.txt
@@ -0,0 +1,13 @@
+project(foo Java)
+
+cmake_minimum_required(VERSION 3.10)
+set(CMAKE_VERBOSE_MAKEFILE 1)
+
+find_package(Java COMPONENTS Development)
+include(UseJava)
+
+add_jar(${PROJECT_NAME} Foo.java module-info.java)
+export_jars(
+  TARGETS ${PROJECT_NAME}
+  NAMESPACE foo::
+  FILE JavaBuildExportTestConfig.cmake)
diff --git a/Tests/JavaModExportImport/BuildExport/Foo.java b/Tests/JavaModExportImport/BuildExport/Foo.java
new file mode 100644
index 0000000..c0e2a1a
--- /dev/null
+++ b/Tests/JavaModExportImport/BuildExport/Foo.java
@@ -0,0 +1,13 @@
+package org.foo;
+
+public class Foo
+{
+  public Foo()
+  {
+  }
+
+  public void printName()
+  {
+    System.out.println("Foo");
+  }
+}
diff --git a/Tests/JavaModExportImport/BuildExport/module-info.java b/Tests/JavaModExportImport/BuildExport/module-info.java
new file mode 100644
index 0000000..aeb0e17
--- /dev/null
+++ b/Tests/JavaModExportImport/BuildExport/module-info.java
@@ -0,0 +1,3 @@
+module mod_foo {
+    exports org.foo;
+}
diff --git a/Tests/JavaModExportImport/CMakeLists.txt b/Tests/JavaModExportImport/CMakeLists.txt
new file mode 100644
index 0000000..5326457
--- /dev/null
+++ b/Tests/JavaModExportImport/CMakeLists.txt
@@ -0,0 +1,105 @@
+cmake_minimum_required(VERSION 3.10)
+project(JavaModExportImport)
+if(NOT DEFINED CMake_TEST_NESTED_MAKE_PROGRAM AND NOT CMAKE_GENERATOR MATCHES "Visual Studio")
+  set(CMake_TEST_NESTED_MAKE_PROGRAM "${CMAKE_MAKE_PROGRAM}")
+endif()
+
+find_package(Java COMPONENTS Development)
+
+# Wipe out the install tree to make sure the exporter works.
+add_custom_command(
+  OUTPUT ${JavaModExportImport_BINARY_DIR}/CleanupProject
+  COMMAND ${CMAKE_COMMAND} -E rm -rf ${JavaModExportImport_BINARY_DIR}/Root
+  )
+add_custom_target(CleanupTarget ALL DEPENDS ${JavaModExportImport_BINARY_DIR}/CleanupProject)
+set_property(
+  SOURCE ${JavaModExportImport_BINARY_DIR}/CleanupProject
+  PROPERTY SYMBOLIC 1
+  )
+
+get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
+if(_isMultiConfig)
+  set(NESTED_CONFIG_TYPE -C "${CMAKE_CFG_INTDIR}")
+else()
+  if(CMAKE_BUILD_TYPE)
+    set(NESTED_CONFIG_TYPE -C "${CMAKE_BUILD_TYPE}")
+  else()
+    set(NESTED_CONFIG_TYPE)
+  endif()
+endif()
+
+configure_file(${JavaModExportImport_SOURCE_DIR}/InitialCache.cmake.in
+               ${JavaModExportImport_BINARY_DIR}/InitialCache.cmake @ONLY)
+
+# Build the build exporter.
+add_custom_command(
+  OUTPUT ${JavaModExportImport_BINARY_DIR}/BuildExportProject
+  COMMAND ${CMAKE_CTEST_COMMAND} ${NESTED_CONFIG_TYPE}
+    --build-and-test
+    ${JavaModExportImport_SOURCE_DIR}/BuildExport
+    ${JavaModExportImport_BINARY_DIR}/BuildExport
+    --build-noclean
+    --build-project BuildExport
+    --build-generator ${CMAKE_GENERATOR}
+    --build-generator-platform "${CMAKE_GENERATOR_PLATFORM}"
+    --build-generator-toolset "${CMAKE_GENERATOR_TOOLSET}"
+    --build-options -C${JavaModExportImport_BINARY_DIR}/InitialCache.cmake
+  VERBATIM
+  )
+add_custom_target(BuildExportTarget ALL DEPENDS ${JavaModExportImport_BINARY_DIR}/BuildExportProject)
+add_dependencies(BuildExportTarget CleanupTarget)
+set_property(
+  SOURCE ${JavaModExportImport_BINARY_DIR}/BuildExportProject
+  PROPERTY SYMBOLIC 1
+  )
+
+# Build and install the install exporter.
+add_custom_command(
+  OUTPUT ${JavaModExportImport_BINARY_DIR}/InstallExportProject
+  COMMAND ${CMAKE_CTEST_COMMAND} ${NESTED_CONFIG_TYPE}
+    --build-and-test
+    ${JavaModExportImport_SOURCE_DIR}/InstallExport
+    ${JavaModExportImport_BINARY_DIR}/InstallExport
+    --build-noclean
+    --build-project InstallExport
+    --build-target install
+    --build-generator ${CMAKE_GENERATOR}
+    --build-generator-platform "${CMAKE_GENERATOR_PLATFORM}"
+    --build-generator-toolset "${CMAKE_GENERATOR_TOOLSET}"
+    --build-options -C${JavaModExportImport_BINARY_DIR}/InitialCache.cmake
+  VERBATIM
+  )
+add_custom_target(InstallExportTarget ALL DEPENDS ${JavaModExportImport_BINARY_DIR}/InstallExportProject)
+add_dependencies(InstallExportTarget CleanupTarget)
+set_property(
+  SOURCE ${JavaModExportImport_BINARY_DIR}/InstallExportProject
+  PROPERTY SYMBOLIC 1
+  )
+
+# Build and install the importer.
+add_custom_command(
+  OUTPUT ${JavaModExportImport_BINARY_DIR}/ImportProject
+  COMMAND ${CMAKE_CTEST_COMMAND} ${NESTED_CONFIG_TYPE}
+    --build-and-test
+    ${JavaModExportImport_SOURCE_DIR}/Import
+    ${JavaModExportImport_BINARY_DIR}/Import
+    --build-noclean
+    --build-project Import
+    --build-generator ${CMAKE_GENERATOR}
+    --build-generator-platform "${CMAKE_GENERATOR_PLATFORM}"
+    --build-generator-toolset "${CMAKE_GENERATOR_TOOLSET}"
+    --build-options
+      -C${JavaModExportImport_BINARY_DIR}/InitialCache.cmake
+      -DJavaBuildExportTest_DIR:PATH=${JavaModExportImport_BINARY_DIR}/BuildExport
+      -DJavaInstallExportTest_DIR:PATH=${JavaModExportImport_BINARY_DIR}/Root/share/cmake
+  VERBATIM
+  )
+add_custom_target(ImportTarget ALL DEPENDS ${JavaModExportImport_BINARY_DIR}/ImportProject)
+add_dependencies(ImportTarget BuildExportTarget InstallExportTarget)
+set_property(
+  SOURCE ${JavaModExportImport_BINARY_DIR}/ImportProject
+  PROPERTY SYMBOLIC 1
+  )
+
+add_executable(JavaModExportImport main.c)
+add_dependencies(JavaModExportImport ImportTarget)
diff --git a/Tests/JavaModExportImport/Import/CMakeLists.txt b/Tests/JavaModExportImport/Import/CMakeLists.txt
new file mode 100644
index 0000000..f8f773a
--- /dev/null
+++ b/Tests/JavaModExportImport/Import/CMakeLists.txt
@@ -0,0 +1,14 @@
+project(import Java)
+
+cmake_minimum_required(VERSION 3.10)
+set(CMAKE_VERBOSE_MAKEFILE 1)
+
+find_package(Java COMPONENTS Development)
+include(UseJava)
+
+find_package(JavaBuildExportTest REQUIRED)
+find_package(JavaInstallExportTest REQUIRED)
+
+add_jar(${PROJECT_NAME}
+  SOURCES Import.java module-info.java
+  INCLUDE_MODULES foo::foo bar::bar)
diff --git a/Tests/JavaModExportImport/Import/Import.java b/Tests/JavaModExportImport/Import/Import.java
new file mode 100644
index 0000000..46b1e9a
--- /dev/null
+++ b/Tests/JavaModExportImport/Import/Import.java
@@ -0,0 +1,13 @@
+import org.foo.Foo;
+import com.bar.Bar;
+
+class Import
+{
+  public static void main(String args[])
+  {
+    Foo foo = new Foo();
+    Bar bar = new Bar();
+    foo.printName();
+    bar.printName();
+  }
+}
diff --git a/Tests/JavaModExportImport/Import/module-info.java b/Tests/JavaModExportImport/Import/module-info.java
new file mode 100644
index 0000000..9d719cd
--- /dev/null
+++ b/Tests/JavaModExportImport/Import/module-info.java
@@ -0,0 +1,4 @@
+module client {
+    requires mod_foo;
+    requires mod_bar;
+}
diff --git a/Tests/JavaModExportImport/InitialCache.cmake.in b/Tests/JavaModExportImport/InitialCache.cmake.in
new file mode 100644
index 0000000..cc7871e
--- /dev/null
+++ b/Tests/JavaModExportImport/InitialCache.cmake.in
@@ -0,0 +1,5 @@
+set(CMAKE_MAKE_PROGRAM "@CMake_TEST_NESTED_MAKE_PROGRAM@" CACHE FILEPATH "Make Program")
+set(Java_JAVA_EXECUTABLE "@Java_JAVA_EXECUTABLE@" CACHE STRING "Java Interpreter")
+set(Java_JAVAC_EXECUTABLE "@Java_JAVAC_EXECUTABLE@" CACHE STRING "Java Compiler")
+set(Java_JAR_EXECUTABLE "@Java_JAR_EXECUTABLE@" CACHE STRING "Java Archive Tool")
+set(CMAKE_INSTALL_PREFIX "@JavaModExportImport_BINARY_DIR@/Root" CACHE STRING "Installation Prefix")
diff --git a/Tests/JavaModExportImport/InstallExport/Bar.java b/Tests/JavaModExportImport/InstallExport/Bar.java
new file mode 100644
index 0000000..dfa941c
--- /dev/null
+++ b/Tests/JavaModExportImport/InstallExport/Bar.java
@@ -0,0 +1,13 @@
+package com.bar;
+
+public class Bar
+{
+  public Bar()
+  {
+  }
+
+  public void printName()
+  {
+    System.out.println("Bar");
+  }
+}
diff --git a/Tests/JavaModExportImport/InstallExport/CMakeLists.txt b/Tests/JavaModExportImport/InstallExport/CMakeLists.txt
new file mode 100644
index 0000000..5997bdc
--- /dev/null
+++ b/Tests/JavaModExportImport/InstallExport/CMakeLists.txt
@@ -0,0 +1,15 @@
+project(bar Java)
+
+cmake_minimum_required(VERSION 3.10)
+set(CMAKE_VERBOSE_MAKEFILE 1)
+
+find_package(Java COMPONENTS Development)
+include(UseJava)
+
+add_jar(${PROJECT_NAME} Bar.java module-info.java)
+install_jar(${PROJECT_NAME} DESTINATION share/java)
+install_jar_exports(
+  TARGETS ${PROJECT_NAME}
+  NAMESPACE bar::
+  FILE JavaInstallExportTestConfig.cmake
+  DESTINATION share/cmake)
diff --git a/Tests/JavaModExportImport/InstallExport/module-info.java b/Tests/JavaModExportImport/InstallExport/module-info.java
new file mode 100644
index 0000000..7c8b62d
--- /dev/null
+++ b/Tests/JavaModExportImport/InstallExport/module-info.java
@@ -0,0 +1,3 @@
+module mod_bar {
+    exports com.bar;
+}
diff --git a/Tests/JavaModExportImport/main.c b/Tests/JavaModExportImport/main.c
new file mode 100644
index 0000000..8488f4e
--- /dev/null
+++ b/Tests/JavaModExportImport/main.c
@@ -0,0 +1,4 @@
+int main(void)
+{
+  return 0;
+}
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index 8652a5c..4c2473d 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -523,6 +523,7 @@
 add_RunCMake_test(GenEx-GENEX_EVAL)
 add_RunCMake_test(GenEx-TARGET_PROPERTY)
 add_RunCMake_test(GenEx-TARGET_RUNTIME_DLLS)
+add_RunCMake_test(GenEx-STRING)
 add_RunCMake_test(GenEx-PATH)
 add_RunCMake_test(GenEx-PATH_EQUAL)
 add_RunCMake_test(GenEx-LIST)
@@ -719,6 +720,7 @@
     list(APPEND file-DOWNLOAD_ARGS -D${var}=${${var}})
   endif()
 endforeach()
+add_RunCMake_test(file-CREATE_LINK)
 add_RunCMake_test(file-DOWNLOAD)
 add_RunCMake_test(file-MAKE_DIRECTORY)
 add_RunCMake_test(file-RPATH
@@ -832,11 +834,14 @@
 
 # Add C++ Module tests.
 add_RunCMake_test(CXXModules
+  -DCMake_TEST_CXX_STDLIB_MODULES_JSON=${CMake_TEST_CXX_STDLIB_MODULES_JSON}
+)
+add_RunCMake_test(CXXModulesCompile
   -DCMake_TEST_MODULE_COMPILATION=${CMake_TEST_MODULE_COMPILATION}
   -DCMake_TEST_MODULE_COMPILATION_RULES=${CMake_TEST_MODULE_COMPILATION_RULES}
   -DCMake_TEST_CXX_STDLIB_MODULES_JSON=${CMake_TEST_CXX_STDLIB_MODULES_JSON}
 )
-set_property(TEST RunCMake.CXXModules APPEND
+set_property(TEST RunCMake.CXXModules RunCMake.CXXModulesCompile APPEND
   PROPERTY LABELS "CXXModules")
 
 # ctresalloc links against CMakeLib and CTestLib, which means it can't be built
@@ -1334,6 +1339,7 @@
 add_RunCMake_test(AndroidMK)
 add_RunCMake_test(ExportPackageInfo)
 add_RunCMake_test(InstallPackageInfo)
+add_RunCMake_test(InstallExportsAsPackageInfo)
 
 if(CMake_TEST_ANDROID_NDK OR CMake_TEST_ANDROID_STANDALONE_TOOLCHAIN)
   if(NOT "${CMAKE_GENERATOR}" MATCHES "Make|Ninja|Visual Studio 1[456]")
@@ -1368,6 +1374,7 @@
 add_RunCMake_test(PrecompileHeaders -DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID}
   -DCMAKE_C_SIMULATE_ID=${CMAKE_C_SIMULATE_ID}
   -DCMAKE_C_COMPILER_VERSION=${CMAKE_C_COMPILER_VERSION})
+add_RunCMake_test(PrecompileHeaders-Reuse -DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID})
 
 # This test can take a long time due to the number of test cases.
 # Provide an option to customize it.
diff --git a/Tests/RunCMake/PrecompileHeaders/PchReuseFromCycle-result.txt b/Tests/RunCMake/CMakePresetsBuild/BuildDirectoryOverride-build-override-result.txt
similarity index 100%
copy from Tests/RunCMake/PrecompileHeaders/PchReuseFromCycle-result.txt
copy to Tests/RunCMake/CMakePresetsBuild/BuildDirectoryOverride-build-override-result.txt
diff --git a/Tests/RunCMake/CMakePresetsBuild/BuildDirectoryOverride-build-override-stderr.txt b/Tests/RunCMake/CMakePresetsBuild/BuildDirectoryOverride-build-override-stderr.txt
new file mode 100644
index 0000000..fbd9416
--- /dev/null
+++ b/Tests/RunCMake/CMakePresetsBuild/BuildDirectoryOverride-build-override-stderr.txt
@@ -0,0 +1,2 @@
+^Error: [^
+]*/Tests/RunCMake/build2 is not a directory$
diff --git a/Tests/RunCMake/CMakePresetsBuild/BuildDirectoryOverride.json.in b/Tests/RunCMake/CMakePresetsBuild/BuildDirectoryOverride.json.in
new file mode 100644
index 0000000..66e8e42
--- /dev/null
+++ b/Tests/RunCMake/CMakePresetsBuild/BuildDirectoryOverride.json.in
@@ -0,0 +1,24 @@
+{
+  "version": 2,
+  "cmakeMinimumRequired": {
+    "major": 3,
+    "minor": 20,
+    "patch": 0
+  },
+  "configurePresets": [
+    {
+      "name": "default",
+      "binaryDir": "${sourceDir}/build",
+      "generator": "@RunCMake_GENERATOR@",
+      "cacheVariables": {
+        "CMAKE_BUILD_TYPE": "Debug"
+      }
+    }
+  ],
+  "buildPresets": [
+    {
+      "name": "override",
+      "configurePreset": "default"
+    }
+  ]
+}
diff --git a/Tests/RunCMake/CMakePresetsBuild/RunCMakeTest.cmake b/Tests/RunCMake/CMakePresetsBuild/RunCMakeTest.cmake
index 1ededc1..85d3baf 100644
--- a/Tests/RunCMake/CMakePresetsBuild/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CMakePresetsBuild/RunCMakeTest.cmake
@@ -5,7 +5,7 @@
   set(RunCMake_GENERATOR "${CMAKE_MATCH_1}")
 endif()
 
-function(run_cmake_build_presets name CMakePresetsBuild_CONFIGURE_PRESETS CMakePresetsBuild_BUILD_PRESETS)
+function(run_cmake_build_presets name CMakePresetsBuild_CONFIGURE_PRESETS CMakePresetsBuild_BUILD_PRESETS CMakePresetsBuild_BUILD_DIR_OVERRIDE)
   set(RunCMake_TEST_SOURCE_DIR "${RunCMake_BINARY_DIR}/${name}")
   set(RunCMake_TEST_BINARY_DIR "${RunCMake_TEST_SOURCE_DIR}/build")
   set(RunCMake_TEST_COMMAND_WORKING_DIRECTORY "${RunCMake_TEST_SOURCE_DIR}")
@@ -50,11 +50,11 @@
 
     if(eq)
       run_cmake_command(${name}-build-${BUILD_PRESET}
-        ${CMAKE_COMMAND} "--build" "--preset=${BUILD_PRESET}" ${ARGN})
+        ${CMAKE_COMMAND} "--build" ${CMakePresetsBuild_BUILD_DIR_OVERRIDE} "--preset=${BUILD_PRESET}" ${ARGN})
       set(eq 0)
     else()
       run_cmake_command(${name}-build-${BUILD_PRESET}
-        ${CMAKE_COMMAND} "--build" "--preset" "${BUILD_PRESET}" ${ARGN})
+        ${CMAKE_COMMAND} "--build" ${CMakePresetsBuild_BUILD_DIR_OVERRIDE} "--preset" "${BUILD_PRESET}" ${ARGN})
       set(eq 1)
     endif()
   endforeach()
@@ -70,19 +70,20 @@
   set(Good_json_jobs [["jobs": 0,]])
 endif()
 
-run_cmake_build_presets(Good "default;other" "build-other;withEnvironment;noEnvironment;macros;vendorObject;singleTarget;initResolve")
-run_cmake_build_presets(InvalidConfigurePreset "default" "badConfigurePreset")
-run_cmake_build_presets(Condition "default" "enabled;disabled")
+run_cmake_build_presets(Good "default;other" "build-other;withEnvironment;noEnvironment;macros;vendorObject;singleTarget;initResolve" "")
+run_cmake_build_presets(InvalidConfigurePreset "default" "badConfigurePreset" "")
+run_cmake_build_presets(Condition "default" "enabled;disabled" "")
 
 set(CMakePresetsBuild_BUILD_ONLY 1)
-run_cmake_build_presets(ListPresets "x" "x" "--list-presets")
-run_cmake_build_presets(NoConfigurePreset "x" "noConfigurePreset")
-run_cmake_build_presets(Invalid "x" "hidden;vendorMacro")
+run_cmake_build_presets(ListPresets "x" "x" "--list-presets" "")
+run_cmake_build_presets(NoConfigurePreset "x" "noConfigurePreset" "")
+run_cmake_build_presets(Invalid "x" "hidden;vendorMacro" "")
+run_cmake_build_presets(BuildDirectoryOverride "" "override" "${RunCMake_BINARY_DIR}/../build2")
 
 set(CMakePresets_SCHEMA_EXPECTED_RESULT 1)
-run_cmake_build_presets(PresetsUnsupported "x" "x")
-run_cmake_build_presets(ConditionFuture "x" "conditionFuture")
+run_cmake_build_presets(PresetsUnsupported "x" "x" "")
+run_cmake_build_presets(ConditionFuture "x" "conditionFuture" "")
 set(CMakePresets_SCHEMA_EXPECTED_RESULT 0)
 
-run_cmake_build_presets(ConfigurePresetUnreachable "x" "x")
+run_cmake_build_presets(ConfigurePresetUnreachable "x" "x" "")
 set(CMakePresetsBuild_BUILD_ONLY 0)
diff --git a/Tests/RunCMake/CPackConfig/CMP0206-NEW-check.cmake b/Tests/RunCMake/CPackConfig/CMP0206-NEW-check.cmake
new file mode 100644
index 0000000..5352a14
--- /dev/null
+++ b/Tests/RunCMake/CPackConfig/CMP0206-NEW-check.cmake
@@ -0,0 +1,3 @@
+include(${RunCMake_SOURCE_DIR}/check.cmake)
+test_variable(CPACK_ARCHIVE_UID "")
+test_variable(CPACK_ARCHIVE_GID "")
diff --git a/Tests/RunCMake/CPackConfig/CMP0206-NEW.cmake b/Tests/RunCMake/CPackConfig/CMP0206-NEW.cmake
new file mode 100644
index 0000000..8b143e5
--- /dev/null
+++ b/Tests/RunCMake/CPackConfig/CMP0206-NEW.cmake
@@ -0,0 +1 @@
+cmake_policy(SET CMP0206 NEW)
diff --git a/Tests/RunCMake/CPackConfig/CMP0206-OLD-check.cmake b/Tests/RunCMake/CPackConfig/CMP0206-OLD-check.cmake
new file mode 100644
index 0000000..86f4e9c
--- /dev/null
+++ b/Tests/RunCMake/CPackConfig/CMP0206-OLD-check.cmake
@@ -0,0 +1,3 @@
+include(${RunCMake_SOURCE_DIR}/check.cmake)
+test_variable(CPACK_ARCHIVE_UID "-1")
+test_variable(CPACK_ARCHIVE_GID "-1")
diff --git a/Tests/RunCMake/CPackConfig/CMP0206-OLD.cmake b/Tests/RunCMake/CPackConfig/CMP0206-OLD.cmake
new file mode 100644
index 0000000..aa8597a
--- /dev/null
+++ b/Tests/RunCMake/CPackConfig/CMP0206-OLD.cmake
@@ -0,0 +1,2 @@
+set(CMAKE_POLICY_WARNING_CMP0206 1)
+cmake_policy(SET CMP0206 OLD)
diff --git a/Tests/RunCMake/CPackConfig/CMP0206-WARN-check.cmake b/Tests/RunCMake/CPackConfig/CMP0206-WARN-check.cmake
new file mode 100644
index 0000000..86f4e9c
--- /dev/null
+++ b/Tests/RunCMake/CPackConfig/CMP0206-WARN-check.cmake
@@ -0,0 +1,3 @@
+include(${RunCMake_SOURCE_DIR}/check.cmake)
+test_variable(CPACK_ARCHIVE_UID "-1")
+test_variable(CPACK_ARCHIVE_GID "-1")
diff --git a/Tests/RunCMake/CPackConfig/CMP0206-WARN-stderr.txt b/Tests/RunCMake/CPackConfig/CMP0206-WARN-stderr.txt
new file mode 100644
index 0000000..ce6f443
--- /dev/null
+++ b/Tests/RunCMake/CPackConfig/CMP0206-WARN-stderr.txt
@@ -0,0 +1,10 @@
+^CMake Warning \(dev\) at [^
+]*/Modules/CPack\.cmake:[0-9]+ \(message\):
+  Policy CMP0206 is not set: The CPack Archive Generator defaults to UID 0
+  and GID 0\.  Run "cmake --help-policy CMP0206" for policy details\.  Use the
+  cmake_policy command to set the policy and suppress this warning\.
+
+  For compatibility, CMake will set archive UID/GID to -1/-1\.
+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/CPackConfig/CMP0206-WARN.cmake b/Tests/RunCMake/CPackConfig/CMP0206-WARN.cmake
new file mode 100644
index 0000000..75ee7f3
--- /dev/null
+++ b/Tests/RunCMake/CPackConfig/CMP0206-WARN.cmake
@@ -0,0 +1 @@
+set(CMAKE_POLICY_WARNING_CMP0206 1)
diff --git a/Tests/RunCMake/CPackConfig/RunCMakeTest.cmake b/Tests/RunCMake/CPackConfig/RunCMakeTest.cmake
index 4d61073..70ed68a 100644
--- a/Tests/RunCMake/CPackConfig/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CPackConfig/RunCMakeTest.cmake
@@ -8,6 +8,9 @@
 run_cmake(CMP0172-NEW)
 run_cmake(CMP0172-OLD)
 run_cmake(CMP0172-WARN)
+run_cmake(CMP0206-NEW)
+run_cmake(CMP0206-OLD)
+run_cmake(CMP0206-WARN)
 run_cmake(Simple)
 run_cmake(Default)
 run_cmake(Special)
diff --git a/Tests/RunCMake/CXXModules/Inspect.cmake b/Tests/RunCMake/CXXModules/Inspect.cmake
index 2913c87..702e349 100644
--- a/Tests/RunCMake/CXXModules/Inspect.cmake
+++ b/Tests/RunCMake/CXXModules/Inspect.cmake
@@ -37,6 +37,7 @@
 set(CMAKE_MAKE_PROGRAM \"${CMAKE_MAKE_PROGRAM}\")
 set(forced_cxx_standard \"${forced_cxx_standard}\")
 set(have_cxx23_import_std \"${have_cxx23_import_std}\")
+set(have_cxx26_import_std \"${have_cxx26_import_std}\")
 set(CMAKE_CXX_COMPILER_VERSION \"${CMAKE_CXX_COMPILER_VERSION}\")
 set(CMAKE_CXX_OUTPUT_EXTENSION \"${CMAKE_CXX_OUTPUT_EXTENSION}\")
 set(CXXModules_default_build_type \"${CMAKE_BUILD_TYPE}\")
diff --git a/Tests/RunCMake/CXXModules/InstallBMINoGenericArgs-check.cmake b/Tests/RunCMake/CXXModules/InstallBMINoGenericArgs-check.cmake
deleted file mode 100644
index 412e260..0000000
--- a/Tests/RunCMake/CXXModules/InstallBMINoGenericArgs-check.cmake
+++ /dev/null
@@ -1,8 +0,0 @@
-file(READ "${RunCMake_TEST_BINARY_DIR}/cmake_install.cmake" install_script)
-
-if (install_script MATCHES [[include\("[^)]*/CMakeFiles/install-bmi-generic-args\.dir/install-cxx-module-bmi-[^.]*\.cmake" OPTIONAL\)]])
-  list(APPEND RunCMake_TEST_FAILED
-    "Found BMI install script inclusion")
-endif ()
-
-string(REPLACE ";" "; " RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}")
diff --git a/Tests/RunCMake/CXXModules/NoCXX23TargetRequired-stderr.txt b/Tests/RunCMake/CXXModules/NoCXX23TargetRequired-stderr.txt
index fd09dfa..48a8b94 100644
--- a/Tests/RunCMake/CXXModules/NoCXX23TargetRequired-stderr.txt
+++ b/Tests/RunCMake/CXXModules/NoCXX23TargetRequired-stderr.txt
@@ -1,9 +1,8 @@
 CMake Error in CMakeLists\.txt:
-  The "CXX_MODULE_STD" property on the target "nocxx23target" requires that
-  the "__CMAKE::CXX23" target exist, but it was not provided by the
-  toolchain\.  Reason:
+  The "CXX_MODULE_STD" property on target "nocxx23target" requires toolchain
+  support, but it was not provided.  Reason:
 
-    (Toolchain does not support discovering `import std` support|Experimental `import std` support not enabled when detecting toolchain; it must be set before `CXX` is enabled \(usually a `project\(\)` call\)|Unsupported generator: [^\n]*)
+    (Toolchain does not support discovering module metadata|Experimental `import std` support not enabled when detecting toolchain; it must be set before `CXX` is enabled \(usually a `project\(\)` call\)|Unsupported generator: [^\n]*)
 
 
 CMake Generate step failed\.  Build files cannot be regenerated correctly\.
diff --git a/Tests/RunCMake/CXXModules/NoCXX26TargetRequired-stderr.txt b/Tests/RunCMake/CXXModules/NoCXX26TargetRequired-stderr.txt
index 836b39b..b45b04e 100644
--- a/Tests/RunCMake/CXXModules/NoCXX26TargetRequired-stderr.txt
+++ b/Tests/RunCMake/CXXModules/NoCXX26TargetRequired-stderr.txt
@@ -1,9 +1,8 @@
 CMake Error in CMakeLists\.txt:
-  The "CXX_MODULE_STD" property on the target "nocxx26target" requires that
-  the "__CMAKE::CXX26" target exist, but it was not provided by the
-  toolchain\.  Reason:
+  The "CXX_MODULE_STD" property on target "nocxx26target" requires toolchain
+  support, but it was not provided.  Reason:
 
-    (Toolchain does not support discovering `import std` support|Experimental `import std` support not enabled when detecting toolchain; it must be set before `CXX` is enabled \(usually a `project\(\)` call\)|Unsupported generator: [^\n]*)
+    (Toolchain does not support discovering module metadata|Experimental `import std` support not enabled when detecting toolchain; it must be set before `CXX` is enabled \(usually a `project\(\)` call\)|Unsupported generator: [^\n]*)
 
 
 CMake Generate step failed\.  Build files cannot be regenerated correctly\.
diff --git a/Tests/RunCMake/CXXModules/RunCMakeTest.cmake b/Tests/RunCMake/CXXModules/RunCMakeTest.cmake
index 9a8e698..31c5e3e 100644
--- a/Tests/RunCMake/CXXModules/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CXXModules/RunCMakeTest.cmake
@@ -135,330 +135,3 @@
   message(FATAL_ERROR
     "Please add 'DependInfo' tests for the '${RunCMake_GENERATOR}' generator.")
 endif ()
-
-# Actual compilation tests.
-if (NOT CMake_TEST_MODULE_COMPILATION)
-  return ()
-endif ()
-
-function (run_cxx_module_test directory)
-  set(test_name "${directory}")
-  if (NOT ARGN STREQUAL "")
-    list(POP_FRONT ARGN test_name)
-  endif ()
-
-  set(RunCMake_TEST_SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}/examples/${directory}")
-  set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/examples/${test_name}-build")
-
-  if (RunCMake_GENERATOR_IS_MULTI_CONFIG)
-    set(RunCMake_TEST_OPTIONS -DCMAKE_CONFIGURATION_TYPES=Debug)
-  else ()
-    set(RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Debug)
-  endif ()
-  if (directory MATCHES "import-std")
-    list(APPEND RunCMake_TEST_OPTIONS
-      ${stdlib_custom_json})
-  endif ()
-
-  if (RunCMake_CXXModules_INSTALL)
-    set(prefix "${RunCMake_BINARY_DIR}/examples/${test_name}-install")
-    file(REMOVE_RECURSE "${prefix}")
-    list(APPEND RunCMake_TEST_OPTIONS
-      "-DCMAKE_INSTALL_PREFIX=${prefix}")
-  endif ()
-
-  list(APPEND RunCMake_TEST_OPTIONS
-    "-DCMake_TEST_MODULE_COMPILATION_RULES=${CMake_TEST_MODULE_COMPILATION_RULES}"
-    ${ARGN})
-  run_cmake("examples/${test_name}")
-  set(RunCMake_TEST_NO_CLEAN 1)
-  if (RunCMake_CXXModules_TARGET)
-    run_cmake_command("examples/${test_name}-build" "${CMAKE_COMMAND}" --build . --config Debug --target "${RunCMake_CXXModules_TARGET}")
-  else ()
-    run_cmake_command("examples/${test_name}-build" "${CMAKE_COMMAND}" --build . --config Debug)
-    foreach (RunCMake_CXXModules_TARGET IN LISTS RunCMake_CXXModules_TARGETS)
-      set(RunCMake_CXXModules_CONFIG "Debug")
-      set(RunCMake_CXXModules_NAME_SUFFIX "")
-      if (RunCMake_CXXModules_TARGET MATCHES "(.*)@(.*)")
-        set(RunCMake_CXXModules_TARGET "${CMAKE_MATCH_1}")
-        set(RunCMake_CXXModules_CONFIG "${CMAKE_MATCH_2}")
-        set(RunCMake_CXXModules_NAME_SUFFIX "-${RunCMake_CXXModules_CONFIG}")
-      endif ()
-      run_cmake_command("examples/${test_name}-target-${RunCMake_CXXModules_TARGET}${RunCMake_CXXModules_NAME_SUFFIX}" "${CMAKE_COMMAND}" --build . --target "${RunCMake_CXXModules_TARGET}" --config "${RunCMake_CXXModules_CONFIG}")
-    endforeach ()
-  endif ()
-  if (RunCMake_CXXModules_INSTALL)
-    run_cmake_command("examples/${test_name}-install" "${CMAKE_COMMAND}" --build . --target install --config Debug)
-  endif ()
-  if (NOT RunCMake_CXXModules_NO_TEST)
-    run_cmake_command("examples/${test_name}-test" "${CMAKE_CTEST_COMMAND}" -C Debug --output-on-failure)
-  endif ()
-  if (RunCMake_CXXModules_REBUILD)
-    execute_process(COMMAND ${CMAKE_COMMAND} -E sleep 1.125) # handle 1s resolution
-    include("${RunCMake_TEST_SOURCE_DIR}/pre-rebuild.cmake")
-    execute_process(COMMAND ${CMAKE_COMMAND} -E sleep 1.125) # handle 1s resolution
-    run_cmake_command("examples/${test_name}-rebuild" "${CMAKE_COMMAND}" --build . --config Debug)
-  endif ()
-endfunction ()
-
-function (run_cxx_module_test_target directory target)
-  set(RunCMake_CXXModules_TARGET "${target}")
-  set(RunCMake_CXXModules_NO_TEST 1)
-  run_cxx_module_test("${directory}" ${ARGN})
-endfunction ()
-
-function (run_cxx_module_test_rebuild directory)
-  set(RunCMake_CXXModules_INSTALL 0)
-  set(RunCMake_CXXModules_NO_TEST 1)
-  set(RunCMake_CXXModules_REBUILD 1)
-  run_cxx_module_test("${directory}" ${ARGN})
-endfunction ()
-
-# Module compilation features:
-# Compiler-based:
-# - `named`: basic support for named modules is available
-# - `shared`: shared libraries are supported
-# - `partitions`: module partitions are supported
-# - `internal_partitions`: internal module partitions are supported
-# - `bmionly`: the compiler supports BMI-only builds
-# - `import_std23`: the compiler supports `import std` for C++23
-#
-# Generator-based:
-# - `compile_commands`: the generator supports `compile_commands.json`
-# - `collation`: the generator supports module collation features
-# - `export_bmi`: the generator supports exporting BMIs
-# - `ninja`: a `ninja` binary is available to perform `Ninja`-only testing
-#   (assumed if the generator matches `Ninja`).
-string(REPLACE "," ";" CMake_TEST_MODULE_COMPILATION "${CMake_TEST_MODULE_COMPILATION}")
-if (RunCMake_GENERATOR MATCHES "Ninja")
-  list(APPEND CMake_TEST_MODULE_COMPILATION
-    "ninja")
-endif ()
-
-if (RunCMake_GENERATOR MATCHES "Ninja")
-  if (RunCMake_GENERATOR_IS_MULTI_CONFIG)
-    set(ninja_cmp0154_target "CMakeFiles/ninja_cmp0154.dir/Debug/unrelated.cxx${CMAKE_CXX_OUTPUT_EXTENSION}")
-  else ()
-    set(ninja_cmp0154_target "CMakeFiles/ninja_cmp0154.dir/unrelated.cxx${CMAKE_CXX_OUTPUT_EXTENSION}")
-  endif ()
-  run_cxx_module_test_target(ninja-cmp0154 "${ninja_cmp0154_target}")
-endif ()
-
-run_cxx_module_test(scan-with-pch)
-
-# Tests which use named modules.
-if ("named" IN_LIST CMake_TEST_MODULE_COMPILATION)
-  run_cxx_module_test(simple)
-  run_cxx_module_test(file-sets-with-dot)
-  run_cxx_module_test(vs-without-flags)
-  run_cxx_module_test(library library-static -DBUILD_SHARED_LIBS=OFF)
-  run_cxx_module_test(unity-build)
-  run_cxx_module_test(object-library)
-  run_cxx_module_test(generated)
-  run_cxx_module_test(deep-chain)
-  run_cxx_module_test(non-trivial-collation-order)
-  run_cxx_module_test(non-trivial-collation-order-randomized)
-  run_cxx_module_test(duplicate)
-  set(RunCMake_CXXModules_NO_TEST 1)
-  run_cxx_module_test(import-from-object)
-  run_cxx_module_test(circular)
-  run_cxx_module_test(try-compile)
-  run_cxx_module_test(try-run)
-  unset(RunCMake_CXXModules_NO_TEST)
-  run_cxx_module_test(same-src-name)
-  run_cxx_module_test(scan_properties)
-  run_cxx_module_test(target-objects)
-
-  if ("cxx_std_23" IN_LIST CMAKE_CXX_COMPILE_FEATURES AND
-      "import_std23" IN_LIST CMake_TEST_MODULE_COMPILATION)
-    run_cxx_module_test(import-std)
-    set(RunCMake_CXXModules_NO_TEST 1)
-    run_cxx_module_test(import-std-no-std-property)
-    unset(RunCMake_CXXModules_NO_TEST)
-    run_cxx_module_test(import-std-export-no-std-build)
-    set(RunCMake_CXXModules_INSTALL 1)
-    run_cxx_module_test(import-std-export-no-std-install)
-    unset(RunCMake_CXXModules_INSTALL)
-
-    if ("collation" IN_LIST CMake_TEST_MODULE_COMPILATION)
-      run_cxx_module_test(import-std-not-in-export-build)
-      run_cxx_module_test(import-std-transitive import-std-transitive-not-in-export-build "-DCMAKE_PREFIX_PATH=${RunCMake_BINARY_DIR}/examples/import-std-not-in-export-build-build")
-
-      set(RunCMake_CXXModules_INSTALL 1)
-      run_cxx_module_test(import-std-not-in-export-install)
-      unset(RunCMake_CXXModules_INSTALL)
-      run_cxx_module_test(import-std-transitive import-std-transitive-not-in-export-install "-DCMAKE_PREFIX_PATH=${RunCMake_BINARY_DIR}/examples/import-std-not-in-export-install-install")
-
-      run_cxx_module_test(import-std-transitive import-std-transitive-export-no-std-build "-DCMAKE_PREFIX_PATH=${RunCMake_BINARY_DIR}/examples/import-std-export-no-std-build-build" -DEXPORT_NO_STD=1)
-      run_cxx_module_test(import-std-transitive import-std-transitive-export-no-std-install "-DCMAKE_PREFIX_PATH=${RunCMake_BINARY_DIR}/examples/import-std-export-no-std-install-install" -DEXPORT_NO_STD=1)
-    endif ()
-  endif ()
-endif ()
-
-# Tests which require compile commands support.
-if ("compile_commands" IN_LIST CMake_TEST_MODULE_COMPILATION)
-  run_cxx_module_test(export-compile-commands)
-endif ()
-
-macro (setup_export_build_database_targets)
-  set(RunCMake_CXXModules_TARGETS
-    cmake_build_database-CXX
-    cmake_build_database)
-
-  if (RunCMake_GENERATOR_IS_MULTI_CONFIG)
-    list(INSERT RunCMake_CXXModules_TARGETS 0
-      cmake_build_database-CXX-Debug
-      cmake_build_database-Debug
-      # Other config targets.
-      cmake_build_database-CXX-Release@Release
-      cmake_build_database-Release@Release)
-  endif ()
-endmacro ()
-
-# Tests which require build database support.
-if ("build_database" IN_LIST CMake_TEST_MODULE_COMPILATION)
-  setup_export_build_database_targets()
-  set(RunCMake_CXXModules_NO_TEST 1)
-
-  run_cxx_module_test(export-build-database)
-
-  unset(RunCMake_CXXModules_NO_TEST)
-  unset(RunCMake_CXXModules_TARGETS)
-endif ()
-
-# Tests which require collation work.
-if ("collation" IN_LIST CMake_TEST_MODULE_COMPILATION)
-  run_cxx_module_test(duplicate-sources)
-  run_cxx_module_test(public-req-private)
-  set(RunCMake_CXXModules_NO_TEST 1)
-  run_cxx_module_test(req-private-other-target)
-  unset(RunCMake_CXXModules_NO_TEST)
-  run_cxx_module_test_rebuild(depchain-modmap)
-  run_cxx_module_test_rebuild(depchain-modules-json-file)
-  if (RunCMake_GENERATOR MATCHES "Ninja")
-    run_cxx_module_test_rebuild(depchain-collation-restat)
-  endif ()
-endif ()
-
-# Tests which use named modules in shared libraries.
-if ("shared" IN_LIST CMake_TEST_MODULE_COMPILATION)
-  run_cxx_module_test(library library-shared -DBUILD_SHARED_LIBS=ON)
-endif ()
-
-# Tests which use partitions.
-if ("partitions" IN_LIST CMake_TEST_MODULE_COMPILATION)
-  run_cxx_module_test(partitions)
-endif ()
-
-# Tests which use internal partitions.
-if ("internal_partitions" IN_LIST CMake_TEST_MODULE_COMPILATION)
-  run_cxx_module_test(internal-partitions)
-endif ()
-
-function (run_cxx_module_import_test type name)
-  set(RunCMake_CXXModules_INSTALL 0)
-
-  if ("EXPORT_BUILD_DATABASE" IN_LIST ARGN)
-    list(REMOVE_ITEM ARGN EXPORT_BUILD_DATABASE)
-    list(APPEND ARGN -DCMAKE_EXPORT_BUILD_DATABASE=1)
-  endif ()
-
-  run_cxx_module_test(import-modules "import-modules-${name}" "-DCMAKE_PREFIX_PATH=${RunCMake_BINARY_DIR}/examples/${name}-${type}" ${ARGN})
-endfunction ()
-
-# Tests which install BMIs
-if ("export_bmi" IN_LIST CMake_TEST_MODULE_COMPILATION)
-  run_cxx_module_test(export-interface-no-properties-build)
-  run_cxx_module_test(export-interface-build)
-  run_cxx_module_test(export-include-directories-build)
-  run_cxx_module_test(export-include-directories-old-cmake-build)
-  run_cxx_module_test(export-usage-build)
-  run_cxx_module_test(export-bmi-and-interface-build)
-  run_cxx_module_test(export-command-sepdir-build)
-  run_cxx_module_test(export-transitive-targets-build)
-  run_cxx_module_test(export-transitive-modules1-build)
-  run_cxx_module_test(export-transitive-modules-build export-transitive-modules-build "-DCMAKE_PREFIX_PATH=${RunCMake_BINARY_DIR}/examples/export-transitive-modules1-build-build" )
-  run_cxx_module_test(export-with-headers-build)
-
-  if ("collation" IN_LIST CMake_TEST_MODULE_COMPILATION AND
-      "bmionly" IN_LIST CMake_TEST_MODULE_COMPILATION)
-    run_cxx_module_import_test(build export-interface-build)
-    run_cxx_module_import_test(build export-interface-no-properties-build -DNO_PROPERTIES=1)
-    run_cxx_module_import_test(build export-include-directories-build -DINCLUDE_PROPERTIES=1)
-    run_cxx_module_import_test(build export-bmi-and-interface-build -DWITH_BMIS=1)
-    run_cxx_module_import_test(build export-command-sepdir-build -DEXPORT_COMMAND_SEPDIR=1)
-    run_cxx_module_import_test(build export-transitive-targets-build -DTRANSITIVE_TARGETS=1)
-    run_cxx_module_import_test(build export-transitive-modules-build -DTRANSITIVE_MODULES=1)
-    run_cxx_module_import_test(build export-with-headers-build -DWITH_HEADERS=1)
-
-    if ("build_database" IN_LIST CMake_TEST_MODULE_COMPILATION)
-      setup_export_build_database_targets()
-
-      run_cxx_module_import_test(build export-build-database -DBUILD_DATABASE=1 EXPORT_BUILD_DATABASE)
-
-      unset(RunCMake_CXXModules_TARGETS)
-    endif ()
-  endif ()
-endif ()
-
-# All of the following tests perform installation.
-set(RunCMake_CXXModules_INSTALL 1)
-
-# Tests which install BMIs
-if ("install_bmi" IN_LIST CMake_TEST_MODULE_COMPILATION)
-  run_cxx_module_test(install-bmi)
-  run_cxx_module_test(install-bmi-and-interfaces)
-
-  if ("export_bmi" IN_LIST CMake_TEST_MODULE_COMPILATION)
-    run_cxx_module_test(export-interface-no-properties-install)
-    run_cxx_module_test(export-interface-install)
-    run_cxx_module_test(export-include-directories-install)
-    run_cxx_module_test(export-include-directories-old-cmake-install)
-    run_cxx_module_test(export-usage-install)
-    run_cxx_module_test(export-bmi-and-interface-install)
-    run_cxx_module_test(export-command-sepdir-install)
-    run_cxx_module_test(export-transitive-targets-install)
-    run_cxx_module_test(export-transitive-modules1-install)
-    run_cxx_module_test(export-transitive-modules-install export-transitive-modules-install "-DCMAKE_PREFIX_PATH=${RunCMake_BINARY_DIR}/examples/export-transitive-modules1-install-install" )
-    run_cxx_module_test(export-with-headers-install)
-
-    if ("collation" IN_LIST CMake_TEST_MODULE_COMPILATION AND
-        "bmionly" IN_LIST CMake_TEST_MODULE_COMPILATION)
-      run_cxx_module_import_test(install export-interface-install)
-      run_cxx_module_import_test(install export-interface-no-properties-install -DNO_PROPERTIES=1)
-      run_cxx_module_import_test(install export-include-directories-install -DINCLUDE_PROPERTIES=1)
-      run_cxx_module_import_test(install export-bmi-and-interface-install -DWITH_BMIS=1)
-      run_cxx_module_import_test(install export-command-sepdir-install -DEXPORT_COMMAND_SEPDIR=1)
-      run_cxx_module_import_test(install export-transitive-targets-install -DTRANSITIVE_TARGETS=1)
-      run_cxx_module_import_test(install export-transitive-modules-install -DTRANSITIVE_MODULES=1)
-      run_cxx_module_import_test(install export-with-headers-install -DWITH_HEADERS=1)
-    endif ()
-  endif ()
-endif ()
-
-# All remaining tests require a working `Ninja` generator to set up a test case
-# for the current generator.
-if (NOT "ninja" IN_LIST CMake_TEST_MODULE_COMPILATION)
-  return ()
-endif ()
-# All remaining tests require `bmionly` in order to consume from the `ninja`
-# build.
-if (NOT "bmionly" IN_LIST CMake_TEST_MODULE_COMPILATION)
-  return ()
-endif ()
-
-function (run_cxx_module_test_ninja directory)
-  set(RunCMake_GENERATOR "Ninja")
-  set(RunCMake_CXXModules_NO_TEST 1)
-  set(RunCMake_CXXModules_INSTALL 1)
-  # `Ninja` is not a multi-config generator.
-  set(RunCMake_GENERATOR_IS_MULTI_CONFIG 0)
-  run_cxx_module_test("${directory}" "${directory}-ninja" ${ARGN})
-endfunction ()
-
-# Installation happens within `run_cxx_module_test_ninja`.
-set(RunCMake_CXXModules_INSTALL 0)
-
-set(test_set modules-from-ninja)
-run_cxx_module_test_ninja("export-${test_set}")
-run_cxx_module_test(import-modules "import-${test_set}" "-DCMAKE_PREFIX_PATH=${RunCMake_BINARY_DIR}/examples/export-${test_set}-ninja-install" -DFROM_NINJA=1)
diff --git a/Tests/RunCMake/CXXModules/examples/expect/export-build-database-cxx-config.json b/Tests/RunCMake/CXXModules/examples/expect/export-build-database-cxx-config.json
deleted file mode 100644
index 3815df5..0000000
--- a/Tests/RunCMake/CXXModules/examples/expect/export-build-database-cxx-config.json
+++ /dev/null
@@ -1,159 +0,0 @@
-{
-  "version": 1,
-  "revision": 0,
-  "sets": [
-    {
-      "family-name": "export_build_database",
-      "name": "export_build_database@<CONFIG>",
-      "translation-units": [
-        {
-          "arguments": [
-            "<IGNORE>",
-            "-D_MBCS",
-            "-Ddep_interface_define",
-            "-Dfrom_compile_definitions",
-            "-Dtarget_private_define",
-            "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
-            "-Dfrom_cmake_cxx_flags",
-            "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
-            "<CXX20_OPTION>",
-            "-Dfrom_compile_flags",
-            "-Dfrom_compile_options",
-            "-Dtarget_private_option",
-            "-Dtarget_public_option",
-            "-Ddep_interface_option",
-            "PATH:-Ddepflag=\"CMakeFiles/export_build_database.dir<CONFIG_DIR>/lib.cxx<OBJEXT>.d\"",
-            "PATH:<OUTPUT_FLAG>CMakeFiles/export_build_database.dir<CONFIG_DIR>/lib.cxx<OBJEXT>",
-            "-c",
-            "PATH:<SOURCE_DIR>/examples/export-build-database/lib.cxx"
-          ],
-          "baseline-arguments": [
-            "-D_MBCS",
-            "-Ddep_interface_define",
-            "-Dfrom_compile_definitions",
-            "-Dtarget_private_define",
-            "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
-            "-Dfrom_cmake_cxx_flags",
-            "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
-            "<CXX20_OPTION>",
-            "-Dfrom_compile_flags",
-            "-Dfrom_compile_options",
-            "-Dtarget_private_option",
-            "-Dtarget_public_option",
-            "-Ddep_interface_option"
-          ],
-          "local-arguments": [
-            "-D_MBCS",
-            "-Ddep_interface_define",
-            "-Dfrom_compile_definitions",
-            "-Dtarget_private_define",
-            "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
-            "-Dfrom_cmake_cxx_flags",
-            "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
-            "<CXX20_OPTION>",
-            "-Dfrom_compile_flags",
-            "-Dfrom_compile_options",
-            "-Dtarget_private_option",
-            "-Dtarget_public_option",
-            "-Ddep_interface_option"
-          ],
-          "object": "PATH:CMakeFiles/export_build_database.dir<CONFIG_DIR>/lib.cxx<OBJEXT>",
-          "private": true,
-          "provides": {},
-          "requires": ["importable"],
-          "source": "PATH:<SOURCE_DIR>/examples/export-build-database/lib.cxx",
-          "work-directory": "<BINARY_DIR>"
-        },
-        {
-          "arguments": [
-            "<IGNORE>",
-            "-D_MBCS",
-            "-Ddep_interface_define",
-            "-Dfrom_compile_definitions",
-            "-Dtarget_private_define",
-            "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
-            "-Dfrom_cmake_cxx_flags",
-            "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
-            "<CXX20_OPTION>",
-            "-Dfrom_compile_flags",
-            "-Dfrom_compile_options",
-            "-Dtarget_private_option",
-            "-Dtarget_public_option",
-            "-Ddep_interface_option",
-            "-Dfrom_source_flag",
-            "-Dfrom_source_option",
-            "PATH:-Ddepflag=\"CMakeFiles/export_build_database.dir<CONFIG_DIR>/importable.cxx<OBJEXT>.d\"",
-            "PATH:<OUTPUT_FLAG>CMakeFiles/export_build_database.dir<CONFIG_DIR>/importable.cxx<OBJEXT>",
-            "-c",
-            "PATH:<SOURCE_DIR>/examples/export-build-database/importable.cxx"
-          ],
-          "baseline-arguments": [
-            "-D_MBCS",
-            "-Ddep_interface_define",
-            "-Dfrom_compile_definitions",
-            "-Dtarget_private_define",
-            "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
-            "-Dfrom_cmake_cxx_flags",
-            "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
-            "<CXX20_OPTION>",
-            "-Dfrom_compile_flags",
-            "-Dfrom_compile_options",
-            "-Dtarget_private_option",
-            "-Dtarget_public_option",
-            "-Ddep_interface_option"
-          ],
-          "local-arguments": [
-            "-D_MBCS",
-            "-Ddep_interface_define",
-            "-Dfrom_compile_definitions",
-            "-Dtarget_private_define",
-            "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
-            "-Dfrom_cmake_cxx_flags",
-            "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
-            "<CXX20_OPTION>",
-            "-Dfrom_compile_flags",
-            "-Dfrom_compile_options",
-            "-Dtarget_private_option",
-            "-Dtarget_public_option",
-            "-Ddep_interface_option",
-            "-Dfrom_source_flag",
-            "-Dfrom_source_option"
-          ],
-          "object": "PATH:CMakeFiles/export_build_database.dir<CONFIG_DIR>/importable.cxx<OBJEXT>",
-          "private": false,
-          "provides": {
-            "importable": "PATH:<BINARY_DIR>/CMakeFiles/export_build_database.dir<CONFIG_DIR>/importable<BMIEXT>"
-          },
-          "requires": [],
-          "source": "PATH:<SOURCE_DIR>/examples/export-build-database/importable.cxx",
-          "work-directory": "<BINARY_DIR>"
-        }
-      ],
-      "visible-sets": []
-    }
-  ]
-}
diff --git a/Tests/RunCMake/CXXModules/examples/expect/export-build-database-cxx.json b/Tests/RunCMake/CXXModules/examples/expect/export-build-database-cxx.json
deleted file mode 100644
index 3815df5..0000000
--- a/Tests/RunCMake/CXXModules/examples/expect/export-build-database-cxx.json
+++ /dev/null
@@ -1,159 +0,0 @@
-{
-  "version": 1,
-  "revision": 0,
-  "sets": [
-    {
-      "family-name": "export_build_database",
-      "name": "export_build_database@<CONFIG>",
-      "translation-units": [
-        {
-          "arguments": [
-            "<IGNORE>",
-            "-D_MBCS",
-            "-Ddep_interface_define",
-            "-Dfrom_compile_definitions",
-            "-Dtarget_private_define",
-            "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
-            "-Dfrom_cmake_cxx_flags",
-            "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
-            "<CXX20_OPTION>",
-            "-Dfrom_compile_flags",
-            "-Dfrom_compile_options",
-            "-Dtarget_private_option",
-            "-Dtarget_public_option",
-            "-Ddep_interface_option",
-            "PATH:-Ddepflag=\"CMakeFiles/export_build_database.dir<CONFIG_DIR>/lib.cxx<OBJEXT>.d\"",
-            "PATH:<OUTPUT_FLAG>CMakeFiles/export_build_database.dir<CONFIG_DIR>/lib.cxx<OBJEXT>",
-            "-c",
-            "PATH:<SOURCE_DIR>/examples/export-build-database/lib.cxx"
-          ],
-          "baseline-arguments": [
-            "-D_MBCS",
-            "-Ddep_interface_define",
-            "-Dfrom_compile_definitions",
-            "-Dtarget_private_define",
-            "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
-            "-Dfrom_cmake_cxx_flags",
-            "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
-            "<CXX20_OPTION>",
-            "-Dfrom_compile_flags",
-            "-Dfrom_compile_options",
-            "-Dtarget_private_option",
-            "-Dtarget_public_option",
-            "-Ddep_interface_option"
-          ],
-          "local-arguments": [
-            "-D_MBCS",
-            "-Ddep_interface_define",
-            "-Dfrom_compile_definitions",
-            "-Dtarget_private_define",
-            "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
-            "-Dfrom_cmake_cxx_flags",
-            "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
-            "<CXX20_OPTION>",
-            "-Dfrom_compile_flags",
-            "-Dfrom_compile_options",
-            "-Dtarget_private_option",
-            "-Dtarget_public_option",
-            "-Ddep_interface_option"
-          ],
-          "object": "PATH:CMakeFiles/export_build_database.dir<CONFIG_DIR>/lib.cxx<OBJEXT>",
-          "private": true,
-          "provides": {},
-          "requires": ["importable"],
-          "source": "PATH:<SOURCE_DIR>/examples/export-build-database/lib.cxx",
-          "work-directory": "<BINARY_DIR>"
-        },
-        {
-          "arguments": [
-            "<IGNORE>",
-            "-D_MBCS",
-            "-Ddep_interface_define",
-            "-Dfrom_compile_definitions",
-            "-Dtarget_private_define",
-            "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
-            "-Dfrom_cmake_cxx_flags",
-            "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
-            "<CXX20_OPTION>",
-            "-Dfrom_compile_flags",
-            "-Dfrom_compile_options",
-            "-Dtarget_private_option",
-            "-Dtarget_public_option",
-            "-Ddep_interface_option",
-            "-Dfrom_source_flag",
-            "-Dfrom_source_option",
-            "PATH:-Ddepflag=\"CMakeFiles/export_build_database.dir<CONFIG_DIR>/importable.cxx<OBJEXT>.d\"",
-            "PATH:<OUTPUT_FLAG>CMakeFiles/export_build_database.dir<CONFIG_DIR>/importable.cxx<OBJEXT>",
-            "-c",
-            "PATH:<SOURCE_DIR>/examples/export-build-database/importable.cxx"
-          ],
-          "baseline-arguments": [
-            "-D_MBCS",
-            "-Ddep_interface_define",
-            "-Dfrom_compile_definitions",
-            "-Dtarget_private_define",
-            "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
-            "-Dfrom_cmake_cxx_flags",
-            "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
-            "<CXX20_OPTION>",
-            "-Dfrom_compile_flags",
-            "-Dfrom_compile_options",
-            "-Dtarget_private_option",
-            "-Dtarget_public_option",
-            "-Ddep_interface_option"
-          ],
-          "local-arguments": [
-            "-D_MBCS",
-            "-Ddep_interface_define",
-            "-Dfrom_compile_definitions",
-            "-Dtarget_private_define",
-            "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
-            "-Dfrom_cmake_cxx_flags",
-            "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
-            "<CXX20_OPTION>",
-            "-Dfrom_compile_flags",
-            "-Dfrom_compile_options",
-            "-Dtarget_private_option",
-            "-Dtarget_public_option",
-            "-Ddep_interface_option",
-            "-Dfrom_source_flag",
-            "-Dfrom_source_option"
-          ],
-          "object": "PATH:CMakeFiles/export_build_database.dir<CONFIG_DIR>/importable.cxx<OBJEXT>",
-          "private": false,
-          "provides": {
-            "importable": "PATH:<BINARY_DIR>/CMakeFiles/export_build_database.dir<CONFIG_DIR>/importable<BMIEXT>"
-          },
-          "requires": [],
-          "source": "PATH:<SOURCE_DIR>/examples/export-build-database/importable.cxx",
-          "work-directory": "<BINARY_DIR>"
-        }
-      ],
-      "visible-sets": []
-    }
-  ]
-}
diff --git a/Tests/RunCMake/CXXModules/examples/expect/export-build-database-imported-config.json b/Tests/RunCMake/CXXModules/examples/expect/export-build-database-imported-config.json
deleted file mode 100644
index 0e510b8..0000000
--- a/Tests/RunCMake/CXXModules/examples/expect/export-build-database-imported-config.json
+++ /dev/null
@@ -1,148 +0,0 @@
-{
-  "version": 1,
-  "revision": 0,
-  "sets": [
-    {
-      "family-name": "use_import_interfaces",
-      "name": "use_import_interfaces@<CONFIG>",
-      "translation-units": [
-        {
-          "arguments": [
-            "<IGNORE>",
-            "-D_MBCS",
-            "-Dtarget_interface_define",
-            "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "-Dfrom_cmake_cxx_flags",
-            "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
-            "<CXX20_OPTION>",
-            "-Dtarget_interface_option",
-            "-Dtarget_public_option",
-            "PATH:-Ddepflag=\"CMakeFiles/use_import_interfaces.dir<CONFIG_DIR>/use.cxx<OBJEXT>.d\"",
-            "PATH:<OUTPUT_FLAG>CMakeFiles/use_import_interfaces.dir<CONFIG_DIR>/use.cxx<OBJEXT>",
-            "-c",
-            "PATH:<SOURCE_DIR>/examples/import-modules/use.cxx"
-          ],
-          "baseline-arguments": [
-            "-D_MBCS",
-            "-Dtarget_interface_define",
-            "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "-Dfrom_cmake_cxx_flags",
-            "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
-            "<CXX20_OPTION>",
-            "-Dtarget_interface_option",
-            "-Dtarget_public_option"
-          ],
-          "local-arguments": [
-            "-D_MBCS",
-            "-Dtarget_interface_define",
-            "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "-Dfrom_cmake_cxx_flags",
-            "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
-            "<CXX20_OPTION>",
-            "-Dtarget_interface_option",
-            "-Dtarget_public_option"
-          ],
-          "object": "PATH:CMakeFiles/use_import_interfaces.dir<CONFIG_DIR>/use.cxx<OBJEXT>",
-          "private": true,
-          "provides": {},
-          "requires": ["importable"],
-          "source": "PATH:<SOURCE_DIR>/examples/import-modules/use.cxx",
-          "work-directory": "<BINARY_DIR>"
-        }
-      ],
-      "visible-sets": ["REGEX:CXXModules__export_build_database@synth_<HEX>@<CONFIG>"]
-    },
-    {
-      "family-name": "REGEX:CXXModules::export_build_database@<HEX>",
-      "name": "REGEX:CXXModules__export_build_database@synth_<HEX>@<CONFIG>",
-      "translation-units": [
-        {
-          "arguments": [
-            "<IGNORE>",
-            "-D_MBCS",
-            "-Ddep_interface_define",
-            "-Dfrom_compile_definitions",
-            "-Dtarget_interface_define",
-            "-Dtarget_private_define",
-            "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
-            "-Dfrom_cmake_cxx_flags",
-            "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
-            "<CXX20_OPTION>",
-            "-Dfrom_compile_options",
-            "-Dtarget_private_option",
-            "-Dtarget_public_option",
-            "-Ddep_interface_option",
-            "-Dtarget_interface_option",
-            "REGEX:PATH:-Ddepflag=\"CMakeFiles/CXXModules__export_build_database@synth_<HEX>.dir<CONFIG_DIR>/.d\"",
-            "REGEX:<BMI_ONLY_FLAG>",
-            "REGEX:PATH:<OUTPUT_FLAG>CMakeFiles/CXXModules__export_build_database@synth_<HEX>.dir<CONFIG_DIR>/",
-            "-c",
-            "PATH:<SOURCE_DIR>/examples/export-build-database/importable.cxx"
-          ],
-          "baseline-arguments": [
-            "-D_MBCS",
-            "-Ddep_interface_define",
-            "-Dfrom_compile_definitions",
-            "-Dtarget_interface_define",
-            "-Dtarget_private_define",
-            "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
-            "-Dfrom_cmake_cxx_flags",
-            "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
-            "<CXX20_OPTION>",
-            "-Dfrom_compile_options",
-            "-Dtarget_private_option",
-            "-Dtarget_public_option",
-            "-Ddep_interface_option",
-            "-Dtarget_interface_option"
-          ],
-          "local-arguments": [
-            "-D_MBCS",
-            "-Ddep_interface_define",
-            "-Dfrom_compile_definitions",
-            "-Dtarget_interface_define",
-            "-Dtarget_private_define",
-            "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
-            "-Dfrom_cmake_cxx_flags",
-            "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
-            "<CXX20_OPTION>",
-            "-Dfrom_compile_options",
-            "-Dtarget_private_option",
-            "-Dtarget_public_option",
-            "-Ddep_interface_option",
-            "-Dtarget_interface_option"
-          ],
-          "object": "PATH:CMakeFiles/use_import_interfaces.dir<CONFIG_DIR>/use.cxx<OBJEXT>",
-          "private": false,
-          "provides": {
-            "importable": "<IGNORE>"
-          },
-          "requires": [],
-          "source": "PATH:<SOURCE_DIR>/examples/export-build-database/importable.cxx",
-          "work-directory": "<BINARY_DIR>"
-        }
-      ],
-      "visible-sets": []
-    }
-  ]
-}
diff --git a/Tests/RunCMake/CXXModules/examples/expect/export-build-database-imported-cxx-config.json b/Tests/RunCMake/CXXModules/examples/expect/export-build-database-imported-cxx-config.json
deleted file mode 100644
index 0e510b8..0000000
--- a/Tests/RunCMake/CXXModules/examples/expect/export-build-database-imported-cxx-config.json
+++ /dev/null
@@ -1,148 +0,0 @@
-{
-  "version": 1,
-  "revision": 0,
-  "sets": [
-    {
-      "family-name": "use_import_interfaces",
-      "name": "use_import_interfaces@<CONFIG>",
-      "translation-units": [
-        {
-          "arguments": [
-            "<IGNORE>",
-            "-D_MBCS",
-            "-Dtarget_interface_define",
-            "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "-Dfrom_cmake_cxx_flags",
-            "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
-            "<CXX20_OPTION>",
-            "-Dtarget_interface_option",
-            "-Dtarget_public_option",
-            "PATH:-Ddepflag=\"CMakeFiles/use_import_interfaces.dir<CONFIG_DIR>/use.cxx<OBJEXT>.d\"",
-            "PATH:<OUTPUT_FLAG>CMakeFiles/use_import_interfaces.dir<CONFIG_DIR>/use.cxx<OBJEXT>",
-            "-c",
-            "PATH:<SOURCE_DIR>/examples/import-modules/use.cxx"
-          ],
-          "baseline-arguments": [
-            "-D_MBCS",
-            "-Dtarget_interface_define",
-            "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "-Dfrom_cmake_cxx_flags",
-            "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
-            "<CXX20_OPTION>",
-            "-Dtarget_interface_option",
-            "-Dtarget_public_option"
-          ],
-          "local-arguments": [
-            "-D_MBCS",
-            "-Dtarget_interface_define",
-            "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "-Dfrom_cmake_cxx_flags",
-            "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
-            "<CXX20_OPTION>",
-            "-Dtarget_interface_option",
-            "-Dtarget_public_option"
-          ],
-          "object": "PATH:CMakeFiles/use_import_interfaces.dir<CONFIG_DIR>/use.cxx<OBJEXT>",
-          "private": true,
-          "provides": {},
-          "requires": ["importable"],
-          "source": "PATH:<SOURCE_DIR>/examples/import-modules/use.cxx",
-          "work-directory": "<BINARY_DIR>"
-        }
-      ],
-      "visible-sets": ["REGEX:CXXModules__export_build_database@synth_<HEX>@<CONFIG>"]
-    },
-    {
-      "family-name": "REGEX:CXXModules::export_build_database@<HEX>",
-      "name": "REGEX:CXXModules__export_build_database@synth_<HEX>@<CONFIG>",
-      "translation-units": [
-        {
-          "arguments": [
-            "<IGNORE>",
-            "-D_MBCS",
-            "-Ddep_interface_define",
-            "-Dfrom_compile_definitions",
-            "-Dtarget_interface_define",
-            "-Dtarget_private_define",
-            "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
-            "-Dfrom_cmake_cxx_flags",
-            "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
-            "<CXX20_OPTION>",
-            "-Dfrom_compile_options",
-            "-Dtarget_private_option",
-            "-Dtarget_public_option",
-            "-Ddep_interface_option",
-            "-Dtarget_interface_option",
-            "REGEX:PATH:-Ddepflag=\"CMakeFiles/CXXModules__export_build_database@synth_<HEX>.dir<CONFIG_DIR>/.d\"",
-            "REGEX:<BMI_ONLY_FLAG>",
-            "REGEX:PATH:<OUTPUT_FLAG>CMakeFiles/CXXModules__export_build_database@synth_<HEX>.dir<CONFIG_DIR>/",
-            "-c",
-            "PATH:<SOURCE_DIR>/examples/export-build-database/importable.cxx"
-          ],
-          "baseline-arguments": [
-            "-D_MBCS",
-            "-Ddep_interface_define",
-            "-Dfrom_compile_definitions",
-            "-Dtarget_interface_define",
-            "-Dtarget_private_define",
-            "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
-            "-Dfrom_cmake_cxx_flags",
-            "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
-            "<CXX20_OPTION>",
-            "-Dfrom_compile_options",
-            "-Dtarget_private_option",
-            "-Dtarget_public_option",
-            "-Ddep_interface_option",
-            "-Dtarget_interface_option"
-          ],
-          "local-arguments": [
-            "-D_MBCS",
-            "-Ddep_interface_define",
-            "-Dfrom_compile_definitions",
-            "-Dtarget_interface_define",
-            "-Dtarget_private_define",
-            "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
-            "-Dfrom_cmake_cxx_flags",
-            "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
-            "<CXX20_OPTION>",
-            "-Dfrom_compile_options",
-            "-Dtarget_private_option",
-            "-Dtarget_public_option",
-            "-Ddep_interface_option",
-            "-Dtarget_interface_option"
-          ],
-          "object": "PATH:CMakeFiles/use_import_interfaces.dir<CONFIG_DIR>/use.cxx<OBJEXT>",
-          "private": false,
-          "provides": {
-            "importable": "<IGNORE>"
-          },
-          "requires": [],
-          "source": "PATH:<SOURCE_DIR>/examples/export-build-database/importable.cxx",
-          "work-directory": "<BINARY_DIR>"
-        }
-      ],
-      "visible-sets": []
-    }
-  ]
-}
diff --git a/Tests/RunCMake/CXXModules/examples/expect/export-build-database-imported-cxx-multi.json b/Tests/RunCMake/CXXModules/examples/expect/export-build-database-imported-cxx-multi.json
deleted file mode 100644
index de16f8e..0000000
--- a/Tests/RunCMake/CXXModules/examples/expect/export-build-database-imported-cxx-multi.json
+++ /dev/null
@@ -1,290 +0,0 @@
-{
-  "version": 1,
-  "revision": 0,
-  "sets": [
-    {
-      "family-name": "use_import_interfaces",
-      "name": "use_import_interfaces@<CONFIG>",
-      "translation-units": [
-        {
-          "arguments": [
-            "<IGNORE>",
-            "-D_MBCS",
-            "-Dtarget_interface_define",
-            "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "-Dfrom_cmake_cxx_flags",
-            "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
-            "<CXX20_OPTION>",
-            "-Dtarget_interface_option",
-            "-Dtarget_public_option",
-            "PATH:-Ddepflag=\"CMakeFiles/use_import_interfaces.dir<CONFIG_DIR>/use.cxx<OBJEXT>.d\"",
-            "PATH:<OUTPUT_FLAG>CMakeFiles/use_import_interfaces.dir<CONFIG_DIR>/use.cxx<OBJEXT>",
-            "-c",
-            "PATH:<SOURCE_DIR>/examples/import-modules/use.cxx"
-          ],
-          "baseline-arguments": [
-            "-D_MBCS",
-            "-Dtarget_interface_define",
-            "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "-Dfrom_cmake_cxx_flags",
-            "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
-            "<CXX20_OPTION>",
-            "-Dtarget_interface_option",
-            "-Dtarget_public_option"
-          ],
-          "local-arguments": [
-            "-D_MBCS",
-            "-Dtarget_interface_define",
-            "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "-Dfrom_cmake_cxx_flags",
-            "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
-            "<CXX20_OPTION>",
-            "-Dtarget_interface_option",
-            "-Dtarget_public_option"
-          ],
-          "object": "PATH:CMakeFiles/use_import_interfaces.dir<CONFIG_DIR>/use.cxx<OBJEXT>",
-          "private": true,
-          "provides": {},
-          "requires": ["importable"],
-          "source": "PATH:<SOURCE_DIR>/examples/import-modules/use.cxx",
-          "work-directory": "<BINARY_DIR>"
-        }
-      ],
-      "visible-sets": ["REGEX:CXXModules__export_build_database@synth_<HEX>@<CONFIG>"]
-    },
-    {
-      "family-name": "use_import_interfaces",
-      "name": "use_import_interfaces@<CONFIG_OTHER>",
-      "translation-units": [
-        {
-          "arguments": [
-            "<IGNORE>",
-            "-D_MBCS",
-            "-Dtarget_interface_define",
-            "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "-Dfrom_cmake_cxx_flags",
-            "-Dfrom_cmake_cxx_<CONFIG_OTHER_LOWER>_flags",
-            "<CXX20_OPTION>",
-            "-Dtarget_interface_option",
-            "-Dtarget_public_option",
-            "PATH:-Ddepflag=\"CMakeFiles/use_import_interfaces.dir<CONFIG_OTHER_DIR>/use.cxx<OBJEXT>.d\"",
-            "PATH:<OUTPUT_FLAG>CMakeFiles/use_import_interfaces.dir<CONFIG_OTHER_DIR>/use.cxx<OBJEXT>",
-            "-c",
-            "PATH:<SOURCE_DIR>/examples/import-modules/use.cxx"
-          ],
-          "baseline-arguments": [
-            "-D_MBCS",
-            "-Dtarget_interface_define",
-            "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "-Dfrom_cmake_cxx_flags",
-            "-Dfrom_cmake_cxx_<CONFIG_OTHER_LOWER>_flags",
-            "<CXX20_OPTION>",
-            "-Dtarget_interface_option",
-            "-Dtarget_public_option"
-          ],
-          "local-arguments": [
-            "-D_MBCS",
-            "-Dtarget_interface_define",
-            "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "-Dfrom_cmake_cxx_flags",
-            "-Dfrom_cmake_cxx_<CONFIG_OTHER_LOWER>_flags",
-            "<CXX20_OPTION>",
-            "-Dtarget_interface_option",
-            "-Dtarget_public_option"
-          ],
-          "object": "PATH:CMakeFiles/use_import_interfaces.dir<CONFIG_OTHER_DIR>/use.cxx<OBJEXT>",
-          "private": true,
-          "provides": {},
-          "requires": ["importable"],
-          "source": "PATH:<SOURCE_DIR>/examples/import-modules/use.cxx",
-          "work-directory": "<BINARY_DIR>"
-        }
-      ],
-      "visible-sets": ["REGEX:CXXModules__export_build_database@synth_<HEX>@<CONFIG_OTHER>"]
-    },
-    {
-      "family-name": "REGEX:CXXModules::export_build_database@<HEX>",
-      "name": "REGEX:CXXModules__export_build_database@synth_<HEX>@<CONFIG>",
-      "translation-units": [
-        {
-          "arguments": [
-            "<IGNORE>",
-            "-D_MBCS",
-            "-Ddep_interface_define",
-            "-Dfrom_compile_definitions",
-            "-Dtarget_interface_define",
-            "-Dtarget_private_define",
-            "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
-            "-Dfrom_cmake_cxx_flags",
-            "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
-            "<CXX20_OPTION>",
-            "-Dfrom_compile_options",
-            "-Dtarget_private_option",
-            "-Dtarget_public_option",
-            "-Ddep_interface_option",
-            "-Dtarget_interface_option",
-            "REGEX:PATH:-Ddepflag=\"CMakeFiles/CXXModules__export_build_database@synth_<HEX>.dir<CONFIG_DIR>/.d\"",
-            "REGEX:<BMI_ONLY_FLAG>",
-            "REGEX:PATH:<OUTPUT_FLAG>CMakeFiles/CXXModules__export_build_database@synth_<HEX>.dir<CONFIG_DIR>/",
-            "-c",
-            "PATH:<SOURCE_DIR>/examples/export-build-database/importable.cxx"
-          ],
-          "baseline-arguments": [
-            "-D_MBCS",
-            "-Ddep_interface_define",
-            "-Dfrom_compile_definitions",
-            "-Dtarget_interface_define",
-            "-Dtarget_private_define",
-            "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
-            "-Dfrom_cmake_cxx_flags",
-            "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
-            "<CXX20_OPTION>",
-            "-Dfrom_compile_options",
-            "-Dtarget_private_option",
-            "-Dtarget_public_option",
-            "-Ddep_interface_option",
-            "-Dtarget_interface_option"
-          ],
-          "local-arguments": [
-            "-D_MBCS",
-            "-Ddep_interface_define",
-            "-Dfrom_compile_definitions",
-            "-Dtarget_interface_define",
-            "-Dtarget_private_define",
-            "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
-            "-Dfrom_cmake_cxx_flags",
-            "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
-            "<CXX20_OPTION>",
-            "-Dfrom_compile_options",
-            "-Dtarget_private_option",
-            "-Dtarget_public_option",
-            "-Ddep_interface_option",
-            "-Dtarget_interface_option"
-          ],
-          "object": "PATH:CMakeFiles/use_import_interfaces.dir<CONFIG_DIR>/use.cxx<OBJEXT>",
-          "private": false,
-          "provides": {
-            "importable": "<IGNORE>"
-          },
-          "requires": [],
-          "source": "PATH:<SOURCE_DIR>/examples/export-build-database/importable.cxx",
-          "work-directory": "<BINARY_DIR>"
-        }
-      ],
-      "visible-sets": []
-    },
-    {
-      "family-name": "REGEX:CXXModules::export_build_database@<HEX>",
-      "name": "REGEX:CXXModules__export_build_database@synth_<HEX>@<CONFIG_OTHER>",
-      "translation-units": [
-        {
-          "arguments": [
-            "<IGNORE>",
-            "-D_MBCS",
-            "-Ddep_interface_define",
-            "-Dfrom_compile_definitions",
-            "-Dtarget_interface_define",
-            "-Dtarget_private_define",
-            "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
-            "-Dfrom_cmake_cxx_flags",
-            "-Dfrom_cmake_cxx_<CONFIG_OTHER_LOWER>_flags",
-            "<CXX20_OPTION>",
-            "-Dfrom_compile_options",
-            "-Dtarget_private_option",
-            "-Dtarget_public_option",
-            "-Ddep_interface_option",
-            "-Dtarget_interface_option",
-            "REGEX:PATH:-Ddepflag=\"CMakeFiles/CXXModules__export_build_database@synth_<HEX>.dir<CONFIG_OTHER_DIR>/.d\"",
-            "REGEX:<BMI_ONLY_FLAG>",
-            "REGEX:PATH:<OUTPUT_FLAG>CMakeFiles/CXXModules__export_build_database@synth_<HEX>.dir<CONFIG_OTHER_DIR>/",
-            "-c",
-            "PATH:<SOURCE_DIR>/examples/export-build-database/importable.cxx"
-          ],
-          "baseline-arguments": [
-            "-D_MBCS",
-            "-Ddep_interface_define",
-            "-Dfrom_compile_definitions",
-            "-Dtarget_interface_define",
-            "-Dtarget_private_define",
-            "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
-            "-Dfrom_cmake_cxx_flags",
-            "-Dfrom_cmake_cxx_<CONFIG_OTHER_LOWER>_flags",
-            "<CXX20_OPTION>",
-            "-Dfrom_compile_options",
-            "-Dtarget_private_option",
-            "-Dtarget_public_option",
-            "-Ddep_interface_option",
-            "-Dtarget_interface_option"
-          ],
-          "local-arguments": [
-            "-D_MBCS",
-            "-Ddep_interface_define",
-            "-Dfrom_compile_definitions",
-            "-Dtarget_interface_define",
-            "-Dtarget_private_define",
-            "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
-            "-Dfrom_cmake_cxx_flags",
-            "-Dfrom_cmake_cxx_<CONFIG_OTHER_LOWER>_flags",
-            "<CXX20_OPTION>",
-            "-Dfrom_compile_options",
-            "-Dtarget_private_option",
-            "-Dtarget_public_option",
-            "-Ddep_interface_option",
-            "-Dtarget_interface_option"
-          ],
-          "object": "PATH:CMakeFiles/use_import_interfaces.dir<CONFIG_OTHER_DIR>/use.cxx<OBJEXT>",
-          "private": false,
-          "provides": {
-            "importable": "<IGNORE>"
-          },
-          "requires": [],
-          "source": "PATH:<SOURCE_DIR>/examples/export-build-database/importable.cxx",
-          "work-directory": "<BINARY_DIR>"
-        }
-      ],
-      "visible-sets": []
-    }
-  ]
-}
diff --git a/Tests/RunCMake/CXXModules/examples/expect/export-build-database-imported-cxx.json b/Tests/RunCMake/CXXModules/examples/expect/export-build-database-imported-cxx.json
deleted file mode 100644
index 0e510b8..0000000
--- a/Tests/RunCMake/CXXModules/examples/expect/export-build-database-imported-cxx.json
+++ /dev/null
@@ -1,148 +0,0 @@
-{
-  "version": 1,
-  "revision": 0,
-  "sets": [
-    {
-      "family-name": "use_import_interfaces",
-      "name": "use_import_interfaces@<CONFIG>",
-      "translation-units": [
-        {
-          "arguments": [
-            "<IGNORE>",
-            "-D_MBCS",
-            "-Dtarget_interface_define",
-            "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "-Dfrom_cmake_cxx_flags",
-            "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
-            "<CXX20_OPTION>",
-            "-Dtarget_interface_option",
-            "-Dtarget_public_option",
-            "PATH:-Ddepflag=\"CMakeFiles/use_import_interfaces.dir<CONFIG_DIR>/use.cxx<OBJEXT>.d\"",
-            "PATH:<OUTPUT_FLAG>CMakeFiles/use_import_interfaces.dir<CONFIG_DIR>/use.cxx<OBJEXT>",
-            "-c",
-            "PATH:<SOURCE_DIR>/examples/import-modules/use.cxx"
-          ],
-          "baseline-arguments": [
-            "-D_MBCS",
-            "-Dtarget_interface_define",
-            "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "-Dfrom_cmake_cxx_flags",
-            "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
-            "<CXX20_OPTION>",
-            "-Dtarget_interface_option",
-            "-Dtarget_public_option"
-          ],
-          "local-arguments": [
-            "-D_MBCS",
-            "-Dtarget_interface_define",
-            "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "-Dfrom_cmake_cxx_flags",
-            "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
-            "<CXX20_OPTION>",
-            "-Dtarget_interface_option",
-            "-Dtarget_public_option"
-          ],
-          "object": "PATH:CMakeFiles/use_import_interfaces.dir<CONFIG_DIR>/use.cxx<OBJEXT>",
-          "private": true,
-          "provides": {},
-          "requires": ["importable"],
-          "source": "PATH:<SOURCE_DIR>/examples/import-modules/use.cxx",
-          "work-directory": "<BINARY_DIR>"
-        }
-      ],
-      "visible-sets": ["REGEX:CXXModules__export_build_database@synth_<HEX>@<CONFIG>"]
-    },
-    {
-      "family-name": "REGEX:CXXModules::export_build_database@<HEX>",
-      "name": "REGEX:CXXModules__export_build_database@synth_<HEX>@<CONFIG>",
-      "translation-units": [
-        {
-          "arguments": [
-            "<IGNORE>",
-            "-D_MBCS",
-            "-Ddep_interface_define",
-            "-Dfrom_compile_definitions",
-            "-Dtarget_interface_define",
-            "-Dtarget_private_define",
-            "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
-            "-Dfrom_cmake_cxx_flags",
-            "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
-            "<CXX20_OPTION>",
-            "-Dfrom_compile_options",
-            "-Dtarget_private_option",
-            "-Dtarget_public_option",
-            "-Ddep_interface_option",
-            "-Dtarget_interface_option",
-            "REGEX:PATH:-Ddepflag=\"CMakeFiles/CXXModules__export_build_database@synth_<HEX>.dir<CONFIG_DIR>/.d\"",
-            "REGEX:<BMI_ONLY_FLAG>",
-            "REGEX:PATH:<OUTPUT_FLAG>CMakeFiles/CXXModules__export_build_database@synth_<HEX>.dir<CONFIG_DIR>/",
-            "-c",
-            "PATH:<SOURCE_DIR>/examples/export-build-database/importable.cxx"
-          ],
-          "baseline-arguments": [
-            "-D_MBCS",
-            "-Ddep_interface_define",
-            "-Dfrom_compile_definitions",
-            "-Dtarget_interface_define",
-            "-Dtarget_private_define",
-            "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
-            "-Dfrom_cmake_cxx_flags",
-            "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
-            "<CXX20_OPTION>",
-            "-Dfrom_compile_options",
-            "-Dtarget_private_option",
-            "-Dtarget_public_option",
-            "-Ddep_interface_option",
-            "-Dtarget_interface_option"
-          ],
-          "local-arguments": [
-            "-D_MBCS",
-            "-Ddep_interface_define",
-            "-Dfrom_compile_definitions",
-            "-Dtarget_interface_define",
-            "-Dtarget_private_define",
-            "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
-            "-Dfrom_cmake_cxx_flags",
-            "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
-            "<CXX20_OPTION>",
-            "-Dfrom_compile_options",
-            "-Dtarget_private_option",
-            "-Dtarget_public_option",
-            "-Ddep_interface_option",
-            "-Dtarget_interface_option"
-          ],
-          "object": "PATH:CMakeFiles/use_import_interfaces.dir<CONFIG_DIR>/use.cxx<OBJEXT>",
-          "private": false,
-          "provides": {
-            "importable": "<IGNORE>"
-          },
-          "requires": [],
-          "source": "PATH:<SOURCE_DIR>/examples/export-build-database/importable.cxx",
-          "work-directory": "<BINARY_DIR>"
-        }
-      ],
-      "visible-sets": []
-    }
-  ]
-}
diff --git a/Tests/RunCMake/CXXModules/examples/expect/export-build-database-target.json b/Tests/RunCMake/CXXModules/examples/expect/export-build-database-target.json
deleted file mode 100644
index 4412d35..0000000
--- a/Tests/RunCMake/CXXModules/examples/expect/export-build-database-target.json
+++ /dev/null
@@ -1,159 +0,0 @@
-{
-  "version": 1,
-  "revision": 0,
-  "sets": [
-    {
-      "family-name": "export_build_database",
-      "name": "export_build_database@<CONFIG>",
-      "translation-units": [
-        {
-          "arguments": [
-            "<IGNORE>",
-            "-D_MBCS",
-            "-Ddep_interface_define",
-            "-Dfrom_compile_definitions",
-            "-Dtarget_private_define",
-            "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
-            "-Dfrom_cmake_cxx_flags",
-            "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
-            "<CXX20_OPTION>",
-            "-Dfrom_compile_flags",
-            "-Dfrom_compile_options",
-            "-Dtarget_private_option",
-            "-Dtarget_public_option",
-            "-Ddep_interface_option",
-            "PATH:-Ddepflag=\"CMakeFiles/export_build_database.dir<CONFIG_DIR>/lib.cxx<OBJEXT>.d\"",
-            "PATH:<OUTPUT_FLAG>CMakeFiles/export_build_database.dir<CONFIG_DIR>/lib.cxx<OBJEXT>",
-            "-c",
-            "PATH:<SOURCE_DIR>/examples/export-build-database/lib.cxx"
-          ],
-          "baseline-arguments": [
-            "-D_MBCS",
-            "-Ddep_interface_define",
-            "-Dfrom_compile_definitions",
-            "-Dtarget_private_define",
-            "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
-            "-Dfrom_cmake_cxx_flags",
-            "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
-            "<CXX20_OPTION>",
-            "-Dfrom_compile_flags",
-            "-Dfrom_compile_options",
-            "-Dtarget_private_option",
-            "-Dtarget_public_option",
-            "-Ddep_interface_option"
-          ],
-          "local-arguments": [
-            "-D_MBCS",
-            "-Ddep_interface_define",
-            "-Dfrom_compile_definitions",
-            "-Dtarget_private_define",
-            "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
-            "-Dfrom_cmake_cxx_flags",
-            "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
-            "<CXX20_OPTION>",
-            "-Dfrom_compile_flags",
-            "-Dfrom_compile_options",
-            "-Dtarget_private_option",
-            "-Dtarget_public_option",
-            "-Ddep_interface_option"
-          ],
-          "object": "PATH:CMakeFiles/export_build_database.dir<CONFIG_DIR>/lib.cxx<OBJEXT>",
-          "private": true,
-          "provides": {},
-          "requires": ["importable"],
-          "source": "PATH:<SOURCE_DIR>/examples/export-build-database/lib.cxx",
-          "work-directory": "<BINARY_DIR>"
-        },
-        {
-          "arguments": [
-            "<IGNORE>",
-            "-D_MBCS",
-            "-Ddep_interface_define",
-            "-Dfrom_compile_definitions",
-            "-Dtarget_private_define",
-            "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
-            "-Dfrom_cmake_cxx_flags",
-            "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
-            "<CXX20_OPTION>",
-            "-Dfrom_compile_flags",
-            "-Dfrom_compile_options",
-            "-Dtarget_private_option",
-            "-Dtarget_public_option",
-            "-Ddep_interface_option",
-            "-Dfrom_source_flag",
-            "-Dfrom_source_option",
-            "PATH:-Ddepflag=\"CMakeFiles/export_build_database.dir<CONFIG_DIR>/importable.cxx<OBJEXT>.d\"",
-            "PATH:<OUTPUT_FLAG>CMakeFiles/export_build_database.dir<CONFIG_DIR>/importable.cxx<OBJEXT>",
-            "-c",
-            "PATH:<SOURCE_DIR>/examples/export-build-database/importable.cxx"
-          ],
-          "baseline-arguments": [
-            "-D_MBCS",
-            "-Ddep_interface_define",
-            "-Dfrom_compile_definitions",
-            "-Dtarget_private_define",
-            "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
-            "-Dfrom_cmake_cxx_flags",
-            "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
-            "<CXX20_OPTION>",
-            "-Dfrom_compile_flags",
-            "-Dfrom_compile_options",
-            "-Dtarget_private_option",
-            "-Dtarget_public_option",
-            "-Ddep_interface_option"
-          ],
-          "local-arguments": [
-            "-D_MBCS",
-            "-Ddep_interface_define",
-            "-Dfrom_compile_definitions",
-            "-Dtarget_private_define",
-            "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
-            "-Dfrom_cmake_cxx_flags",
-            "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
-            "<CXX20_OPTION>",
-            "-Dfrom_compile_flags",
-            "-Dfrom_compile_options",
-            "-Dtarget_private_option",
-            "-Dtarget_public_option",
-            "-Ddep_interface_option",
-            "-Dfrom_source_flag",
-            "-Dfrom_source_option"
-          ],
-          "object": "PATH:CMakeFiles/export_build_database.dir<CONFIG_DIR>/importable.cxx<OBJEXT>",
-          "private": false,
-          "provides": {
-            "importable": "<BINARY_DIR>/CMakeFiles/export_build_database.dir<CONFIG_DIR>/importable<BMIEXT>"
-          },
-          "requires": [],
-          "source": "PATH:<SOURCE_DIR>/examples/export-build-database/importable.cxx",
-          "work-directory": "<BINARY_DIR>"
-        }
-      ],
-      "visible-sets": []
-    }
-  ]
-}
diff --git a/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-build/forward.cxx b/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-build/forward.cxx
deleted file mode 100644
index 7f53271..0000000
--- a/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-build/forward.cxx
+++ /dev/null
@@ -1,6 +0,0 @@
-import priv;
-
-int forwarding()
-{
-  return from_private();
-}
diff --git a/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-build/importable.cxx b/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-build/importable.cxx
deleted file mode 100644
index 8dfc41b..0000000
--- a/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-build/importable.cxx
+++ /dev/null
@@ -1,10 +0,0 @@
-export module importable;
-
-extern "C++" {
-int forwarding();
-}
-
-export int from_import()
-{
-  return forwarding();
-}
diff --git a/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-build/no_modules.cxx b/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-build/no_modules.cxx
deleted file mode 100644
index eea854f..0000000
--- a/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-build/no_modules.cxx
+++ /dev/null
@@ -1,3 +0,0 @@
-void no_modules()
-{
-}
diff --git a/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-build/private.cxx b/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-build/private.cxx
deleted file mode 100644
index c5b719a..0000000
--- a/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-build/private.cxx
+++ /dev/null
@@ -1,6 +0,0 @@
-export module priv;
-
-export int from_private()
-{
-  return 0;
-}
diff --git a/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-build/subdir/importable.cxx b/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-build/subdir/importable.cxx
deleted file mode 100644
index 07d6af6..0000000
--- a/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-build/subdir/importable.cxx
+++ /dev/null
@@ -1,6 +0,0 @@
-export module subdir_importable;
-
-export int from_subdir()
-{
-  return 0;
-}
diff --git a/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-install/forward.cxx b/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-install/forward.cxx
deleted file mode 100644
index 7f53271..0000000
--- a/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-install/forward.cxx
+++ /dev/null
@@ -1,6 +0,0 @@
-import priv;
-
-int forwarding()
-{
-  return from_private();
-}
diff --git a/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-install/importable.cxx b/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-install/importable.cxx
deleted file mode 100644
index 8dfc41b..0000000
--- a/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-install/importable.cxx
+++ /dev/null
@@ -1,10 +0,0 @@
-export module importable;
-
-extern "C++" {
-int forwarding();
-}
-
-export int from_import()
-{
-  return forwarding();
-}
diff --git a/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-install/no_modules.cxx b/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-install/no_modules.cxx
deleted file mode 100644
index eea854f..0000000
--- a/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-install/no_modules.cxx
+++ /dev/null
@@ -1,3 +0,0 @@
-void no_modules()
-{
-}
diff --git a/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-install/private.cxx b/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-install/private.cxx
deleted file mode 100644
index c5b719a..0000000
--- a/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-install/private.cxx
+++ /dev/null
@@ -1,6 +0,0 @@
-export module priv;
-
-export int from_private()
-{
-  return 0;
-}
diff --git a/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-install/subdir/importable.cxx b/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-install/subdir/importable.cxx
deleted file mode 100644
index 07d6af6..0000000
--- a/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-install/subdir/importable.cxx
+++ /dev/null
@@ -1,6 +0,0 @@
-export module subdir_importable;
-
-export int from_subdir()
-{
-  return 0;
-}
diff --git a/Tests/RunCMake/CXXModules/examples/export-build-database-build-check.cmake b/Tests/RunCMake/CXXModules/examples/export-build-database-build-check.cmake
deleted file mode 100644
index 131926b..0000000
--- a/Tests/RunCMake/CXXModules/examples/export-build-database-build-check.cmake
+++ /dev/null
@@ -1,19 +0,0 @@
-include("${CMAKE_CURRENT_LIST_DIR}/build-database-check.cmake")
-
-check_build_database("export-build-database" "build_database.json" NO_EXIST)
-check_build_database("export-build-database" "build_database_CXX.json" NO_EXIST)
-
-check_build_database("export-build-database" "build_database_CXX_Debug.json" NO_EXIST)
-check_build_database("export-build-database" "build_database_Debug.json" NO_EXIST)
-
-if (RunCMake_GENERATOR_IS_MULTI_CONFIG)
-  check_build_database("export-build-database" "CMakeFiles/export_build_database.dir/Debug/CXX_build_database.json" JUST_TARGET_DEBUG)
-
-  # check_build_database("export-build-database" "build_database_CXX_Release.json" NO_EXIST)
-  # check_build_database("export-build-database" "build_database_Release.json" NO_EXIST)
-  # check_build_database("export-build-database" "CMakeFiles/export_build_database.dir/Release/CXX_build_database.json" NO_EXIST)
-else ()
-  check_build_database("export-build-database" "CMakeFiles/export_build_database.dir/CXX_build_database.json" JUST_TARGET)
-endif ()
-
-string(REPLACE ";" "\n  " RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}")
diff --git a/Tests/RunCMake/CXXModules/examples/export-build-database-target-cmake_build_database-check.cmake b/Tests/RunCMake/CXXModules/examples/export-build-database-target-cmake_build_database-check.cmake
deleted file mode 100644
index 79db482..0000000
--- a/Tests/RunCMake/CXXModules/examples/export-build-database-target-cmake_build_database-check.cmake
+++ /dev/null
@@ -1,21 +0,0 @@
-include("${CMAKE_CURRENT_LIST_DIR}/build-database-check.cmake")
-
-if (RunCMake_GENERATOR_IS_MULTI_CONFIG)
-  check_build_database("export-build-database" "build_database.json" ALL_MULTI)
-  check_build_database("export-build-database" "build_database_CXX.json" JUST_CXX_MULTI)
-
-  check_build_database("export-build-database" "build_database_CXX_Debug.json" CXX_AND_DEBUG)
-  check_build_database("export-build-database" "build_database_Debug.json" JUST_DEBUG)
-  check_build_database("export-build-database" "CMakeFiles/export_build_database.dir/Debug/CXX_build_database.json" JUST_TARGET_DEBUG)
-
-  check_build_database("export-build-database" "build_database_CXX_Release.json" CXX_AND_RELEASE)
-  check_build_database("export-build-database" "build_database_Release.json" JUST_RELEASE)
-  check_build_database("export-build-database" "CMakeFiles/export_build_database.dir/Release/CXX_build_database.json" JUST_TARGET_RELEASE)
-else ()
-  check_build_database("export-build-database" "build_database.json" ALL)
-  check_build_database("export-build-database" "build_database_CXX.json" JUST_CXX)
-
-  check_build_database("export-build-database" "CMakeFiles/export_build_database.dir/CXX_build_database.json" JUST_TARGET)
-endif ()
-
-string(REPLACE ";" "\n  " RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}")
diff --git a/Tests/RunCMake/CXXModules/examples/export-build-database/importable.cxx b/Tests/RunCMake/CXXModules/examples/export-build-database/importable.cxx
deleted file mode 100644
index 607680a..0000000
--- a/Tests/RunCMake/CXXModules/examples/export-build-database/importable.cxx
+++ /dev/null
@@ -1,6 +0,0 @@
-export module importable;
-
-export int from_import()
-{
-  return 0;
-}
diff --git a/Tests/RunCMake/CXXModules/examples/export-include-directories-build/forward.cxx b/Tests/RunCMake/CXXModules/examples/export-include-directories-build/forward.cxx
deleted file mode 100644
index 7f53271..0000000
--- a/Tests/RunCMake/CXXModules/examples/export-include-directories-build/forward.cxx
+++ /dev/null
@@ -1,6 +0,0 @@
-import priv;
-
-int forwarding()
-{
-  return from_private();
-}
diff --git a/Tests/RunCMake/CXXModules/examples/export-include-directories-build/no_modules.cxx b/Tests/RunCMake/CXXModules/examples/export-include-directories-build/no_modules.cxx
deleted file mode 100644
index eea854f..0000000
--- a/Tests/RunCMake/CXXModules/examples/export-include-directories-build/no_modules.cxx
+++ /dev/null
@@ -1,3 +0,0 @@
-void no_modules()
-{
-}
diff --git a/Tests/RunCMake/CXXModules/examples/export-include-directories-build/private.cxx b/Tests/RunCMake/CXXModules/examples/export-include-directories-build/private.cxx
deleted file mode 100644
index c5b719a..0000000
--- a/Tests/RunCMake/CXXModules/examples/export-include-directories-build/private.cxx
+++ /dev/null
@@ -1,6 +0,0 @@
-export module priv;
-
-export int from_private()
-{
-  return 0;
-}
diff --git a/Tests/RunCMake/CXXModules/examples/export-include-directories-build/subdir/importable.cxx b/Tests/RunCMake/CXXModules/examples/export-include-directories-build/subdir/importable.cxx
deleted file mode 100644
index 07d6af6..0000000
--- a/Tests/RunCMake/CXXModules/examples/export-include-directories-build/subdir/importable.cxx
+++ /dev/null
@@ -1,6 +0,0 @@
-export module subdir_importable;
-
-export int from_subdir()
-{
-  return 0;
-}
diff --git a/Tests/RunCMake/CXXModules/examples/export-include-directories-install/forward.cxx b/Tests/RunCMake/CXXModules/examples/export-include-directories-install/forward.cxx
deleted file mode 100644
index 7f53271..0000000
--- a/Tests/RunCMake/CXXModules/examples/export-include-directories-install/forward.cxx
+++ /dev/null
@@ -1,6 +0,0 @@
-import priv;
-
-int forwarding()
-{
-  return from_private();
-}
diff --git a/Tests/RunCMake/CXXModules/examples/export-include-directories-install/includes/includes.h b/Tests/RunCMake/CXXModules/examples/export-include-directories-install/includes/includes.h
deleted file mode 100644
index 96bf33b..0000000
--- a/Tests/RunCMake/CXXModules/examples/export-include-directories-install/includes/includes.h
+++ /dev/null
@@ -1,3 +0,0 @@
-#pragma once
-
-#define includes_h_included
diff --git a/Tests/RunCMake/CXXModules/examples/export-include-directories-install/no_modules.cxx b/Tests/RunCMake/CXXModules/examples/export-include-directories-install/no_modules.cxx
deleted file mode 100644
index eea854f..0000000
--- a/Tests/RunCMake/CXXModules/examples/export-include-directories-install/no_modules.cxx
+++ /dev/null
@@ -1,3 +0,0 @@
-void no_modules()
-{
-}
diff --git a/Tests/RunCMake/CXXModules/examples/export-include-directories-install/private.cxx b/Tests/RunCMake/CXXModules/examples/export-include-directories-install/private.cxx
deleted file mode 100644
index c5b719a..0000000
--- a/Tests/RunCMake/CXXModules/examples/export-include-directories-install/private.cxx
+++ /dev/null
@@ -1,6 +0,0 @@
-export module priv;
-
-export int from_private()
-{
-  return 0;
-}
diff --git a/Tests/RunCMake/CXXModules/examples/export-include-directories-install/subdir/importable.cxx b/Tests/RunCMake/CXXModules/examples/export-include-directories-install/subdir/importable.cxx
deleted file mode 100644
index 07d6af6..0000000
--- a/Tests/RunCMake/CXXModules/examples/export-include-directories-install/subdir/importable.cxx
+++ /dev/null
@@ -1,6 +0,0 @@
-export module subdir_importable;
-
-export int from_subdir()
-{
-  return 0;
-}
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-no-properties-build/forward.cxx b/Tests/RunCMake/CXXModules/examples/export-interface-no-properties-build/forward.cxx
deleted file mode 100644
index 7f53271..0000000
--- a/Tests/RunCMake/CXXModules/examples/export-interface-no-properties-build/forward.cxx
+++ /dev/null
@@ -1,6 +0,0 @@
-import priv;
-
-int forwarding()
-{
-  return from_private();
-}
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-no-properties-build/importable.cxx b/Tests/RunCMake/CXXModules/examples/export-interface-no-properties-build/importable.cxx
deleted file mode 100644
index 8dfc41b..0000000
--- a/Tests/RunCMake/CXXModules/examples/export-interface-no-properties-build/importable.cxx
+++ /dev/null
@@ -1,10 +0,0 @@
-export module importable;
-
-extern "C++" {
-int forwarding();
-}
-
-export int from_import()
-{
-  return forwarding();
-}
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-no-properties-build/no_modules.cxx b/Tests/RunCMake/CXXModules/examples/export-interface-no-properties-build/no_modules.cxx
deleted file mode 100644
index eea854f..0000000
--- a/Tests/RunCMake/CXXModules/examples/export-interface-no-properties-build/no_modules.cxx
+++ /dev/null
@@ -1,3 +0,0 @@
-void no_modules()
-{
-}
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-no-properties-build/private.cxx b/Tests/RunCMake/CXXModules/examples/export-interface-no-properties-build/private.cxx
deleted file mode 100644
index c5b719a..0000000
--- a/Tests/RunCMake/CXXModules/examples/export-interface-no-properties-build/private.cxx
+++ /dev/null
@@ -1,6 +0,0 @@
-export module priv;
-
-export int from_private()
-{
-  return 0;
-}
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-no-properties-build/subdir/importable.cxx b/Tests/RunCMake/CXXModules/examples/export-interface-no-properties-build/subdir/importable.cxx
deleted file mode 100644
index 07d6af6..0000000
--- a/Tests/RunCMake/CXXModules/examples/export-interface-no-properties-build/subdir/importable.cxx
+++ /dev/null
@@ -1,6 +0,0 @@
-export module subdir_importable;
-
-export int from_subdir()
-{
-  return 0;
-}
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-no-properties-install/forward.cxx b/Tests/RunCMake/CXXModules/examples/export-interface-no-properties-install/forward.cxx
deleted file mode 100644
index 7f53271..0000000
--- a/Tests/RunCMake/CXXModules/examples/export-interface-no-properties-install/forward.cxx
+++ /dev/null
@@ -1,6 +0,0 @@
-import priv;
-
-int forwarding()
-{
-  return from_private();
-}
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-no-properties-install/importable.cxx b/Tests/RunCMake/CXXModules/examples/export-interface-no-properties-install/importable.cxx
deleted file mode 100644
index 8dfc41b..0000000
--- a/Tests/RunCMake/CXXModules/examples/export-interface-no-properties-install/importable.cxx
+++ /dev/null
@@ -1,10 +0,0 @@
-export module importable;
-
-extern "C++" {
-int forwarding();
-}
-
-export int from_import()
-{
-  return forwarding();
-}
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-no-properties-install/no_modules.cxx b/Tests/RunCMake/CXXModules/examples/export-interface-no-properties-install/no_modules.cxx
deleted file mode 100644
index eea854f..0000000
--- a/Tests/RunCMake/CXXModules/examples/export-interface-no-properties-install/no_modules.cxx
+++ /dev/null
@@ -1,3 +0,0 @@
-void no_modules()
-{
-}
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-no-properties-install/private.cxx b/Tests/RunCMake/CXXModules/examples/export-interface-no-properties-install/private.cxx
deleted file mode 100644
index c5b719a..0000000
--- a/Tests/RunCMake/CXXModules/examples/export-interface-no-properties-install/private.cxx
+++ /dev/null
@@ -1,6 +0,0 @@
-export module priv;
-
-export int from_private()
-{
-  return 0;
-}
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-no-properties-install/subdir/importable.cxx b/Tests/RunCMake/CXXModules/examples/export-interface-no-properties-install/subdir/importable.cxx
deleted file mode 100644
index 07d6af6..0000000
--- a/Tests/RunCMake/CXXModules/examples/export-interface-no-properties-install/subdir/importable.cxx
+++ /dev/null
@@ -1,6 +0,0 @@
-export module subdir_importable;
-
-export int from_subdir()
-{
-  return 0;
-}
diff --git a/Tests/RunCMake/CXXModules/examples/export-transitive-targets-install/subdir/importable.cxx b/Tests/RunCMake/CXXModules/examples/export-transitive-targets-install/subdir/importable.cxx
deleted file mode 100644
index 07d6af6..0000000
--- a/Tests/RunCMake/CXXModules/examples/export-transitive-targets-install/subdir/importable.cxx
+++ /dev/null
@@ -1,6 +0,0 @@
-export module subdir_importable;
-
-export int from_subdir()
-{
-  return 0;
-}
diff --git a/Tests/RunCMake/CXXModules/examples/import-modules-export-build-database-build-check.cmake b/Tests/RunCMake/CXXModules/examples/import-modules-export-build-database-build-check.cmake
deleted file mode 100644
index 21a29b6..0000000
--- a/Tests/RunCMake/CXXModules/examples/import-modules-export-build-database-build-check.cmake
+++ /dev/null
@@ -1,18 +0,0 @@
-include("${CMAKE_CURRENT_LIST_DIR}/build-database-check.cmake")
-set(item_filter "-ifcOnly")
-
-check_build_database("export-build-database-imported" "build_database.json" NO_EXIST)
-check_build_database("export-build-database-imported" "build_database_CXX.json" NO_EXIST)
-if (RunCMake_GENERATOR_IS_MULTI_CONFIG)
-  check_build_database("export-build-database-imported" "build_database_CXX_Debug.json" NO_EXIST)
-  check_build_database("export-build-database-imported" "build_database_Debug.json" NO_EXIST)
-  check_build_database("export-build-database-imported" "CMakeFiles/export-module-commands.dir/Debug/CXX_build_database.json" NO_EXIST)
-
-  check_build_database("export-build-database-imported" "build_database_CXX_Release.json" NO_EXIST)
-  check_build_database("export-build-database-imported" "build_database_Release.json" NO_EXIST)
-  check_build_database("export-build-database-imported" "CMakeFiles/export-module-commands.dir/Release/CXX_build_database.json" NO_EXIST)
-else ()
-  check_build_database("export-build-database-imported" "CMakeFiles/export-module-commands.dir/CXX_build_database.json" NO_EXIST)
-endif ()
-
-string(REPLACE ";" "\n  " RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}")
diff --git a/Tests/RunCMake/CXXModules/examples/import-modules-export-build-database-check.cmake b/Tests/RunCMake/CXXModules/examples/import-modules-export-build-database-check.cmake
deleted file mode 100644
index 21a29b6..0000000
--- a/Tests/RunCMake/CXXModules/examples/import-modules-export-build-database-check.cmake
+++ /dev/null
@@ -1,18 +0,0 @@
-include("${CMAKE_CURRENT_LIST_DIR}/build-database-check.cmake")
-set(item_filter "-ifcOnly")
-
-check_build_database("export-build-database-imported" "build_database.json" NO_EXIST)
-check_build_database("export-build-database-imported" "build_database_CXX.json" NO_EXIST)
-if (RunCMake_GENERATOR_IS_MULTI_CONFIG)
-  check_build_database("export-build-database-imported" "build_database_CXX_Debug.json" NO_EXIST)
-  check_build_database("export-build-database-imported" "build_database_Debug.json" NO_EXIST)
-  check_build_database("export-build-database-imported" "CMakeFiles/export-module-commands.dir/Debug/CXX_build_database.json" NO_EXIST)
-
-  check_build_database("export-build-database-imported" "build_database_CXX_Release.json" NO_EXIST)
-  check_build_database("export-build-database-imported" "build_database_Release.json" NO_EXIST)
-  check_build_database("export-build-database-imported" "CMakeFiles/export-module-commands.dir/Release/CXX_build_database.json" NO_EXIST)
-else ()
-  check_build_database("export-build-database-imported" "CMakeFiles/export-module-commands.dir/CXX_build_database.json" NO_EXIST)
-endif ()
-
-string(REPLACE ";" "\n  " RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}")
diff --git a/Tests/RunCMake/CXXModules/examples/import-modules-export-build-database-stderr.txt b/Tests/RunCMake/CXXModules/examples/import-modules-export-build-database-stderr.txt
deleted file mode 100644
index a001af7..0000000
--- a/Tests/RunCMake/CXXModules/examples/import-modules-export-build-database-stderr.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-CMake Warning \(dev\) in CMakeLists\.txt:
-  CMake's support for exporting build databases is experimental\.  It is meant
-  only for experimentation and feedback to CMake developers\.
-This warning is for project developers\.  Use -Wno-dev to suppress it\.
diff --git a/Tests/RunCMake/CXXModules/examples/import-modules-export-build-database-target-cmake_build_database-check.cmake b/Tests/RunCMake/CXXModules/examples/import-modules-export-build-database-target-cmake_build_database-check.cmake
deleted file mode 100644
index cfa3a3c..0000000
--- a/Tests/RunCMake/CXXModules/examples/import-modules-export-build-database-target-cmake_build_database-check.cmake
+++ /dev/null
@@ -1,22 +0,0 @@
-include("${CMAKE_CURRENT_LIST_DIR}/build-database-check.cmake")
-set(item_filter "-ifcOnly")
-
-if (RunCMake_GENERATOR_IS_MULTI_CONFIG)
-  check_build_database("export-build-database-imported" "build_database.json" ALL_MULTI)
-  check_build_database("export-build-database-imported" "build_database_CXX.json" JUST_CXX_MULTI)
-
-  check_build_database("export-build-database-imported" "build_database_CXX_Debug.json" CXX_AND_DEBUG)
-  check_build_database("export-build-database-imported" "build_database_Debug.json" JUST_DEBUG)
-  check_build_database("export-build-database-imported" "CMakeFiles/use_import_interfaces.dir/Debug/CXX_build_database.json" JUST_TARGET_DEBUG)
-
-  check_build_database("export-build-database-imported" "build_database_CXX_Release.json" CXX_AND_RELEASE)
-  check_build_database("export-build-database-imported" "build_database_Release.json" JUST_RELEASE)
-  check_build_database("export-build-database-imported" "CMakeFiles/use_import_interfaces.dir/Release/CXX_build_database.json" JUST_TARGET_RELEASE)
-else ()
-  check_build_database("export-build-database-imported" "build_database.json" ALL)
-  check_build_database("export-build-database-imported" "build_database_CXX.json" JUST_CXX)
-
-  check_build_database("export-build-database-imported" "CMakeFiles/use_import_interfaces.dir/CXX_build_database.json" JUST_TARGET)
-endif ()
-
-string(REPLACE ";" "\n  " RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}")
diff --git a/Tests/RunCMake/CXXModules/examples/import-modules-export-build-database-target-cmake_build_database/CXX-check.cmake b/Tests/RunCMake/CXXModules/examples/import-modules-export-build-database-target-cmake_build_database/CXX-check.cmake
deleted file mode 100644
index 39203d9..0000000
--- a/Tests/RunCMake/CXXModules/examples/import-modules-export-build-database-target-cmake_build_database/CXX-check.cmake
+++ /dev/null
@@ -1,22 +0,0 @@
-include("${CMAKE_CURRENT_LIST_DIR}/../build-database-check.cmake")
-set(item_filter "-ifcOnly")
-
-check_build_database("export-build-database-imported" "build_database.json" NO_EXIST)
-
-if (RunCMake_GENERATOR_IS_MULTI_CONFIG)
-  check_build_database("export-build-database-imported" "build_database_CXX.json" JUST_CXX_MULTI)
-
-  check_build_database("export-build-database-imported" "build_database_CXX_Debug.json" CXX_AND_DEBUG)
-  check_build_database("export-build-database-imported" "build_database_Debug.json" JUST_DEBUG)
-  check_build_database("export-build-database-imported" "CMakeFiles/use_import_interfaces.dir/Debug/CXX_build_database.json" JUST_TARGET_DEBUG)
-
-  check_build_database("export-build-database-imported" "build_database_CXX_Release.json" CXX_AND_RELEASE)
-  check_build_database("export-build-database-imported" "build_database_Release.json" JUST_RELEASE)
-  check_build_database("export-build-database-imported" "CMakeFiles/use_import_interfaces.dir/Release/CXX_build_database.json" JUST_TARGET_RELEASE)
-else ()
-  check_build_database("export-build-database-imported" "build_database_CXX.json" JUST_CXX)
-
-  check_build_database("export-build-database-imported" "CMakeFiles/use_import_interfaces.dir/CXX_build_database.json" JUST_TARGET)
-endif ()
-
-string(REPLACE ";" "\n  " RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}")
diff --git a/Tests/RunCMake/CXXModules/examples/import-modules-export-build-database-target-cmake_build_database/CXX/Debug-check.cmake b/Tests/RunCMake/CXXModules/examples/import-modules-export-build-database-target-cmake_build_database/CXX/Debug-check.cmake
deleted file mode 100644
index cf01237..0000000
--- a/Tests/RunCMake/CXXModules/examples/import-modules-export-build-database-target-cmake_build_database/CXX/Debug-check.cmake
+++ /dev/null
@@ -1,19 +0,0 @@
-include("${CMAKE_CURRENT_LIST_DIR}/../../build-database-check.cmake")
-set(item_filter "-ifcOnly")
-
-check_build_database("export-build-database-imported" "build_database.json" NO_EXIST)
-check_build_database("export-build-database-imported" "build_database_CXX.json" NO_EXIST)
-
-if (RunCMake_GENERATOR_IS_MULTI_CONFIG)
-  check_build_database("export-build-database-imported" "build_database_CXX_Debug.json" CXX_AND_DEBUG)
-  check_build_database("export-build-database-imported" "build_database_Debug.json" NO_EXIST)
-  check_build_database("export-build-database-imported" "CMakeFiles/use_import_interfaces.dir/Debug/CXX_build_database.json" JUST_TARGET_DEBUG)
-
-  check_build_database("export-build-database-imported" "build_database_CXX_Release.json" NO_EXIST)
-  check_build_database("export-build-database-imported" "build_database_Release.json" NO_EXIST)
-  check_build_database("export-build-database-imported" "CMakeFiles/use_import_interfaces.dir/Release/CXX_build_database.json" NO_EXIST)
-else ()
-  check_build_database("export-build-database-imported" "CMakeFiles/use_import_interfaces.dir/CXX_build_database.json" JUST_TARGET)
-endif ()
-
-string(REPLACE ";" "\n  " RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}")
diff --git a/Tests/RunCMake/CXXModules/examples/import-modules-export-build-database-target-cmake_build_database/CXX/Release-Release-check.cmake b/Tests/RunCMake/CXXModules/examples/import-modules-export-build-database-target-cmake_build_database/CXX/Release-Release-check.cmake
deleted file mode 100644
index 7e231ea..0000000
--- a/Tests/RunCMake/CXXModules/examples/import-modules-export-build-database-target-cmake_build_database/CXX/Release-Release-check.cmake
+++ /dev/null
@@ -1,19 +0,0 @@
-include("${CMAKE_CURRENT_LIST_DIR}/../../build-database-check.cmake")
-set(item_filter "-ifcOnly")
-
-check_build_database("export-build-database-imported" "build_database.json" NO_EXIST)
-check_build_database("export-build-database-imported" "build_database_CXX.json" NO_EXIST)
-
-if (RunCMake_GENERATOR_IS_MULTI_CONFIG)
-  check_build_database("export-build-database-imported" "build_database_CXX_Debug.json" CXX_AND_DEBUG)
-  check_build_database("export-build-database-imported" "build_database_Debug.json" JUST_DEBUG)
-  check_build_database("export-build-database-imported" "CMakeFiles/use_import_interfaces.dir/Debug/CXX_build_database.json" JUST_TARGET_DEBUG)
-
-  check_build_database("export-build-database-imported" "build_database_CXX_Release.json" CXX_AND_RELEASE)
-  check_build_database("export-build-database-imported" "build_database_Release.json" NO_EXIST)
-  check_build_database("export-build-database-imported" "CMakeFiles/use_import_interfaces.dir/Release/CXX_build_database.json" JUST_TARGET_RELEASE)
-else ()
-  check_build_database("export-build-database-imported" "CMakeFiles/use_import_interfaces.dir/CXX_build_database.json" JUST_TARGET)
-endif ()
-
-string(REPLACE ";" "\n  " RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}")
diff --git a/Tests/RunCMake/CXXModules/examples/import-modules-export-build-database-target-cmake_build_database/Debug-check.cmake b/Tests/RunCMake/CXXModules/examples/import-modules-export-build-database-target-cmake_build_database/Debug-check.cmake
deleted file mode 100644
index 876888c..0000000
--- a/Tests/RunCMake/CXXModules/examples/import-modules-export-build-database-target-cmake_build_database/Debug-check.cmake
+++ /dev/null
@@ -1,19 +0,0 @@
-include("${CMAKE_CURRENT_LIST_DIR}/../build-database-check.cmake")
-set(item_filter "-ifcOnly")
-
-check_build_database("export-build-database-imported" "build_database.json" NO_EXIST)
-check_build_database("export-build-database-imported" "build_database_CXX.json" NO_EXIST)
-
-if (RunCMake_GENERATOR_IS_MULTI_CONFIG)
-  check_build_database("export-build-database-imported" "build_database_CXX_Debug.json" CXX_AND_DEBUG)
-  check_build_database("export-build-database-imported" "build_database_Debug.json" JUST_DEBUG)
-  check_build_database("export-build-database-imported" "CMakeFiles/use_import_interfaces.dir/Debug/CXX_build_database.json" JUST_TARGET_DEBUG)
-
-  check_build_database("export-build-database-imported" "build_database_CXX_Release.json" NO_EXIST)
-  check_build_database("export-build-database-imported" "build_database_Release.json" NO_EXIST)
-  check_build_database("export-build-database-imported" "CMakeFiles/use_import_interfaces.dir/Release/CXX_build_database.json" NO_EXIST)
-else ()
-  check_build_database("export-build-database-imported" "CMakeFiles/use_import_interfaces.dir/CXX_build_database.json" JUST_TARGET)
-endif ()
-
-string(REPLACE ";" "\n  " RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}")
diff --git a/Tests/RunCMake/CXXModules/examples/import-modules-export-build-database-target-cmake_build_database/Release-check.cmake b/Tests/RunCMake/CXXModules/examples/import-modules-export-build-database-target-cmake_build_database/Release-check.cmake
deleted file mode 100644
index 94edc3b..0000000
--- a/Tests/RunCMake/CXXModules/examples/import-modules-export-build-database-target-cmake_build_database/Release-check.cmake
+++ /dev/null
@@ -1,19 +0,0 @@
-include("${CMAKE_CURRENT_LIST_DIR}/../build-database-check.cmake")
-set(item_filter "-ifcOnly")
-
-check_build_database("export-build-database-imported" "build_database.json" NO_EXIST)
-check_build_database("export-build-database-imported" "build_database_CXX.json" JUST_CXX)
-
-if (RunCMake_GENERATOR_IS_MULTI_CONFIG)
-  check_build_database("export-build-database-imported" "build_database_CXX_Debug.json" CXX_AND_DEBUG)
-  check_build_database("export-build-database-imported" "build_database_Debug.json" JUST_DEBUG)
-  check_build_database("export-build-database-imported" "CMakeFiles/use_import_interfaces.dir/Debug/CXX_build_database.json" JUST_TARGET_DEBUG)
-
-  check_build_database("export-build-database-imported" "build_database_CXX_Release.json" CXX_AND_RELEASE)
-  check_build_database("export-build-database-imported" "build_database_Release.json" JUST_RELEASE)
-  check_build_database("export-build-database-imported" "CMakeFiles/use_import_interfaces.dir/Release/CXX_build_database.json" JUST_TARGET_RELEASE)
-else ()
-  check_build_database("export-build-database-imported" "CMakeFiles/use_import_interfaces.dir/CXX_build_database.json" JUST_TARGET)
-endif ()
-
-string(REPLACE ";" "\n  " RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}")
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-install-stderr.txt b/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-install-stderr.txt
deleted file mode 100644
index 583556f..0000000
--- a/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-install-stderr.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-CMake Warning \(dev\) at .*/Modules/Compiler/CMakeCommonCompilerMacros\.cmake:[0-9]* \(cmake_language\):
-  CMake's support for `import std;` in C\+\+23 and newer is experimental\.  It
-  is meant only for experimentation and feedback to CMake developers\.
-Call Stack \(most recent call first\):
-  .*/Modules/CMakeDetermineCompilerSupport\.cmake:[0-9]* \(cmake_create_cxx_import_std\)
-  .*/Modules/CMakeTestCXXCompiler\.cmake:[0-9]* \(CMAKE_DETERMINE_COMPILER_SUPPORT\)
-  CMakeLists\.txt:[0-9]* \(project\)
-This warning is for project developers\.  Use -Wno-dev to suppress it\.
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-no-std-property-stderr.txt b/Tests/RunCMake/CXXModules/examples/import-std-no-std-property-stderr.txt
deleted file mode 100644
index 583556f..0000000
--- a/Tests/RunCMake/CXXModules/examples/import-std-no-std-property-stderr.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-CMake Warning \(dev\) at .*/Modules/Compiler/CMakeCommonCompilerMacros\.cmake:[0-9]* \(cmake_language\):
-  CMake's support for `import std;` in C\+\+23 and newer is experimental\.  It
-  is meant only for experimentation and feedback to CMake developers\.
-Call Stack \(most recent call first\):
-  .*/Modules/CMakeDetermineCompilerSupport\.cmake:[0-9]* \(cmake_create_cxx_import_std\)
-  .*/Modules/CMakeTestCXXCompiler\.cmake:[0-9]* \(CMAKE_DETERMINE_COMPILER_SUPPORT\)
-  CMakeLists\.txt:[0-9]* \(project\)
-This warning is for project developers\.  Use -Wno-dev to suppress it\.
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-not-in-export-build-stderr.txt b/Tests/RunCMake/CXXModules/examples/import-std-not-in-export-build-stderr.txt
deleted file mode 100644
index 583556f..0000000
--- a/Tests/RunCMake/CXXModules/examples/import-std-not-in-export-build-stderr.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-CMake Warning \(dev\) at .*/Modules/Compiler/CMakeCommonCompilerMacros\.cmake:[0-9]* \(cmake_language\):
-  CMake's support for `import std;` in C\+\+23 and newer is experimental\.  It
-  is meant only for experimentation and feedback to CMake developers\.
-Call Stack \(most recent call first\):
-  .*/Modules/CMakeDetermineCompilerSupport\.cmake:[0-9]* \(cmake_create_cxx_import_std\)
-  .*/Modules/CMakeTestCXXCompiler\.cmake:[0-9]* \(CMAKE_DETERMINE_COMPILER_SUPPORT\)
-  CMakeLists\.txt:[0-9]* \(project\)
-This warning is for project developers\.  Use -Wno-dev to suppress it\.
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-not-in-export-build/main.cxx b/Tests/RunCMake/CXXModules/examples/import-std-not-in-export-build/main.cxx
deleted file mode 100644
index a6dd8d8..0000000
--- a/Tests/RunCMake/CXXModules/examples/import-std-not-in-export-build/main.cxx
+++ /dev/null
@@ -1,6 +0,0 @@
-import uses_std;
-
-int main(int argc, char* argv[])
-{
-  return f();
-}
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-not-in-export-install-stderr.txt b/Tests/RunCMake/CXXModules/examples/import-std-not-in-export-install-stderr.txt
deleted file mode 100644
index 583556f..0000000
--- a/Tests/RunCMake/CXXModules/examples/import-std-not-in-export-install-stderr.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-CMake Warning \(dev\) at .*/Modules/Compiler/CMakeCommonCompilerMacros\.cmake:[0-9]* \(cmake_language\):
-  CMake's support for `import std;` in C\+\+23 and newer is experimental\.  It
-  is meant only for experimentation and feedback to CMake developers\.
-Call Stack \(most recent call first\):
-  .*/Modules/CMakeDetermineCompilerSupport\.cmake:[0-9]* \(cmake_create_cxx_import_std\)
-  .*/Modules/CMakeTestCXXCompiler\.cmake:[0-9]* \(CMAKE_DETERMINE_COMPILER_SUPPORT\)
-  CMakeLists\.txt:[0-9]* \(project\)
-This warning is for project developers\.  Use -Wno-dev to suppress it\.
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-not-in-export-install/main.cxx b/Tests/RunCMake/CXXModules/examples/import-std-not-in-export-install/main.cxx
deleted file mode 100644
index a6dd8d8..0000000
--- a/Tests/RunCMake/CXXModules/examples/import-std-not-in-export-install/main.cxx
+++ /dev/null
@@ -1,6 +0,0 @@
-import uses_std;
-
-int main(int argc, char* argv[])
-{
-  return f();
-}
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-stderr.txt b/Tests/RunCMake/CXXModules/examples/import-std-stderr.txt
deleted file mode 100644
index 583556f..0000000
--- a/Tests/RunCMake/CXXModules/examples/import-std-stderr.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-CMake Warning \(dev\) at .*/Modules/Compiler/CMakeCommonCompilerMacros\.cmake:[0-9]* \(cmake_language\):
-  CMake's support for `import std;` in C\+\+23 and newer is experimental\.  It
-  is meant only for experimentation and feedback to CMake developers\.
-Call Stack \(most recent call first\):
-  .*/Modules/CMakeDetermineCompilerSupport\.cmake:[0-9]* \(cmake_create_cxx_import_std\)
-  .*/Modules/CMakeTestCXXCompiler\.cmake:[0-9]* \(CMAKE_DETERMINE_COMPILER_SUPPORT\)
-  CMakeLists\.txt:[0-9]* \(project\)
-This warning is for project developers\.  Use -Wno-dev to suppress it\.
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-transitive-not-in-export-build-stderr.txt b/Tests/RunCMake/CXXModules/examples/import-std-transitive-not-in-export-build-stderr.txt
deleted file mode 100644
index 583556f..0000000
--- a/Tests/RunCMake/CXXModules/examples/import-std-transitive-not-in-export-build-stderr.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-CMake Warning \(dev\) at .*/Modules/Compiler/CMakeCommonCompilerMacros\.cmake:[0-9]* \(cmake_language\):
-  CMake's support for `import std;` in C\+\+23 and newer is experimental\.  It
-  is meant only for experimentation and feedback to CMake developers\.
-Call Stack \(most recent call first\):
-  .*/Modules/CMakeDetermineCompilerSupport\.cmake:[0-9]* \(cmake_create_cxx_import_std\)
-  .*/Modules/CMakeTestCXXCompiler\.cmake:[0-9]* \(CMAKE_DETERMINE_COMPILER_SUPPORT\)
-  CMakeLists\.txt:[0-9]* \(project\)
-This warning is for project developers\.  Use -Wno-dev to suppress it\.
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-transitive-not-in-export-install-stderr.txt b/Tests/RunCMake/CXXModules/examples/import-std-transitive-not-in-export-install-stderr.txt
deleted file mode 100644
index 583556f..0000000
--- a/Tests/RunCMake/CXXModules/examples/import-std-transitive-not-in-export-install-stderr.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-CMake Warning \(dev\) at .*/Modules/Compiler/CMakeCommonCompilerMacros\.cmake:[0-9]* \(cmake_language\):
-  CMake's support for `import std;` in C\+\+23 and newer is experimental\.  It
-  is meant only for experimentation and feedback to CMake developers\.
-Call Stack \(most recent call first\):
-  .*/Modules/CMakeDetermineCompilerSupport\.cmake:[0-9]* \(cmake_create_cxx_import_std\)
-  .*/Modules/CMakeTestCXXCompiler\.cmake:[0-9]* \(CMAKE_DETERMINE_COMPILER_SUPPORT\)
-  CMakeLists\.txt:[0-9]* \(project\)
-This warning is for project developers\.  Use -Wno-dev to suppress it\.
diff --git a/Tests/RunCMake/CXXModules/examples/public-req-private-build-result.txt b/Tests/RunCMake/CXXModules/examples/public-req-private-build-result.txt
deleted file mode 100644
index d00491f..0000000
--- a/Tests/RunCMake/CXXModules/examples/public-req-private-build-result.txt
+++ /dev/null
@@ -1 +0,0 @@
-1
diff --git a/Tests/RunCMake/CXXModules/examples/public-req-private-build-stdout.txt b/Tests/RunCMake/CXXModules/examples/public-req-private-build-stdout.txt
deleted file mode 100644
index def33fa..0000000
--- a/Tests/RunCMake/CXXModules/examples/public-req-private-build-stdout.txt
+++ /dev/null
@@ -1 +0,0 @@
-CMake Error: Public C\+\+ module source `.*/Tests/RunCMake/CXXModules/examples/public-req-private/pub\.cxx` requires the `priv` C\+\+ module which is provided by a private source
diff --git a/Tests/RunCMake/CXXModulesCompile/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/CMakeLists.txt
new file mode 100644
index 0000000..913371f
--- /dev/null
+++ b/Tests/RunCMake/CXXModulesCompile/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 3.23)
+project(${RunCMake_TEST} NONE)
+
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CXXModulesCompile/Inspect.cmake b/Tests/RunCMake/CXXModulesCompile/Inspect.cmake
new file mode 100644
index 0000000..fb8b3e2
--- /dev/null
+++ b/Tests/RunCMake/CXXModulesCompile/Inspect.cmake
@@ -0,0 +1,23 @@
+enable_language(CXX)
+
+set(info "")
+
+# See `Modules/Compiler/MSVC-CXX.cmake` for this. If there is explicitly no
+# default, the feature list is populated to be everything.
+if (DEFINED CMAKE_CXX_STANDARD_DEFAULT AND
+    CMAKE_CXX_STANDARD_DEFAULT STREQUAL "")
+  set(CMAKE_CXX_COMPILE_FEATURES "")
+endif ()
+
+# Forward information about the C++ compile features.
+string(APPEND info "\
+set(CMAKE_CXX_COMPILE_FEATURES \"${CMAKE_CXX_COMPILE_FEATURES}\")
+set(CMAKE_MAKE_PROGRAM \"${CMAKE_MAKE_PROGRAM}\")
+set(CMAKE_CXX_COMPILER_VERSION \"${CMAKE_CXX_COMPILER_VERSION}\")
+set(CMAKE_CXX_OUTPUT_EXTENSION \"${CMAKE_CXX_OUTPUT_EXTENSION}\")
+set(CMAKE_CXX20_STANDARD_COMPILE_OPTION \"${CMAKE_CXX20_STANDARD_COMPILE_OPTION}\")
+set(CMAKE_CXX_COMPILER_FRONTEND_VARIANT \"${CMAKE_CXX_COMPILER_FRONTEND_VARIANT}\")
+set(CMAKE_CXX_MODULE_MAP_FORMAT \"${CMAKE_CXX_MODULE_MAP_FORMAT}\")
+")
+
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/info.cmake" "${info}")
diff --git a/Tests/RunCMake/CXXModulesCompile/RunCMakeTest.cmake b/Tests/RunCMake/CXXModulesCompile/RunCMakeTest.cmake
new file mode 100644
index 0000000..69beb79
--- /dev/null
+++ b/Tests/RunCMake/CXXModulesCompile/RunCMakeTest.cmake
@@ -0,0 +1,372 @@
+include(RunCMake)
+
+set(stdlib_custom_json)
+if (CMake_TEST_CXX_STDLIB_MODULES_JSON)
+  list(APPEND stdlib_custom_json
+    -DCMAKE_CXX_STDLIB_MODULES_JSON=${CMake_TEST_CXX_STDLIB_MODULES_JSON})
+endif ()
+
+run_cmake(Inspect ${stdlib_custom_json})
+include("${RunCMake_BINARY_DIR}/Inspect-build/info.cmake")
+
+if (RunCMake_GENERATOR MATCHES "Ninja")
+  execute_process(
+    COMMAND "${CMAKE_MAKE_PROGRAM}" --version
+    RESULT_VARIABLE res
+    OUTPUT_VARIABLE ninja_version
+    ERROR_VARIABLE err
+    OUTPUT_STRIP_TRAILING_WHITESPACE
+    ERROR_STRIP_TRAILING_WHITESPACE)
+
+  if (res)
+    message(WARNING
+      "Failed to determine `ninja` version: ${err}")
+    set(ninja_version "0")
+  endif ()
+endif ()
+
+set(generator_supports_cxx_modules 0)
+if (RunCMake_GENERATOR MATCHES "Ninja" AND
+    ninja_version VERSION_GREATER_EQUAL "1.11" AND
+    "cxx_std_20" IN_LIST CMAKE_CXX_COMPILE_FEATURES)
+  set(generator_supports_cxx_modules 1)
+endif ()
+
+if (RunCMake_GENERATOR MATCHES "Visual Studio" AND
+    CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "19.34")
+  set(generator_supports_cxx_modules 1)
+endif ()
+
+# Test behavior when the generator does not support C++20 modules.
+if (NOT generator_supports_cxx_modules)
+  # Bail; the remaining tests require the generator to successfully generate
+  # with C++20 modules in the source list.
+  return ()
+endif ()
+
+# This performs actual compilation tests; avoid it when not requested.
+if (NOT CMake_TEST_MODULE_COMPILATION)
+  return ()
+endif ()
+
+# Module compilation features:
+# Compiler-based:
+# - `named`: basic support for named modules is available
+# - `shared`: shared libraries are supported
+# - `partitions`: module partitions are supported
+# - `internal_partitions`: internal module partitions are supported
+# - `bmionly`: the compiler supports BMI-only builds
+# - `import_std23`: the compiler supports `import std` for C++23
+#
+# Generator-based:
+# - `compile_commands`: the generator supports `compile_commands.json`
+# - `collation`: the generator supports module collation features
+# - `export_bmi`: the generator supports exporting BMIs
+# - `ninja`: a `ninja` binary is available to perform `Ninja`-only testing
+#   (assumed if the generator matches `Ninja`).
+string(REPLACE "," ";" CMake_TEST_MODULE_COMPILATION "${CMake_TEST_MODULE_COMPILATION}")
+if (RunCMake_GENERATOR MATCHES "Ninja")
+  list(APPEND CMake_TEST_MODULE_COMPILATION
+    "ninja")
+endif ()
+
+function (run_cxx_module_test directory)
+  set(test_name "${directory}")
+  if (NOT ARGN STREQUAL "")
+    list(POP_FRONT ARGN test_name)
+  endif ()
+
+  set(RunCMake_TEST_SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}/${directory}")
+  set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/${test_name}-build")
+
+  if (RunCMake_GENERATOR_IS_MULTI_CONFIG)
+    set(RunCMake_TEST_OPTIONS -DCMAKE_CONFIGURATION_TYPES=Debug)
+  else ()
+    set(RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Debug)
+  endif ()
+  if (directory MATCHES "imp-std")
+    list(APPEND RunCMake_TEST_OPTIONS
+      ${stdlib_custom_json})
+  endif ()
+
+  if (RunCMake_CXXModules_INSTALL)
+    set(prefix "${RunCMake_BINARY_DIR}/${test_name}-install")
+    file(REMOVE_RECURSE "${prefix}")
+    list(APPEND RunCMake_TEST_OPTIONS
+      "-DCMAKE_INSTALL_PREFIX=${prefix}")
+  endif ()
+
+  list(APPEND RunCMake_TEST_OPTIONS
+    "-DCMake_TEST_MODULE_COMPILATION_RULES=${CMake_TEST_MODULE_COMPILATION_RULES}"
+    ${ARGN})
+  run_cmake("${test_name}")
+  set(RunCMake_TEST_NO_CLEAN 1)
+  if (RunCMake_CXXModules_TARGET)
+    run_cmake_command("${test_name}-build" "${CMAKE_COMMAND}" --build . --config Debug --target "${RunCMake_CXXModules_TARGET}")
+  else ()
+    run_cmake_command("${test_name}-build" "${CMAKE_COMMAND}" --build . --config Debug)
+    foreach (RunCMake_CXXModules_TARGET IN LISTS RunCMake_CXXModules_TARGETS)
+      set(RunCMake_CXXModules_CONFIG "Debug")
+      set(RunCMake_CXXModules_NAME_SUFFIX "")
+      if (RunCMake_CXXModules_TARGET MATCHES "(.*)@(.*)")
+        set(RunCMake_CXXModules_TARGET "${CMAKE_MATCH_1}")
+        set(RunCMake_CXXModules_CONFIG "${CMAKE_MATCH_2}")
+        set(RunCMake_CXXModules_NAME_SUFFIX "-${RunCMake_CXXModules_CONFIG}")
+      endif ()
+      run_cmake_command("${test_name}-target-${RunCMake_CXXModules_TARGET}${RunCMake_CXXModules_NAME_SUFFIX}" "${CMAKE_COMMAND}" --build . --target "${RunCMake_CXXModules_TARGET}" --config "${RunCMake_CXXModules_CONFIG}")
+    endforeach ()
+  endif ()
+  if (RunCMake_CXXModules_INSTALL)
+    run_cmake_command("${test_name}-install" "${CMAKE_COMMAND}" --build . --target install --config Debug)
+  endif ()
+  if (NOT RunCMake_CXXModules_NO_TEST)
+    run_cmake_command("${test_name}-test" "${CMAKE_CTEST_COMMAND}" -C Debug --output-on-failure)
+  endif ()
+  if (RunCMake_CXXModules_REBUILD)
+    execute_process(COMMAND ${CMAKE_COMMAND} -E sleep 1.125) # handle 1s resolution
+    include("${RunCMake_TEST_SOURCE_DIR}/pre-rebuild.cmake")
+    execute_process(COMMAND ${CMAKE_COMMAND} -E sleep 1.125) # handle 1s resolution
+    run_cmake_command("${test_name}-rebuild" "${CMAKE_COMMAND}" --build . --config Debug)
+  endif ()
+endfunction ()
+
+function (run_cxx_module_test_target directory target)
+  set(RunCMake_CXXModules_TARGET "${target}")
+  set(RunCMake_CXXModules_NO_TEST 1)
+  run_cxx_module_test("${directory}" ${ARGN})
+endfunction ()
+
+function (run_cxx_module_test_rebuild directory)
+  set(RunCMake_CXXModules_INSTALL 0)
+  set(RunCMake_CXXModules_NO_TEST 1)
+  set(RunCMake_CXXModules_REBUILD 1)
+  run_cxx_module_test("${directory}" ${ARGN})
+endfunction ()
+
+if (RunCMake_GENERATOR MATCHES "Ninja")
+  if (RunCMake_GENERATOR_IS_MULTI_CONFIG)
+    set(ninja_cmp0154_target "CMakeFiles/ninja_cmp0154.dir/Debug/unrelated.cxx${CMAKE_CXX_OUTPUT_EXTENSION}")
+  else ()
+    set(ninja_cmp0154_target "CMakeFiles/ninja_cmp0154.dir/unrelated.cxx${CMAKE_CXX_OUTPUT_EXTENSION}")
+  endif ()
+  run_cxx_module_test_target(ninja-cmp0154 "${ninja_cmp0154_target}")
+endif ()
+
+run_cxx_module_test(scan-with-pch)
+
+# Tests which use named modules.
+if ("named" IN_LIST CMake_TEST_MODULE_COMPILATION)
+  run_cxx_module_test(simple)
+  run_cxx_module_test(file-sets-with-dot)
+  run_cxx_module_test(vs-without-flags)
+  run_cxx_module_test(library library-static -DBUILD_SHARED_LIBS=OFF)
+  run_cxx_module_test(unity-build)
+  run_cxx_module_test(object-library)
+  run_cxx_module_test(generated)
+  run_cxx_module_test(deep-chain)
+  run_cxx_module_test(non-trivial-collation-order)
+  run_cxx_module_test(non-trivial-collation-order-randomized)
+  run_cxx_module_test(duplicate)
+  set(RunCMake_CXXModules_NO_TEST 1)
+  run_cxx_module_test(imp-from-object)
+  run_cxx_module_test(circular)
+  run_cxx_module_test(try-compile)
+  run_cxx_module_test(try-run)
+  unset(RunCMake_CXXModules_NO_TEST)
+  run_cxx_module_test(same-src-name)
+  run_cxx_module_test(scan_props)
+  run_cxx_module_test(target-objects)
+
+  if ("cxx_std_23" IN_LIST CMAKE_CXX_COMPILE_FEATURES AND
+      "import_std23" IN_LIST CMake_TEST_MODULE_COMPILATION)
+    run_cxx_module_test(imp-std)
+    set(RunCMake_CXXModules_NO_TEST 1)
+    run_cxx_module_test(imp-std-no-std-prop)
+    unset(RunCMake_CXXModules_NO_TEST)
+    run_cxx_module_test(imp-std-exp-no-std-build)
+    set(RunCMake_CXXModules_INSTALL 1)
+    run_cxx_module_test(imp-std-exp-no-std-install)
+    unset(RunCMake_CXXModules_INSTALL)
+
+    if ("collation" IN_LIST CMake_TEST_MODULE_COMPILATION)
+      run_cxx_module_test(imp-std-not-in-exp-build)
+      run_cxx_module_test(imp-std-trans imp-std-trans-not-in-exp-build "-DCMAKE_PREFIX_PATH=${RunCMake_BINARY_DIR}/imp-std-not-in-exp-build-build")
+
+      set(RunCMake_CXXModules_INSTALL 1)
+      run_cxx_module_test(imp-std-not-in-exp-install)
+      unset(RunCMake_CXXModules_INSTALL)
+      run_cxx_module_test(imp-std-trans imp-std-trans-not-in-exp-install "-DCMAKE_PREFIX_PATH=${RunCMake_BINARY_DIR}/imp-std-not-in-exp-install-install")
+
+      run_cxx_module_test(imp-std-trans imp-std-trans-exp-no-std-build "-DCMAKE_PREFIX_PATH=${RunCMake_BINARY_DIR}/imp-std-exp-no-std-build-build" -DEXPORT_NO_STD=1)
+      run_cxx_module_test(imp-std-trans imp-std-trans-exp-no-std-install "-DCMAKE_PREFIX_PATH=${RunCMake_BINARY_DIR}/imp-std-exp-no-std-install-install" -DEXPORT_NO_STD=1)
+    endif ()
+  endif ()
+endif ()
+
+# Tests which require compile commands support.
+if ("compile_commands" IN_LIST CMake_TEST_MODULE_COMPILATION)
+  run_cxx_module_test(exp-compile-commands)
+endif ()
+
+macro (setup_export_build_database_targets)
+  set(RunCMake_CXXModules_TARGETS
+    cmake_build_database-CXX
+    cmake_build_database)
+
+  if (RunCMake_GENERATOR_IS_MULTI_CONFIG)
+    list(INSERT RunCMake_CXXModules_TARGETS 0
+      cmake_build_database-CXX-Debug
+      cmake_build_database-Debug
+      # Other config targets.
+      cmake_build_database-CXX-Release@Release
+      cmake_build_database-Release@Release)
+  endif ()
+endmacro ()
+
+# Tests which require build database support.
+if ("build_database" IN_LIST CMake_TEST_MODULE_COMPILATION)
+  setup_export_build_database_targets()
+  set(RunCMake_CXXModules_NO_TEST 1)
+
+  run_cxx_module_test(exp-builddb)
+
+  unset(RunCMake_CXXModules_NO_TEST)
+  unset(RunCMake_CXXModules_TARGETS)
+endif ()
+
+# Tests which require collation work.
+if ("collation" IN_LIST CMake_TEST_MODULE_COMPILATION)
+  run_cxx_module_test(duplicate-sources)
+  run_cxx_module_test(public-req-priv)
+  set(RunCMake_CXXModules_NO_TEST 1)
+  run_cxx_module_test(req-priv-other-target)
+  unset(RunCMake_CXXModules_NO_TEST)
+  run_cxx_module_test_rebuild(depchain-modmap)
+  run_cxx_module_test_rebuild(depchain-mods-json-file)
+  if (RunCMake_GENERATOR MATCHES "Ninja")
+    run_cxx_module_test_rebuild(depchain-collation-restat)
+  endif ()
+endif ()
+
+# Tests which use named modules in shared libraries.
+if ("shared" IN_LIST CMake_TEST_MODULE_COMPILATION)
+  run_cxx_module_test(library library-shared -DBUILD_SHARED_LIBS=ON)
+endif ()
+
+# Tests which use partitions.
+if ("partitions" IN_LIST CMake_TEST_MODULE_COMPILATION)
+  run_cxx_module_test(partitions)
+endif ()
+
+# Tests which use internal partitions.
+if ("internal_partitions" IN_LIST CMake_TEST_MODULE_COMPILATION)
+  run_cxx_module_test(internal-partitions)
+endif ()
+
+function (run_cxx_module_import_test type name)
+  set(RunCMake_CXXModules_INSTALL 0)
+
+  if ("EXPORT_BUILD_DATABASE" IN_LIST ARGN)
+    list(REMOVE_ITEM ARGN EXPORT_BUILD_DATABASE)
+    list(APPEND ARGN -DCMAKE_EXPORT_BUILD_DATABASE=1)
+  endif ()
+
+  run_cxx_module_test(imp-mods "imp-mods-${name}" "-DCMAKE_PREFIX_PATH=${RunCMake_BINARY_DIR}/${name}-${type}" ${ARGN})
+endfunction ()
+
+# Tests which install BMIs
+if ("export_bmi" IN_LIST CMake_TEST_MODULE_COMPILATION)
+  run_cxx_module_test(exp-iface-no-props-build)
+  run_cxx_module_test(exp-iface-build)
+  run_cxx_module_test(exp-incdirs-build)
+  run_cxx_module_test(exp-incdirs-old-cmake-build)
+  run_cxx_module_test(exp-usage-build)
+  run_cxx_module_test(exp-bmi-and-iface-build)
+  run_cxx_module_test(exp-command-sepdir-build)
+  run_cxx_module_test(exp-trans-targets-build)
+  run_cxx_module_test(exp-trans-mods1-build)
+  run_cxx_module_test(exp-trans-mods-build exp-trans-mods-build "-DCMAKE_PREFIX_PATH=${RunCMake_BINARY_DIR}/exp-trans-mods1-build-build" )
+  run_cxx_module_test(exp-with-headers-build)
+
+  if ("collation" IN_LIST CMake_TEST_MODULE_COMPILATION AND
+      "bmionly" IN_LIST CMake_TEST_MODULE_COMPILATION)
+    run_cxx_module_import_test(build exp-iface-build)
+    run_cxx_module_import_test(build exp-iface-no-props-build -DNO_PROPERTIES=1)
+    run_cxx_module_import_test(build exp-incdirs-build -DINCLUDE_PROPERTIES=1)
+    run_cxx_module_import_test(build exp-bmi-and-iface-build -DWITH_BMIS=1)
+    run_cxx_module_import_test(build exp-command-sepdir-build -DEXPORT_COMMAND_SEPDIR=1)
+    run_cxx_module_import_test(build exp-trans-targets-build -DTRANSITIVE_TARGETS=1)
+    run_cxx_module_import_test(build exp-trans-mods-build -DTRANSITIVE_MODULES=1)
+    run_cxx_module_import_test(build exp-with-headers-build -DWITH_HEADERS=1)
+
+    if ("build_database" IN_LIST CMake_TEST_MODULE_COMPILATION)
+      setup_export_build_database_targets()
+
+      run_cxx_module_import_test(build exp-builddb -DBUILD_DATABASE=1 EXPORT_BUILD_DATABASE)
+
+      unset(RunCMake_CXXModules_TARGETS)
+    endif ()
+  endif ()
+endif ()
+
+# All of the following tests perform installation.
+set(RunCMake_CXXModules_INSTALL 1)
+
+# Tests which install BMIs
+if ("install_bmi" IN_LIST CMake_TEST_MODULE_COMPILATION)
+  run_cxx_module_test(install-bmi)
+  run_cxx_module_test(install-bmi-and-ifaces)
+
+  if ("export_bmi" IN_LIST CMake_TEST_MODULE_COMPILATION)
+    run_cxx_module_test(exp-iface-no-props-install)
+    run_cxx_module_test(exp-iface-install)
+    run_cxx_module_test(exp-incdirs-install)
+    run_cxx_module_test(exp-incdirs-old-cmake-install)
+    run_cxx_module_test(exp-usage-install)
+    run_cxx_module_test(exp-bmi-and-iface-install)
+    run_cxx_module_test(exp-command-sepdir-install)
+    run_cxx_module_test(exp-trans-targets-install)
+    run_cxx_module_test(exp-trans-mods1-install)
+    run_cxx_module_test(exp-trans-mods-install exp-trans-mods-install "-DCMAKE_PREFIX_PATH=${RunCMake_BINARY_DIR}/exp-trans-mods1-install-install" )
+    run_cxx_module_test(exp-with-headers-install)
+
+    if ("collation" IN_LIST CMake_TEST_MODULE_COMPILATION AND
+        "bmionly" IN_LIST CMake_TEST_MODULE_COMPILATION)
+      run_cxx_module_import_test(install exp-iface-install)
+      run_cxx_module_import_test(install exp-iface-no-props-install -DNO_PROPERTIES=1)
+      run_cxx_module_import_test(install exp-incdirs-install -DINCLUDE_PROPERTIES=1)
+      run_cxx_module_import_test(install exp-bmi-and-iface-install -DWITH_BMIS=1)
+      run_cxx_module_import_test(install exp-command-sepdir-install -DEXPORT_COMMAND_SEPDIR=1)
+      run_cxx_module_import_test(install exp-trans-targets-install -DTRANSITIVE_TARGETS=1)
+      run_cxx_module_import_test(install exp-trans-mods-install -DTRANSITIVE_MODULES=1)
+      run_cxx_module_import_test(install exp-with-headers-install -DWITH_HEADERS=1)
+    endif ()
+  endif ()
+endif ()
+
+# All remaining tests require a working `Ninja` generator to set up a test case
+# for the current generator.
+if (NOT "ninja" IN_LIST CMake_TEST_MODULE_COMPILATION)
+  return ()
+endif ()
+# All remaining tests require `bmionly` in order to consume from the `ninja`
+# build.
+if (NOT "bmionly" IN_LIST CMake_TEST_MODULE_COMPILATION)
+  return ()
+endif ()
+
+function (run_cxx_module_test_ninja directory)
+  set(RunCMake_GENERATOR "Ninja")
+  set(RunCMake_CXXModules_NO_TEST 1)
+  set(RunCMake_CXXModules_INSTALL 1)
+  # `Ninja` is not a multi-config generator.
+  set(RunCMake_GENERATOR_IS_MULTI_CONFIG 0)
+  run_cxx_module_test("${directory}" "${directory}-ninja" ${ARGN})
+endfunction ()
+
+# Installation happens within `run_cxx_module_test_ninja`.
+set(RunCMake_CXXModules_INSTALL 0)
+
+set(test_set mods-from-ninja)
+run_cxx_module_test_ninja("exp-${test_set}")
+run_cxx_module_test(imp-mods "imp-${test_set}" "-DCMAKE_PREFIX_PATH=${RunCMake_BINARY_DIR}/exp-${test_set}-ninja-install" -DFROM_NINJA=1)
diff --git a/Tests/RunCMake/CXXModules/examples/build-database-check.cmake b/Tests/RunCMake/CXXModulesCompile/build-database-check.cmake
similarity index 97%
rename from Tests/RunCMake/CXXModules/examples/build-database-check.cmake
rename to Tests/RunCMake/CXXModulesCompile/build-database-check.cmake
index 9b440a8..c1cf629 100644
--- a/Tests/RunCMake/CXXModules/examples/build-database-check.cmake
+++ b/Tests/RunCMake/CXXModulesCompile/build-database-check.cmake
@@ -1,4 +1,4 @@
-include("${CMAKE_CURRENT_LIST_DIR}/../check-json.cmake")
+include("${CMAKE_CURRENT_LIST_DIR}/check-json.cmake")
 
 function (check_build_database expect_basename fname component)
   if (component STREQUAL "NO_EXIST")
diff --git a/Tests/RunCMake/CXXModulesCompile/check-json.cmake b/Tests/RunCMake/CXXModulesCompile/check-json.cmake
new file mode 100644
index 0000000..09edc33
--- /dev/null
+++ b/Tests/RunCMake/CXXModulesCompile/check-json.cmake
@@ -0,0 +1,227 @@
+function (json_placeholders in out)
+  string(REPLACE "<CONFIG>" "${CXXModules_config}" in "${in}")
+  string(TOLOWER "${CXXModules_config}" config_lower)
+  string(REPLACE "<CONFIG_LOWER>" "${config_lower}" in "${in}")
+  string(REPLACE "<CONFIG_OTHER>" "${CXXModules_config_other}" in "${in}")
+  string(TOLOWER "${CXXModules_config_other}" config_lower)
+  string(REPLACE "<CONFIG_OTHER_LOWER>" "${config_lower}" in "${in}")
+  if (RunCMake_GENERATOR_IS_MULTI_CONFIG)
+    string(REPLACE "<CONFIG_DIR>" "/${CXXModules_config}" in "${in}")
+    string(REPLACE "<CONFIG_OTHER_DIR>" "/${CXXModules_config_other}" in "${in}")
+  else ()
+    string(REPLACE "<CONFIG_DIR>" "" in "${in}")
+    string(REPLACE "<CONFIG_OTHER_DIR>" "" in "${in}")
+  endif ()
+  if (CMAKE_BUILD_TYPE)
+    string(REPLACE "<CONFIG_FORCE>" "${CXXModules_config}" in "${in}")
+    string(REPLACE "<CONFIG_OTHER_FORCE>" "${CXXModules_config_other}" in "${in}")
+  else ()
+    string(REPLACE "<CONFIG_FORCE>" "noconfig" in "${in}")
+  endif ()
+  string(REPLACE "<SOURCE_DIR>" "${RunCMake_SOURCE_DIR}" in "${in}")
+  string(REPLACE "<BINARY_DIR>" "${RunCMake_TEST_BINARY_DIR}" in "${in}")
+  string(REPLACE "<OBJEXT>" "${CMAKE_CXX_OUTPUT_EXTENSION}" in "${in}")
+  if (CMAKE_CXX_MODULE_MAP_FORMAT STREQUAL "gcc")
+    set(bmiflag "-fmodule-only")
+    set(bmiext "gcm")
+  elseif (CMAKE_CXX_MODULE_MAP_FORMAT STREQUAL "clang")
+    set(bmiflag "--precompile")
+    set(bmiext "pcm")
+  elseif (CMAKE_CXX_MODULE_MAP_FORMAT STREQUAL "msvc")
+    set(bmiflag "-ifcOutput.*")
+    set(bmiext "ifc")
+  endif ()
+  string(REPLACE "<BMI_ONLY_FLAG>" "${bmiflag}" in "${in}")
+  string(REPLACE "<BMIEXT>" ".${bmiext}" in "${in}")
+  set(output_flag "-o")
+  if (CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC")
+    set(output_flag "-Fo")
+  endif ()
+  string(REPLACE "<OUTPUT_FLAG>" "${output_flag}" in "${in}")
+  string(REPLACE "<CXX20_OPTION>" "${CMAKE_CXX20_STANDARD_COMPILE_OPTION}" in "${in}")
+  string(REPLACE "<HEX>" "[0-9a-f]+" in "${in}")
+  string(REPLACE "REGEX:" "" in "${in}")
+  string(REPLACE "PATH:" "" in "${in}")
+  set("${out}" "${in}" PARENT_SCOPE)
+endfunction ()
+
+function (check_json_value path actual_type expect_type actual_value expect_value)
+  if (NOT actual_type STREQUAL expect_type)
+    string(APPEND RunCMake_TEST_FAILED
+      "Type mismatch at:\n ${path}\nexpected:\n ${expect_type}\nactual:\n ${actual_type}\n")
+    set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}" PARENT_SCOPE)
+    return ()
+  endif ()
+
+  if (actual_type STREQUAL NULL)
+    # Nothing to check
+  elseif (actual_type STREQUAL BOOLEAN)
+    if (NOT actual_value STREQUAL expect_value)
+      string(APPEND RunCMake_TEST_FAILED
+        "Boolean mismatch at:\n ${path}\nexpected:\n ${expect_value}\nactual:\n ${actual_value}\n")
+    endif ()
+  elseif (actual_type STREQUAL NUMBER)
+    if (NOT actual_value EQUAL expect_value)
+      string(APPEND RunCMake_TEST_FAILED
+        "Number mismatch at:\n ${path}\nexpected:\n ${expect_value}\nactual:\n ${actual_value}\n")
+    endif ()
+  elseif (actual_type STREQUAL STRING)
+    # Allow some values to be ignored.
+    if (expect_value STREQUAL "<IGNORE>")
+      return ()
+    endif ()
+
+    json_placeholders("${expect_value}" expect_value_expanded)
+    if (expect_value MATCHES "^REGEX:PATH:")
+      string(REPLACE "\\" "/" actual_value_check "${actual_value}")
+      string(REGEX REPLACE "^\"(.*)\"$" "\\1" actual_value_check "${actual_value_check}")
+      if (NOT actual_value_check MATCHES "^${expect_value_expanded}$")
+        string(APPEND RunCMake_TEST_FAILED
+          "String mismatch (path regex) at:\n ${path}\nexpected:\n ^${expect_value_expanded}$\nactual:\n ${actual_value}\n")
+      endif ()
+    elseif (expect_value MATCHES "^REGEX:")
+      if (NOT actual_value MATCHES "^${expect_value_expanded}$")
+        string(APPEND RunCMake_TEST_FAILED
+          "String mismatch (regex) at:\n ${path}\nexpected:\n ^${expect_value_expanded}$\nactual:\n ${actual_value}\n")
+      endif ()
+    elseif (expect_value MATCHES "^PATH:")
+      string(REPLACE "\\" "/" actual_value_check "${actual_value}")
+      string(REGEX REPLACE "^\"(.*)\"$" "\\1" actual_value_check "${actual_value_check}")
+      if (NOT actual_value_check STREQUAL "${expect_value_expanded}")
+        string(APPEND RunCMake_TEST_FAILED
+          "String mismatch (path) at:\n ${path}\nexpected:\n ${expect_value_expanded}\nactual:\n ${actual_value}\n")
+      endif ()
+    elseif (NOT actual_value STREQUAL expect_value_expanded)
+      string(APPEND RunCMake_TEST_FAILED
+        "String mismatch at:\n ${path}\nexpected:\n ${expect_value_expanded}\nactual:\n ${actual_value}\n")
+    endif ()
+  elseif (actual_type STREQUAL ARRAY)
+    check_json_array("${path}" "${actual_value}" "${expect_value}")
+  elseif (actual_type STREQUAL OBJECT)
+    check_json_object("${path}" "${actual_value}" "${expect_value}")
+  endif ()
+
+  set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}" PARENT_SCOPE)
+endfunction ()
+
+# Check that two arrays are the same.
+function (check_json_array path actual expect)
+  if (item_filter)
+    string(JSON iter_len LENGTH "${actual}")
+    set(idx 0)
+    while (idx LESS iter_len)
+      string(JSON type TYPE "${actual}" "${idx}")
+      string(JSON item GET "${actual}" "${idx}")
+      if (type STREQUAL "STRING" AND
+          item MATCHES "${item_filter}")
+        string(JSON actual REMOVE "${actual}" "${idx}")
+        math(EXPR iter_len "${iter_len} - 1")
+      else ()
+        math(EXPR idx "${idx} + 1")
+      endif ()
+    endwhile ()
+  endif ()
+
+  string(JSON actual_len LENGTH "${actual}")
+  string(JSON expect_len LENGTH "${expect}")
+
+  set(iter_len "${actual_len}")
+  if (actual_len LESS expect_len)
+    string(APPEND RunCMake_TEST_FAILED
+      "Missing array items at:\n ${path}\n")
+  elseif (expect_len LESS actual_len)
+    string(APPEND RunCMake_TEST_FAILED
+      "Extra array items at:\n ${path}\n")
+    set(iter_len "${expect_len}")
+  endif ()
+
+  foreach (idx RANGE "${iter_len}")
+    if (idx EQUAL iter_len)
+      break ()
+    endif ()
+
+    set(new_path "${path}[${idx}]")
+    string(JSON actual_type TYPE "${actual}" "${idx}")
+    string(JSON expect_type TYPE "${expect}" "${idx}")
+    string(JSON actual_value GET "${actual}" "${idx}")
+    string(JSON expect_value GET "${expect}" "${idx}")
+    check_json_value("${new_path}" "${actual_type}" "${expect_type}" "${actual_value}" "${expect_value}")
+  endforeach ()
+
+  set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}" PARENT_SCOPE)
+endfunction ()
+
+# Check that two inner objects are the same.
+function (check_json_object path actual expect)
+  string(JSON actual_len LENGTH "${actual}")
+  string(JSON expect_len LENGTH "${expect}")
+
+  set(actual_keys "")
+  set(expect_keys "")
+  foreach (idx RANGE "${actual_len}")
+    if (idx EQUAL actual_len)
+      break ()
+    endif ()
+
+    string(JSON actual_key MEMBER "${actual}" "${idx}")
+    list(APPEND actual_keys "${actual_key}")
+  endforeach ()
+  foreach (idx RANGE "${expect_len}")
+    if (idx EQUAL expect_len)
+      break ()
+    endif ()
+
+    string(JSON expect_key MEMBER "${expect}" "${idx}")
+    list(APPEND expect_keys "${expect_key}")
+  endforeach ()
+
+  json_placeholders("${expect_keys}" expect_keys_expanded)
+
+  set(actual_keys_missed "${actual_keys}")
+  set(expect_keys_missed "${expect_keys}")
+
+  set(common_keys "")
+  set(expect_keys_stack "${expect_keys}")
+  while (expect_keys_stack)
+    list(POP_BACK expect_keys_stack expect_key)
+    json_placeholders("${expect_key}" expect_key_expanded)
+
+    if (expect_key_expanded IN_LIST actual_keys_missed AND
+        expect_key IN_LIST expect_keys_missed)
+      list(APPEND common_keys "${expect_key}")
+    endif ()
+
+    list(REMOVE_ITEM actual_keys_missed "${expect_key_expanded}")
+    list(REMOVE_ITEM expect_keys_missed "${expect_key}")
+  endwhile ()
+
+  if (actual_keys_missed)
+    string(REPLACE ";" ", " actual_keys_missed_text "${actual_keys_missed}")
+    string(APPEND RunCMake_TEST_FAILED
+      "Extra unexpected members at:\n ${path}\nactual:\n ${actual_keys_missed_text}\n")
+  endif ()
+  if (expect_keys_missed)
+    string(REPLACE ";" ", " expect_keys_missed_text "${expect_keys_missed}")
+    string(APPEND RunCMake_TEST_FAILED
+      "Missing expected members at\n ${path}\nactual:\n ${expect_keys_missed_text}\n")
+  endif ()
+
+  foreach (key IN LISTS common_keys)
+    json_placeholders("${key}" key_expanded)
+    set(new_path "${path}.${key_expanded}")
+    string(JSON actual_type TYPE "${actual}" "${key_expanded}")
+    string(JSON expect_type TYPE "${expect}" "${key}")
+    string(JSON actual_value GET "${actual}" "${key_expanded}")
+    string(JSON expect_value GET "${expect}" "${key}")
+    check_json_value("${new_path}" "${actual_type}" "${expect_type}" "${actual_value}" "${expect_value}")
+  endforeach ()
+
+  set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}" PARENT_SCOPE)
+endfunction ()
+
+# Check that two JSON objects are the same.
+function (check_json actual expect)
+  check_json_object("" "${actual}" "${expect}")
+
+  set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}" PARENT_SCOPE)
+endfunction ()
diff --git a/Tests/RunCMake/CXXModules/examples/circular-build-result.txt b/Tests/RunCMake/CXXModulesCompile/circular-build-result.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/circular-build-result.txt
rename to Tests/RunCMake/CXXModulesCompile/circular-build-result.txt
diff --git a/Tests/RunCMake/CXXModules/examples/circular-build-stdout.txt b/Tests/RunCMake/CXXModulesCompile/circular-build-stdout.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/circular-build-stdout.txt
rename to Tests/RunCMake/CXXModulesCompile/circular-build-stdout.txt
diff --git a/Tests/RunCMake/CXXModules/examples/circular/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/circular/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/circular/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/circular/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/circular/circular-a.cppm b/Tests/RunCMake/CXXModulesCompile/circular/circular-a.cppm
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/circular/circular-a.cppm
rename to Tests/RunCMake/CXXModulesCompile/circular/circular-a.cppm
diff --git a/Tests/RunCMake/CXXModules/examples/circular/circular-b.cppm b/Tests/RunCMake/CXXModulesCompile/circular/circular-b.cppm
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/circular/circular-b.cppm
rename to Tests/RunCMake/CXXModulesCompile/circular/circular-b.cppm
diff --git a/Tests/RunCMake/CXXModules/examples/cxx-modules-find-bmi-and-interfaces.cmake b/Tests/RunCMake/CXXModulesCompile/cxx-mods-find-bmi-and-ifaces.cmake
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/cxx-modules-find-bmi-and-interfaces.cmake
rename to Tests/RunCMake/CXXModulesCompile/cxx-mods-find-bmi-and-ifaces.cmake
diff --git a/Tests/RunCMake/CXXModules/examples/cxx-modules-find-bmi.cmake b/Tests/RunCMake/CXXModulesCompile/cxx-modules-find-bmi.cmake
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/cxx-modules-find-bmi.cmake
rename to Tests/RunCMake/CXXModulesCompile/cxx-modules-find-bmi.cmake
diff --git a/Tests/RunCMake/CXXModules/examples/cxx-modules-rules.cmake b/Tests/RunCMake/CXXModulesCompile/cxx-modules-rules.cmake
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/cxx-modules-rules.cmake
rename to Tests/RunCMake/CXXModulesCompile/cxx-modules-rules.cmake
diff --git a/Tests/RunCMake/CXXModules/examples/deep-chain/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/deep-chain/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/deep-chain/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/deep-chain/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/deep-chain/a.cxx b/Tests/RunCMake/CXXModulesCompile/deep-chain/a.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/deep-chain/a.cxx
rename to Tests/RunCMake/CXXModulesCompile/deep-chain/a.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/deep-chain/b.cxx b/Tests/RunCMake/CXXModulesCompile/deep-chain/b.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/deep-chain/b.cxx
rename to Tests/RunCMake/CXXModulesCompile/deep-chain/b.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/deep-chain/c.cxx b/Tests/RunCMake/CXXModulesCompile/deep-chain/c.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/deep-chain/c.cxx
rename to Tests/RunCMake/CXXModulesCompile/deep-chain/c.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/deep-chain/d.cxx b/Tests/RunCMake/CXXModulesCompile/deep-chain/d.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/deep-chain/d.cxx
rename to Tests/RunCMake/CXXModulesCompile/deep-chain/d.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/deep-chain/e.cxx b/Tests/RunCMake/CXXModulesCompile/deep-chain/e.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/deep-chain/e.cxx
rename to Tests/RunCMake/CXXModulesCompile/deep-chain/e.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/deep-chain/main.cxx b/Tests/RunCMake/CXXModulesCompile/deep-chain/main.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/deep-chain/main.cxx
rename to Tests/RunCMake/CXXModulesCompile/deep-chain/main.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/depchain-collation-restat-rebuild-check.cmake b/Tests/RunCMake/CXXModulesCompile/depchain-collation-restat-rebuild-check.cmake
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/depchain-collation-restat-rebuild-check.cmake
rename to Tests/RunCMake/CXXModulesCompile/depchain-collation-restat-rebuild-check.cmake
diff --git a/Tests/RunCMake/CXXModules/examples/depchain-collation-restat/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/depchain-collation-restat/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/depchain-collation-restat/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/depchain-collation-restat/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/depchain-collation-restat/importable.cxx b/Tests/RunCMake/CXXModulesCompile/depchain-collation-restat/importable.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/depchain-collation-restat/importable.cxx
rename to Tests/RunCMake/CXXModulesCompile/depchain-collation-restat/importable.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/depchain-collation-restat/main.cxx b/Tests/RunCMake/CXXModulesCompile/depchain-collation-restat/main.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/depchain-collation-restat/main.cxx
rename to Tests/RunCMake/CXXModulesCompile/depchain-collation-restat/main.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/depchain-collation-restat/pre-rebuild.cmake b/Tests/RunCMake/CXXModulesCompile/depchain-collation-restat/pre-rebuild.cmake
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/depchain-collation-restat/pre-rebuild.cmake
rename to Tests/RunCMake/CXXModulesCompile/depchain-collation-restat/pre-rebuild.cmake
diff --git a/Tests/RunCMake/CXXModules/examples/depchain-modmap-rebuild-check.cmake b/Tests/RunCMake/CXXModulesCompile/depchain-modmap-rebuild-check.cmake
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/depchain-modmap-rebuild-check.cmake
rename to Tests/RunCMake/CXXModulesCompile/depchain-modmap-rebuild-check.cmake
diff --git a/Tests/RunCMake/CXXModules/examples/depchain-modmap/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/depchain-modmap/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/depchain-modmap/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/depchain-modmap/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/depchain-modmap/importable.cxx b/Tests/RunCMake/CXXModulesCompile/depchain-modmap/importable.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/depchain-modmap/importable.cxx
rename to Tests/RunCMake/CXXModulesCompile/depchain-modmap/importable.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/depchain-modmap/main.cxx b/Tests/RunCMake/CXXModulesCompile/depchain-modmap/main.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/depchain-modmap/main.cxx
rename to Tests/RunCMake/CXXModulesCompile/depchain-modmap/main.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/depchain-modmap/pre-rebuild.cmake b/Tests/RunCMake/CXXModulesCompile/depchain-modmap/pre-rebuild.cmake
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/depchain-modmap/pre-rebuild.cmake
rename to Tests/RunCMake/CXXModulesCompile/depchain-modmap/pre-rebuild.cmake
diff --git a/Tests/RunCMake/CXXModules/examples/depchain-modules-json-file-rebuild-check.cmake b/Tests/RunCMake/CXXModulesCompile/depchain-mods-json-file-rebuild-check.cmake
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/depchain-modules-json-file-rebuild-check.cmake
rename to Tests/RunCMake/CXXModulesCompile/depchain-mods-json-file-rebuild-check.cmake
diff --git a/Tests/RunCMake/CXXModules/examples/depchain-modules-json-file/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/depchain-mods-json-file/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/depchain-modules-json-file/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/depchain-mods-json-file/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/depchain-modules-json-file/importable.cxx b/Tests/RunCMake/CXXModulesCompile/depchain-mods-json-file/importable.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/depchain-modules-json-file/importable.cxx
rename to Tests/RunCMake/CXXModulesCompile/depchain-mods-json-file/importable.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/depchain-modules-json-file/main.cxx b/Tests/RunCMake/CXXModulesCompile/depchain-mods-json-file/main.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/depchain-modules-json-file/main.cxx
rename to Tests/RunCMake/CXXModulesCompile/depchain-mods-json-file/main.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/depchain-modules-json-file/pre-rebuild.cmake b/Tests/RunCMake/CXXModulesCompile/depchain-mods-json-file/pre-rebuild.cmake
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/depchain-modules-json-file/pre-rebuild.cmake
rename to Tests/RunCMake/CXXModulesCompile/depchain-mods-json-file/pre-rebuild.cmake
diff --git a/Tests/RunCMake/CXXModules/examples/duplicate-sources-stderr.txt b/Tests/RunCMake/CXXModulesCompile/duplicate-sources-stderr.txt
similarity index 75%
rename from Tests/RunCMake/CXXModules/examples/duplicate-sources-stderr.txt
rename to Tests/RunCMake/CXXModulesCompile/duplicate-sources-stderr.txt
index d3960f6..1dfe3d3 100644
--- a/Tests/RunCMake/CXXModules/examples/duplicate-sources-stderr.txt
+++ b/Tests/RunCMake/CXXModulesCompile/duplicate-sources-stderr.txt
@@ -2,7 +2,7 @@
   Target "duplicate_sources" has source file
 
     [^
-]*/Tests/RunCMake/CXXModules/examples/duplicate-sources/duplicate\.cxx
+]*/Tests/RunCMake/CXXModulesCompile/duplicate-sources/duplicate\.cxx
 
   in a "FILE_SET TYPE CXX_MODULES" multiple times\.
 This warning is for project developers\.  Use -Wno-dev to suppress it\.
diff --git a/Tests/RunCMake/CXXModules/examples/duplicate-sources/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/duplicate-sources/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/duplicate-sources/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/duplicate-sources/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/duplicate-sources/duplicate.cxx b/Tests/RunCMake/CXXModulesCompile/duplicate-sources/duplicate.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/duplicate-sources/duplicate.cxx
rename to Tests/RunCMake/CXXModulesCompile/duplicate-sources/duplicate.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/duplicate-sources/main.cxx b/Tests/RunCMake/CXXModulesCompile/duplicate-sources/main.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/duplicate-sources/main.cxx
rename to Tests/RunCMake/CXXModulesCompile/duplicate-sources/main.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/duplicate/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/duplicate/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/duplicate/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/duplicate/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/duplicate/duplicate.cxx b/Tests/RunCMake/CXXModulesCompile/duplicate/duplicate.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/duplicate/duplicate.cxx
rename to Tests/RunCMake/CXXModulesCompile/duplicate/duplicate.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/duplicate/main.cxx b/Tests/RunCMake/CXXModulesCompile/duplicate/main.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/duplicate/main.cxx
rename to Tests/RunCMake/CXXModulesCompile/duplicate/main.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-build/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-bmi-and-iface-build/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-build/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/exp-bmi-and-iface-build/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-build/forward.cxx b/Tests/RunCMake/CXXModulesCompile/exp-bmi-and-iface-build/forward.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-interface-build/forward.cxx
rename to Tests/RunCMake/CXXModulesCompile/exp-bmi-and-iface-build/forward.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-build/importable.cxx b/Tests/RunCMake/CXXModulesCompile/exp-bmi-and-iface-build/importable.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-interface-build/importable.cxx
rename to Tests/RunCMake/CXXModulesCompile/exp-bmi-and-iface-build/importable.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-build/no_modules.cxx b/Tests/RunCMake/CXXModulesCompile/exp-bmi-and-iface-build/no_modules.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-interface-build/no_modules.cxx
rename to Tests/RunCMake/CXXModulesCompile/exp-bmi-and-iface-build/no_modules.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-build/private.cxx b/Tests/RunCMake/CXXModulesCompile/exp-bmi-and-iface-build/private.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-interface-build/private.cxx
rename to Tests/RunCMake/CXXModulesCompile/exp-bmi-and-iface-build/private.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-build/subdir/importable.cxx b/Tests/RunCMake/CXXModulesCompile/exp-bmi-and-iface-build/subdir/importable.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-interface-build/subdir/importable.cxx
rename to Tests/RunCMake/CXXModulesCompile/exp-bmi-and-iface-build/subdir/importable.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-build/test/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-bmi-and-iface-build/test/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-build/test/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/exp-bmi-and-iface-build/test/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-install/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-bmi-and-iface-install/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-install/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/exp-bmi-and-iface-install/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-install/forward.cxx b/Tests/RunCMake/CXXModulesCompile/exp-bmi-and-iface-install/forward.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-interface-install/forward.cxx
rename to Tests/RunCMake/CXXModulesCompile/exp-bmi-and-iface-install/forward.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-install/importable.cxx b/Tests/RunCMake/CXXModulesCompile/exp-bmi-and-iface-install/importable.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-interface-install/importable.cxx
rename to Tests/RunCMake/CXXModulesCompile/exp-bmi-and-iface-install/importable.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-install/no_modules.cxx b/Tests/RunCMake/CXXModulesCompile/exp-bmi-and-iface-install/no_modules.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-interface-install/no_modules.cxx
rename to Tests/RunCMake/CXXModulesCompile/exp-bmi-and-iface-install/no_modules.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-install/private.cxx b/Tests/RunCMake/CXXModulesCompile/exp-bmi-and-iface-install/private.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-interface-install/private.cxx
rename to Tests/RunCMake/CXXModulesCompile/exp-bmi-and-iface-install/private.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-install/subdir/importable.cxx b/Tests/RunCMake/CXXModulesCompile/exp-bmi-and-iface-install/subdir/importable.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-interface-install/subdir/importable.cxx
rename to Tests/RunCMake/CXXModulesCompile/exp-bmi-and-iface-install/subdir/importable.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-install/test/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-bmi-and-iface-install/test/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-install/test/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/exp-bmi-and-iface-install/test/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModulesCompile/exp-builddb-build-check.cmake b/Tests/RunCMake/CXXModulesCompile/exp-builddb-build-check.cmake
new file mode 100644
index 0000000..303842f
--- /dev/null
+++ b/Tests/RunCMake/CXXModulesCompile/exp-builddb-build-check.cmake
@@ -0,0 +1,19 @@
+include("${CMAKE_CURRENT_LIST_DIR}/build-database-check.cmake")
+
+check_build_database("exp-builddb" "build_database.json" NO_EXIST)
+check_build_database("exp-builddb" "build_database_CXX.json" NO_EXIST)
+
+check_build_database("exp-builddb" "build_database_CXX_Debug.json" NO_EXIST)
+check_build_database("exp-builddb" "build_database_Debug.json" NO_EXIST)
+
+if (RunCMake_GENERATOR_IS_MULTI_CONFIG)
+  check_build_database("exp-builddb" "CMakeFiles/export_build_database.dir/Debug/CXX_build_database.json" JUST_TARGET_DEBUG)
+
+  # check_build_database("exp-builddb" "build_database_CXX_Release.json" NO_EXIST)
+  # check_build_database("exp-builddb" "build_database_Release.json" NO_EXIST)
+  # check_build_database("exp-builddb" "CMakeFiles/export_build_database.dir/Release/CXX_build_database.json" NO_EXIST)
+else ()
+  check_build_database("exp-builddb" "CMakeFiles/export_build_database.dir/CXX_build_database.json" JUST_TARGET)
+endif ()
+
+string(REPLACE ";" "\n  " RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}")
diff --git a/Tests/RunCMake/CXXModules/examples/export-build-database-check.cmake b/Tests/RunCMake/CXXModulesCompile/exp-builddb-check.cmake
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-build-database-check.cmake
rename to Tests/RunCMake/CXXModulesCompile/exp-builddb-check.cmake
diff --git a/Tests/RunCMake/CXXModules/examples/export-build-database-stderr.txt b/Tests/RunCMake/CXXModulesCompile/exp-builddb-stderr.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-build-database-stderr.txt
rename to Tests/RunCMake/CXXModulesCompile/exp-builddb-stderr.txt
diff --git a/Tests/RunCMake/CXXModulesCompile/exp-builddb-target-cmake_build_database-check.cmake b/Tests/RunCMake/CXXModulesCompile/exp-builddb-target-cmake_build_database-check.cmake
new file mode 100644
index 0000000..9c16a2f
--- /dev/null
+++ b/Tests/RunCMake/CXXModulesCompile/exp-builddb-target-cmake_build_database-check.cmake
@@ -0,0 +1,21 @@
+include("${CMAKE_CURRENT_LIST_DIR}/build-database-check.cmake")
+
+if (RunCMake_GENERATOR_IS_MULTI_CONFIG)
+  check_build_database("exp-builddb" "build_database.json" ALL_MULTI)
+  check_build_database("exp-builddb" "build_database_CXX.json" JUST_CXX_MULTI)
+
+  check_build_database("exp-builddb" "build_database_CXX_Debug.json" CXX_AND_DEBUG)
+  check_build_database("exp-builddb" "build_database_Debug.json" JUST_DEBUG)
+  check_build_database("exp-builddb" "CMakeFiles/export_build_database.dir/Debug/CXX_build_database.json" JUST_TARGET_DEBUG)
+
+  check_build_database("exp-builddb" "build_database_CXX_Release.json" CXX_AND_RELEASE)
+  check_build_database("exp-builddb" "build_database_Release.json" JUST_RELEASE)
+  check_build_database("exp-builddb" "CMakeFiles/export_build_database.dir/Release/CXX_build_database.json" JUST_TARGET_RELEASE)
+else ()
+  check_build_database("exp-builddb" "build_database.json" ALL)
+  check_build_database("exp-builddb" "build_database_CXX.json" JUST_CXX)
+
+  check_build_database("exp-builddb" "CMakeFiles/export_build_database.dir/CXX_build_database.json" JUST_TARGET)
+endif ()
+
+string(REPLACE ";" "\n  " RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}")
diff --git a/Tests/RunCMake/CXXModules/examples/export-build-database-target-cmake_build_database/CXX-check.cmake b/Tests/RunCMake/CXXModulesCompile/exp-builddb-target-cmake_build_database/CXX-check.cmake
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-build-database-target-cmake_build_database/CXX-check.cmake
rename to Tests/RunCMake/CXXModulesCompile/exp-builddb-target-cmake_build_database/CXX-check.cmake
diff --git a/Tests/RunCMake/CXXModules/examples/export-build-database-target-cmake_build_database/CXX/Debug-check.cmake b/Tests/RunCMake/CXXModulesCompile/exp-builddb-target-cmake_build_database/CXX/Debug-check.cmake
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-build-database-target-cmake_build_database/CXX/Debug-check.cmake
rename to Tests/RunCMake/CXXModulesCompile/exp-builddb-target-cmake_build_database/CXX/Debug-check.cmake
diff --git a/Tests/RunCMake/CXXModules/examples/export-build-database-target-cmake_build_database/CXX/Release-Release-check.cmake b/Tests/RunCMake/CXXModulesCompile/exp-builddb-target-cmake_build_database/CXX/Release-Release-check.cmake
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-build-database-target-cmake_build_database/CXX/Release-Release-check.cmake
rename to Tests/RunCMake/CXXModulesCompile/exp-builddb-target-cmake_build_database/CXX/Release-Release-check.cmake
diff --git a/Tests/RunCMake/CXXModules/examples/export-build-database-target-cmake_build_database/Debug-check.cmake b/Tests/RunCMake/CXXModulesCompile/exp-builddb-target-cmake_build_database/Debug-check.cmake
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-build-database-target-cmake_build_database/Debug-check.cmake
rename to Tests/RunCMake/CXXModulesCompile/exp-builddb-target-cmake_build_database/Debug-check.cmake
diff --git a/Tests/RunCMake/CXXModules/examples/export-build-database-target-cmake_build_database/Release-Release-check.cmake b/Tests/RunCMake/CXXModulesCompile/exp-builddb-target-cmake_build_database/Release-Release-check.cmake
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-build-database-target-cmake_build_database/Release-Release-check.cmake
rename to Tests/RunCMake/CXXModulesCompile/exp-builddb-target-cmake_build_database/Release-Release-check.cmake
diff --git a/Tests/RunCMake/CXXModules/examples/export-build-database/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-builddb/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-build-database/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/exp-builddb/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/export-build-database/dep_interface_include/anchor b/Tests/RunCMake/CXXModulesCompile/exp-builddb/dep_interface_include/anchor
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-build-database/dep_interface_include/anchor
rename to Tests/RunCMake/CXXModulesCompile/exp-builddb/dep_interface_include/anchor
diff --git a/Tests/RunCMake/CXXModules/examples/simple/importable.cxx b/Tests/RunCMake/CXXModulesCompile/exp-builddb/importable.cxx
similarity index 100%
copy from Tests/RunCMake/CXXModules/examples/simple/importable.cxx
copy to Tests/RunCMake/CXXModulesCompile/exp-builddb/importable.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-build-database/lib.cxx b/Tests/RunCMake/CXXModulesCompile/exp-builddb/lib.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-build-database/lib.cxx
rename to Tests/RunCMake/CXXModulesCompile/exp-builddb/lib.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-build-database/target_interface_include/anchor b/Tests/RunCMake/CXXModulesCompile/exp-builddb/target_interface_include/anchor
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-build-database/target_interface_include/anchor
rename to Tests/RunCMake/CXXModulesCompile/exp-builddb/target_interface_include/anchor
diff --git a/Tests/RunCMake/CXXModules/examples/export-build-database/target_public_include/anchor b/Tests/RunCMake/CXXModulesCompile/exp-builddb/target_public_include/anchor
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-build-database/target_public_include/anchor
rename to Tests/RunCMake/CXXModulesCompile/exp-builddb/target_public_include/anchor
diff --git a/Tests/RunCMake/CXXModules/examples/export-command-sepdir-build/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-command-sepdir-build/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-command-sepdir-build/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/exp-command-sepdir-build/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/export-command-sepdir-build/subdir/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-command-sepdir-build/subdir/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-command-sepdir-build/subdir/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/exp-command-sepdir-build/subdir/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/export-command-sepdir-build/subdir/importable.cxx b/Tests/RunCMake/CXXModulesCompile/exp-command-sepdir-build/subdir/importable.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-command-sepdir-build/subdir/importable.cxx
rename to Tests/RunCMake/CXXModulesCompile/exp-command-sepdir-build/subdir/importable.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-command-sepdir-build/test/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-command-sepdir-build/test/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-command-sepdir-build/test/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/exp-command-sepdir-build/test/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/export-command-sepdir-install/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-command-sepdir-install/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-command-sepdir-install/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/exp-command-sepdir-install/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/export-command-sepdir-install/subdir/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-command-sepdir-install/subdir/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-command-sepdir-install/subdir/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/exp-command-sepdir-install/subdir/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/export-command-sepdir-install/subdir/importable.cxx b/Tests/RunCMake/CXXModulesCompile/exp-command-sepdir-install/subdir/importable.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-command-sepdir-install/subdir/importable.cxx
rename to Tests/RunCMake/CXXModulesCompile/exp-command-sepdir-install/subdir/importable.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-command-sepdir-install/test/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-command-sepdir-install/test/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-command-sepdir-install/test/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/exp-command-sepdir-install/test/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/export-compile-commands-check.cmake b/Tests/RunCMake/CXXModulesCompile/exp-compile-commands-check.cmake
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-compile-commands-check.cmake
rename to Tests/RunCMake/CXXModulesCompile/exp-compile-commands-check.cmake
diff --git a/Tests/RunCMake/CXXModules/examples/export-compile-commands/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-compile-commands/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-compile-commands/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/exp-compile-commands/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/export-compile-commands/importable.cxx b/Tests/RunCMake/CXXModulesCompile/exp-compile-commands/importable.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-compile-commands/importable.cxx
rename to Tests/RunCMake/CXXModulesCompile/exp-compile-commands/importable.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-compile-commands/main.cxx b/Tests/RunCMake/CXXModulesCompile/exp-compile-commands/main.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-compile-commands/main.cxx
rename to Tests/RunCMake/CXXModulesCompile/exp-compile-commands/main.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-build/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-iface-build/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-interface-build/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/exp-iface-build/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-build/forward.cxx b/Tests/RunCMake/CXXModulesCompile/exp-iface-build/forward.cxx
similarity index 100%
copy from Tests/RunCMake/CXXModules/examples/export-interface-build/forward.cxx
copy to Tests/RunCMake/CXXModulesCompile/exp-iface-build/forward.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-build/importable.cxx b/Tests/RunCMake/CXXModulesCompile/exp-iface-build/importable.cxx
similarity index 100%
copy from Tests/RunCMake/CXXModules/examples/export-interface-build/importable.cxx
copy to Tests/RunCMake/CXXModulesCompile/exp-iface-build/importable.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-build/no_modules.cxx b/Tests/RunCMake/CXXModulesCompile/exp-iface-build/no_modules.cxx
similarity index 100%
copy from Tests/RunCMake/CXXModules/examples/export-interface-build/no_modules.cxx
copy to Tests/RunCMake/CXXModulesCompile/exp-iface-build/no_modules.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-build/private.cxx b/Tests/RunCMake/CXXModulesCompile/exp-iface-build/private.cxx
similarity index 100%
copy from Tests/RunCMake/CXXModules/examples/export-interface-build/private.cxx
copy to Tests/RunCMake/CXXModulesCompile/exp-iface-build/private.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-build/subdir/importable.cxx b/Tests/RunCMake/CXXModulesCompile/exp-iface-build/subdir/importable.cxx
similarity index 100%
copy from Tests/RunCMake/CXXModules/examples/export-interface-build/subdir/importable.cxx
copy to Tests/RunCMake/CXXModulesCompile/exp-iface-build/subdir/importable.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-build/test/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-iface-build/test/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-interface-build/test/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/exp-iface-build/test/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-install/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-iface-install/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-interface-install/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/exp-iface-install/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-install/forward.cxx b/Tests/RunCMake/CXXModulesCompile/exp-iface-install/forward.cxx
similarity index 100%
copy from Tests/RunCMake/CXXModules/examples/export-interface-install/forward.cxx
copy to Tests/RunCMake/CXXModulesCompile/exp-iface-install/forward.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-install/importable.cxx b/Tests/RunCMake/CXXModulesCompile/exp-iface-install/importable.cxx
similarity index 100%
copy from Tests/RunCMake/CXXModules/examples/export-interface-install/importable.cxx
copy to Tests/RunCMake/CXXModulesCompile/exp-iface-install/importable.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-install/no_modules.cxx b/Tests/RunCMake/CXXModulesCompile/exp-iface-install/no_modules.cxx
similarity index 100%
copy from Tests/RunCMake/CXXModules/examples/export-interface-install/no_modules.cxx
copy to Tests/RunCMake/CXXModulesCompile/exp-iface-install/no_modules.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-install/private.cxx b/Tests/RunCMake/CXXModulesCompile/exp-iface-install/private.cxx
similarity index 100%
copy from Tests/RunCMake/CXXModules/examples/export-interface-install/private.cxx
copy to Tests/RunCMake/CXXModulesCompile/exp-iface-install/private.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-install/subdir/importable.cxx b/Tests/RunCMake/CXXModulesCompile/exp-iface-install/subdir/importable.cxx
similarity index 100%
copy from Tests/RunCMake/CXXModules/examples/export-interface-install/subdir/importable.cxx
copy to Tests/RunCMake/CXXModulesCompile/exp-iface-install/subdir/importable.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-install/test/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-iface-install/test/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-interface-install/test/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/exp-iface-install/test/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-no-properties-build/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-iface-no-props-build/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-interface-no-properties-build/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/exp-iface-no-props-build/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-build/forward.cxx b/Tests/RunCMake/CXXModulesCompile/exp-iface-no-props-build/forward.cxx
similarity index 100%
copy from Tests/RunCMake/CXXModules/examples/export-interface-build/forward.cxx
copy to Tests/RunCMake/CXXModulesCompile/exp-iface-no-props-build/forward.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-build/importable.cxx b/Tests/RunCMake/CXXModulesCompile/exp-iface-no-props-build/importable.cxx
similarity index 100%
copy from Tests/RunCMake/CXXModules/examples/export-interface-build/importable.cxx
copy to Tests/RunCMake/CXXModulesCompile/exp-iface-no-props-build/importable.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-build/no_modules.cxx b/Tests/RunCMake/CXXModulesCompile/exp-iface-no-props-build/no_modules.cxx
similarity index 100%
copy from Tests/RunCMake/CXXModules/examples/export-interface-build/no_modules.cxx
copy to Tests/RunCMake/CXXModulesCompile/exp-iface-no-props-build/no_modules.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-build/private.cxx b/Tests/RunCMake/CXXModulesCompile/exp-iface-no-props-build/private.cxx
similarity index 100%
copy from Tests/RunCMake/CXXModules/examples/export-interface-build/private.cxx
copy to Tests/RunCMake/CXXModulesCompile/exp-iface-no-props-build/private.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-build/subdir/importable.cxx b/Tests/RunCMake/CXXModulesCompile/exp-iface-no-props-build/subdir/importable.cxx
similarity index 100%
copy from Tests/RunCMake/CXXModules/examples/export-interface-build/subdir/importable.cxx
copy to Tests/RunCMake/CXXModulesCompile/exp-iface-no-props-build/subdir/importable.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-no-properties-build/test/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-iface-no-props-build/test/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-interface-no-properties-build/test/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/exp-iface-no-props-build/test/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-no-properties-install/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-iface-no-props-install/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-interface-no-properties-install/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/exp-iface-no-props-install/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-install/forward.cxx b/Tests/RunCMake/CXXModulesCompile/exp-iface-no-props-install/forward.cxx
similarity index 100%
copy from Tests/RunCMake/CXXModules/examples/export-interface-install/forward.cxx
copy to Tests/RunCMake/CXXModulesCompile/exp-iface-no-props-install/forward.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-install/importable.cxx b/Tests/RunCMake/CXXModulesCompile/exp-iface-no-props-install/importable.cxx
similarity index 100%
copy from Tests/RunCMake/CXXModules/examples/export-interface-install/importable.cxx
copy to Tests/RunCMake/CXXModulesCompile/exp-iface-no-props-install/importable.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-install/no_modules.cxx b/Tests/RunCMake/CXXModulesCompile/exp-iface-no-props-install/no_modules.cxx
similarity index 100%
copy from Tests/RunCMake/CXXModules/examples/export-interface-install/no_modules.cxx
copy to Tests/RunCMake/CXXModulesCompile/exp-iface-no-props-install/no_modules.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-install/private.cxx b/Tests/RunCMake/CXXModulesCompile/exp-iface-no-props-install/private.cxx
similarity index 100%
copy from Tests/RunCMake/CXXModules/examples/export-interface-install/private.cxx
copy to Tests/RunCMake/CXXModulesCompile/exp-iface-no-props-install/private.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-install/subdir/importable.cxx b/Tests/RunCMake/CXXModulesCompile/exp-iface-no-props-install/subdir/importable.cxx
similarity index 100%
copy from Tests/RunCMake/CXXModules/examples/export-interface-install/subdir/importable.cxx
copy to Tests/RunCMake/CXXModulesCompile/exp-iface-no-props-install/subdir/importable.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-no-properties-install/test/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-iface-no-props-install/test/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-interface-no-properties-install/test/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/exp-iface-no-props-install/test/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/export-include-directories-build/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-incdirs-build/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-include-directories-build/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/exp-incdirs-build/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/export-usage-build/forward.cxx b/Tests/RunCMake/CXXModulesCompile/exp-incdirs-build/forward.cxx
similarity index 100%
copy from Tests/RunCMake/CXXModules/examples/export-usage-build/forward.cxx
copy to Tests/RunCMake/CXXModulesCompile/exp-incdirs-build/forward.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-include-directories-build/importable.cxx b/Tests/RunCMake/CXXModulesCompile/exp-incdirs-build/importable.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-include-directories-build/importable.cxx
rename to Tests/RunCMake/CXXModulesCompile/exp-incdirs-build/importable.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-include-directories-build/include/include.h b/Tests/RunCMake/CXXModulesCompile/exp-incdirs-build/include/include.h
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-include-directories-build/include/include.h
rename to Tests/RunCMake/CXXModulesCompile/exp-incdirs-build/include/include.h
diff --git a/Tests/RunCMake/CXXModules/examples/export-include-directories-build/includes/includes.h b/Tests/RunCMake/CXXModulesCompile/exp-incdirs-build/includes/includes.h
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-include-directories-build/includes/includes.h
rename to Tests/RunCMake/CXXModulesCompile/exp-incdirs-build/includes/includes.h
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-build/no_modules.cxx b/Tests/RunCMake/CXXModulesCompile/exp-incdirs-build/no_modules.cxx
similarity index 100%
copy from Tests/RunCMake/CXXModules/examples/export-interface-build/no_modules.cxx
copy to Tests/RunCMake/CXXModulesCompile/exp-incdirs-build/no_modules.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-usage-build/private.cxx b/Tests/RunCMake/CXXModulesCompile/exp-incdirs-build/private.cxx
similarity index 100%
copy from Tests/RunCMake/CXXModules/examples/export-usage-build/private.cxx
copy to Tests/RunCMake/CXXModulesCompile/exp-incdirs-build/private.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-build/subdir/importable.cxx b/Tests/RunCMake/CXXModulesCompile/exp-incdirs-build/subdir/importable.cxx
similarity index 100%
copy from Tests/RunCMake/CXXModules/examples/export-interface-build/subdir/importable.cxx
copy to Tests/RunCMake/CXXModulesCompile/exp-incdirs-build/subdir/importable.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-include-directories-build/test/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-incdirs-build/test/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-include-directories-build/test/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/exp-incdirs-build/test/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/export-include-directories-install/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-incdirs-install/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-include-directories-install/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/exp-incdirs-install/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/export-usage-install/forward.cxx b/Tests/RunCMake/CXXModulesCompile/exp-incdirs-install/forward.cxx
similarity index 100%
copy from Tests/RunCMake/CXXModules/examples/export-usage-install/forward.cxx
copy to Tests/RunCMake/CXXModulesCompile/exp-incdirs-install/forward.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-include-directories-install/importable.cxx b/Tests/RunCMake/CXXModulesCompile/exp-incdirs-install/importable.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-include-directories-install/importable.cxx
rename to Tests/RunCMake/CXXModulesCompile/exp-incdirs-install/importable.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-include-directories-install/include/include.h b/Tests/RunCMake/CXXModulesCompile/exp-incdirs-install/include/include.h
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-include-directories-install/include/include.h
rename to Tests/RunCMake/CXXModulesCompile/exp-incdirs-install/include/include.h
diff --git a/Tests/RunCMake/CXXModules/examples/export-transitive-targets-install/includes/includes.h b/Tests/RunCMake/CXXModulesCompile/exp-incdirs-install/includes/includes.h
similarity index 100%
copy from Tests/RunCMake/CXXModules/examples/export-transitive-targets-install/includes/includes.h
copy to Tests/RunCMake/CXXModulesCompile/exp-incdirs-install/includes/includes.h
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-install/no_modules.cxx b/Tests/RunCMake/CXXModulesCompile/exp-incdirs-install/no_modules.cxx
similarity index 100%
copy from Tests/RunCMake/CXXModules/examples/export-interface-install/no_modules.cxx
copy to Tests/RunCMake/CXXModulesCompile/exp-incdirs-install/no_modules.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-usage-install/private.cxx b/Tests/RunCMake/CXXModulesCompile/exp-incdirs-install/private.cxx
similarity index 100%
copy from Tests/RunCMake/CXXModules/examples/export-usage-install/private.cxx
copy to Tests/RunCMake/CXXModulesCompile/exp-incdirs-install/private.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-install/subdir/importable.cxx b/Tests/RunCMake/CXXModulesCompile/exp-incdirs-install/subdir/importable.cxx
similarity index 100%
copy from Tests/RunCMake/CXXModules/examples/export-interface-install/subdir/importable.cxx
copy to Tests/RunCMake/CXXModulesCompile/exp-incdirs-install/subdir/importable.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-include-directories-install/test/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-incdirs-install/test/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-include-directories-install/test/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/exp-incdirs-install/test/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/export-include-directories-old-cmake-build/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-incdirs-old-cmake-build/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-include-directories-old-cmake-build/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/exp-incdirs-old-cmake-build/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/export-include-directories-old-cmake-build/importable.cxx b/Tests/RunCMake/CXXModulesCompile/exp-incdirs-old-cmake-build/importable.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-include-directories-old-cmake-build/importable.cxx
rename to Tests/RunCMake/CXXModulesCompile/exp-incdirs-old-cmake-build/importable.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-include-directories-old-cmake-build/test/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-incdirs-old-cmake-build/test/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-include-directories-old-cmake-build/test/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/exp-incdirs-old-cmake-build/test/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/export-include-directories-old-cmake-install/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-incdirs-old-cmake-install/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-include-directories-old-cmake-install/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/exp-incdirs-old-cmake-install/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/export-include-directories-old-cmake-install/importable.cxx b/Tests/RunCMake/CXXModulesCompile/exp-incdirs-old-cmake-install/importable.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-include-directories-old-cmake-install/importable.cxx
rename to Tests/RunCMake/CXXModulesCompile/exp-incdirs-old-cmake-install/importable.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-include-directories-old-cmake-install/test/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-incdirs-old-cmake-install/test/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-include-directories-old-cmake-install/test/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/exp-incdirs-old-cmake-install/test/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/export-modules-from-ninja/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-mods-from-ninja/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-modules-from-ninja/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/exp-mods-from-ninja/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/export-modules-from-ninja/forward.cxx b/Tests/RunCMake/CXXModulesCompile/exp-mods-from-ninja/forward.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-modules-from-ninja/forward.cxx
rename to Tests/RunCMake/CXXModulesCompile/exp-mods-from-ninja/forward.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-modules-from-ninja/importable.cxx b/Tests/RunCMake/CXXModulesCompile/exp-mods-from-ninja/importable.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-modules-from-ninja/importable.cxx
rename to Tests/RunCMake/CXXModulesCompile/exp-mods-from-ninja/importable.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-modules-from-ninja/no_modules.cxx b/Tests/RunCMake/CXXModulesCompile/exp-mods-from-ninja/no_modules.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-modules-from-ninja/no_modules.cxx
rename to Tests/RunCMake/CXXModulesCompile/exp-mods-from-ninja/no_modules.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-modules-from-ninja/private.cxx b/Tests/RunCMake/CXXModulesCompile/exp-mods-from-ninja/private.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-modules-from-ninja/private.cxx
rename to Tests/RunCMake/CXXModulesCompile/exp-mods-from-ninja/private.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-modules-from-ninja/subdir/importable.cxx b/Tests/RunCMake/CXXModulesCompile/exp-mods-from-ninja/subdir/importable.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-modules-from-ninja/subdir/importable.cxx
rename to Tests/RunCMake/CXXModulesCompile/exp-mods-from-ninja/subdir/importable.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-transitive-modules-build/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-trans-mods-build/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-transitive-modules-build/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/exp-trans-mods-build/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/export-transitive-modules-build/importable.cxx b/Tests/RunCMake/CXXModulesCompile/exp-trans-mods-build/importable.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-transitive-modules-build/importable.cxx
rename to Tests/RunCMake/CXXModulesCompile/exp-trans-mods-build/importable.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-transitive-modules-build/test/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-trans-mods-build/test/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-transitive-modules-build/test/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/exp-trans-mods-build/test/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/export-transitive-modules-install/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-trans-mods-install/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-transitive-modules-install/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/exp-trans-mods-install/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/export-transitive-modules-install/importable.cxx b/Tests/RunCMake/CXXModulesCompile/exp-trans-mods-install/importable.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-transitive-modules-install/importable.cxx
rename to Tests/RunCMake/CXXModulesCompile/exp-trans-mods-install/importable.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-transitive-modules-install/test/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-trans-mods-install/test/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-transitive-modules-install/test/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/exp-trans-mods-install/test/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/export-transitive-modules1-build/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-trans-mods1-build/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-transitive-modules1-build/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/exp-trans-mods1-build/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/export-transitive-modules1-build/importable.cxx b/Tests/RunCMake/CXXModulesCompile/exp-trans-mods1-build/importable.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-transitive-modules1-build/importable.cxx
rename to Tests/RunCMake/CXXModulesCompile/exp-trans-mods1-build/importable.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-transitive-modules1-build/test/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-trans-mods1-build/test/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-transitive-modules1-build/test/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/exp-trans-mods1-build/test/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/export-transitive-modules1-install/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-trans-mods1-install/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-transitive-modules1-install/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/exp-trans-mods1-install/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/export-transitive-modules1-install/importable.cxx b/Tests/RunCMake/CXXModulesCompile/exp-trans-mods1-install/importable.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-transitive-modules1-install/importable.cxx
rename to Tests/RunCMake/CXXModulesCompile/exp-trans-mods1-install/importable.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-transitive-modules1-install/test/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-trans-mods1-install/test/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-transitive-modules1-install/test/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/exp-trans-mods1-install/test/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/export-transitive-targets-build/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-trans-targets-build/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-transitive-targets-build/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/exp-trans-targets-build/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/export-transitive-targets-build/forward.cxx b/Tests/RunCMake/CXXModulesCompile/exp-trans-targets-build/forward.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-transitive-targets-build/forward.cxx
rename to Tests/RunCMake/CXXModulesCompile/exp-trans-targets-build/forward.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-transitive-targets-build/importable.cxx b/Tests/RunCMake/CXXModulesCompile/exp-trans-targets-build/importable.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-transitive-targets-build/importable.cxx
rename to Tests/RunCMake/CXXModulesCompile/exp-trans-targets-build/importable.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-transitive-targets-build/include/include.h b/Tests/RunCMake/CXXModulesCompile/exp-trans-targets-build/include/include.h
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-transitive-targets-build/include/include.h
rename to Tests/RunCMake/CXXModulesCompile/exp-trans-targets-build/include/include.h
diff --git a/Tests/RunCMake/CXXModules/examples/export-transitive-targets-build/includes/includes.h b/Tests/RunCMake/CXXModulesCompile/exp-trans-targets-build/includes/includes.h
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-transitive-targets-build/includes/includes.h
rename to Tests/RunCMake/CXXModulesCompile/exp-trans-targets-build/includes/includes.h
diff --git a/Tests/RunCMake/CXXModules/examples/export-transitive-targets-build/no_modules.cxx b/Tests/RunCMake/CXXModulesCompile/exp-trans-targets-build/no_modules.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-transitive-targets-build/no_modules.cxx
rename to Tests/RunCMake/CXXModulesCompile/exp-trans-targets-build/no_modules.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-transitive-targets-build/private.cxx b/Tests/RunCMake/CXXModulesCompile/exp-trans-targets-build/private.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-transitive-targets-build/private.cxx
rename to Tests/RunCMake/CXXModulesCompile/exp-trans-targets-build/private.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-transitive-targets-build/subdir/importable.cxx b/Tests/RunCMake/CXXModulesCompile/exp-trans-targets-build/subdir/importable.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-transitive-targets-build/subdir/importable.cxx
rename to Tests/RunCMake/CXXModulesCompile/exp-trans-targets-build/subdir/importable.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-transitive-targets-build/test/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-trans-targets-build/test/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-transitive-targets-build/test/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/exp-trans-targets-build/test/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/export-transitive-targets-install/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-trans-targets-install/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-transitive-targets-install/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/exp-trans-targets-install/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/export-transitive-targets-install/forward.cxx b/Tests/RunCMake/CXXModulesCompile/exp-trans-targets-install/forward.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-transitive-targets-install/forward.cxx
rename to Tests/RunCMake/CXXModulesCompile/exp-trans-targets-install/forward.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-transitive-targets-install/importable.cxx b/Tests/RunCMake/CXXModulesCompile/exp-trans-targets-install/importable.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-transitive-targets-install/importable.cxx
rename to Tests/RunCMake/CXXModulesCompile/exp-trans-targets-install/importable.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-transitive-targets-install/include/include.h b/Tests/RunCMake/CXXModulesCompile/exp-trans-targets-install/include/include.h
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-transitive-targets-install/include/include.h
rename to Tests/RunCMake/CXXModulesCompile/exp-trans-targets-install/include/include.h
diff --git a/Tests/RunCMake/CXXModules/examples/export-transitive-targets-install/includes/includes.h b/Tests/RunCMake/CXXModulesCompile/exp-trans-targets-install/includes/includes.h
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-transitive-targets-install/includes/includes.h
rename to Tests/RunCMake/CXXModulesCompile/exp-trans-targets-install/includes/includes.h
diff --git a/Tests/RunCMake/CXXModules/examples/export-transitive-targets-install/no_modules.cxx b/Tests/RunCMake/CXXModulesCompile/exp-trans-targets-install/no_modules.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-transitive-targets-install/no_modules.cxx
rename to Tests/RunCMake/CXXModulesCompile/exp-trans-targets-install/no_modules.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-transitive-targets-install/private.cxx b/Tests/RunCMake/CXXModulesCompile/exp-trans-targets-install/private.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-transitive-targets-install/private.cxx
rename to Tests/RunCMake/CXXModulesCompile/exp-trans-targets-install/private.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-install/subdir/importable.cxx b/Tests/RunCMake/CXXModulesCompile/exp-trans-targets-install/subdir/importable.cxx
similarity index 100%
copy from Tests/RunCMake/CXXModules/examples/export-interface-install/subdir/importable.cxx
copy to Tests/RunCMake/CXXModulesCompile/exp-trans-targets-install/subdir/importable.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-transitive-targets-install/test/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-trans-targets-install/test/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-transitive-targets-install/test/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/exp-trans-targets-install/test/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/export-usage-build/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-usage-build/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-usage-build/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/exp-usage-build/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/export-usage-build/forward.cxx b/Tests/RunCMake/CXXModulesCompile/exp-usage-build/forward.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-usage-build/forward.cxx
rename to Tests/RunCMake/CXXModulesCompile/exp-usage-build/forward.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-usage-build/importable.cxx b/Tests/RunCMake/CXXModulesCompile/exp-usage-build/importable.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-usage-build/importable.cxx
rename to Tests/RunCMake/CXXModulesCompile/exp-usage-build/importable.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-usage-build/private.cxx b/Tests/RunCMake/CXXModulesCompile/exp-usage-build/private.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-usage-build/private.cxx
rename to Tests/RunCMake/CXXModulesCompile/exp-usage-build/private.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-usage-build/test/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-usage-build/test/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-usage-build/test/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/exp-usage-build/test/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/export-usage-install/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-usage-install/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-usage-install/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/exp-usage-install/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/export-usage-install/forward.cxx b/Tests/RunCMake/CXXModulesCompile/exp-usage-install/forward.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-usage-install/forward.cxx
rename to Tests/RunCMake/CXXModulesCompile/exp-usage-install/forward.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-usage-install/importable.cxx b/Tests/RunCMake/CXXModulesCompile/exp-usage-install/importable.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-usage-install/importable.cxx
rename to Tests/RunCMake/CXXModulesCompile/exp-usage-install/importable.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-usage-install/private.cxx b/Tests/RunCMake/CXXModulesCompile/exp-usage-install/private.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-usage-install/private.cxx
rename to Tests/RunCMake/CXXModulesCompile/exp-usage-install/private.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-usage-install/test/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-usage-install/test/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-usage-install/test/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/exp-usage-install/test/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/export-with-headers-build/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-with-headers-build/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-with-headers-build/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/exp-with-headers-build/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/export-with-headers-build/importable.cxx b/Tests/RunCMake/CXXModulesCompile/exp-with-headers-build/importable.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-with-headers-build/importable.cxx
rename to Tests/RunCMake/CXXModulesCompile/exp-with-headers-build/importable.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-with-headers-build/include/subdir/header.h b/Tests/RunCMake/CXXModulesCompile/exp-with-headers-build/include/subdir/header.h
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-with-headers-build/include/subdir/header.h
rename to Tests/RunCMake/CXXModulesCompile/exp-with-headers-build/include/subdir/header.h
diff --git a/Tests/RunCMake/CXXModules/examples/export-with-headers-build/test/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-with-headers-build/test/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-with-headers-build/test/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/exp-with-headers-build/test/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/export-with-headers-install/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-with-headers-install/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-with-headers-install/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/exp-with-headers-install/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/export-with-headers-install/importable.cxx b/Tests/RunCMake/CXXModulesCompile/exp-with-headers-install/importable.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-with-headers-install/importable.cxx
rename to Tests/RunCMake/CXXModulesCompile/exp-with-headers-install/importable.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/export-with-headers-install/include/subdir/header.h b/Tests/RunCMake/CXXModulesCompile/exp-with-headers-install/include/subdir/header.h
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-with-headers-install/include/subdir/header.h
rename to Tests/RunCMake/CXXModulesCompile/exp-with-headers-install/include/subdir/header.h
diff --git a/Tests/RunCMake/CXXModules/examples/export-with-headers-install/test/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-with-headers-install/test/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-with-headers-install/test/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/exp-with-headers-install/test/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/expect/export-build-database-all-multi.json b/Tests/RunCMake/CXXModulesCompile/expect/exp-builddb-all-multi.json
similarity index 65%
rename from Tests/RunCMake/CXXModules/examples/expect/export-build-database-all-multi.json
rename to Tests/RunCMake/CXXModulesCompile/expect/exp-builddb-all-multi.json
index ffb74cb..1cb79bb 100644
--- a/Tests/RunCMake/CXXModules/examples/expect/export-build-database-all-multi.json
+++ b/Tests/RunCMake/CXXModulesCompile/expect/exp-builddb-all-multi.json
@@ -14,10 +14,10 @@
             "-Dfrom_compile_definitions",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -29,7 +29,7 @@
             "PATH:-Ddepflag=\"CMakeFiles/export_build_database.dir<CONFIG_DIR>/lib.cxx<OBJEXT>.d\"",
             "PATH:<OUTPUT_FLAG>CMakeFiles/export_build_database.dir<CONFIG_DIR>/lib.cxx<OBJEXT>",
             "-c",
-            "PATH:<SOURCE_DIR>/examples/export-build-database/lib.cxx"
+            "PATH:<SOURCE_DIR>/exp-builddb/lib.cxx"
           ],
           "baseline-arguments": [
             "-D_MBCS",
@@ -37,10 +37,10 @@
             "-Dfrom_compile_definitions",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -56,10 +56,10 @@
             "-Dfrom_compile_definitions",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -73,7 +73,7 @@
           "private": true,
           "provides": {},
           "requires": ["importable"],
-          "source": "PATH:<SOURCE_DIR>/examples/export-build-database/lib.cxx",
+          "source": "PATH:<SOURCE_DIR>/exp-builddb/lib.cxx",
           "work-directory": "<BINARY_DIR>"
         },
         {
@@ -84,10 +84,10 @@
             "-Dfrom_compile_definitions",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -101,7 +101,7 @@
             "PATH:-Ddepflag=\"CMakeFiles/export_build_database.dir<CONFIG_DIR>/importable.cxx<OBJEXT>.d\"",
             "PATH:<OUTPUT_FLAG>CMakeFiles/export_build_database.dir<CONFIG_DIR>/importable.cxx<OBJEXT>",
             "-c",
-            "PATH:<SOURCE_DIR>/examples/export-build-database/importable.cxx"
+            "PATH:<SOURCE_DIR>/exp-builddb/importable.cxx"
           ],
           "baseline-arguments": [
             "-D_MBCS",
@@ -109,10 +109,10 @@
             "-Dfrom_compile_definitions",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -128,10 +128,10 @@
             "-Dfrom_compile_definitions",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -149,7 +149,7 @@
             "importable": "PATH:<BINARY_DIR>/CMakeFiles/export_build_database.dir<CONFIG_DIR>/importable<BMIEXT>"
           },
           "requires": [],
-          "source": "PATH:<SOURCE_DIR>/examples/export-build-database/importable.cxx",
+          "source": "PATH:<SOURCE_DIR>/exp-builddb/importable.cxx",
           "work-directory": "<BINARY_DIR>"
         }
       ],
@@ -167,10 +167,10 @@
             "-Dfrom_compile_definitions",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_OTHER_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -182,7 +182,7 @@
             "PATH:-Ddepflag=\"CMakeFiles/export_build_database.dir<CONFIG_OTHER_DIR>/lib.cxx<OBJEXT>.d\"",
             "PATH:<OUTPUT_FLAG>CMakeFiles/export_build_database.dir<CONFIG_OTHER_DIR>/lib.cxx<OBJEXT>",
             "-c",
-            "PATH:<SOURCE_DIR>/examples/export-build-database/lib.cxx"
+            "PATH:<SOURCE_DIR>/exp-builddb/lib.cxx"
           ],
           "baseline-arguments": [
             "-D_MBCS",
@@ -190,10 +190,10 @@
             "-Dfrom_compile_definitions",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_OTHER_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -209,10 +209,10 @@
             "-Dfrom_compile_definitions",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_OTHER_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -226,7 +226,7 @@
           "private": true,
           "provides": {},
           "requires": ["importable"],
-          "source": "PATH:<SOURCE_DIR>/examples/export-build-database/lib.cxx",
+          "source": "PATH:<SOURCE_DIR>/exp-builddb/lib.cxx",
           "work-directory": "<BINARY_DIR>"
         },
         {
@@ -237,10 +237,10 @@
             "-Dfrom_compile_definitions",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_OTHER_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -254,7 +254,7 @@
             "PATH:-Ddepflag=\"CMakeFiles/export_build_database.dir<CONFIG_OTHER_DIR>/importable.cxx<OBJEXT>.d\"",
             "PATH:<OUTPUT_FLAG>CMakeFiles/export_build_database.dir<CONFIG_OTHER_DIR>/importable.cxx<OBJEXT>",
             "-c",
-            "PATH:<SOURCE_DIR>/examples/export-build-database/importable.cxx"
+            "PATH:<SOURCE_DIR>/exp-builddb/importable.cxx"
           ],
           "baseline-arguments": [
             "-D_MBCS",
@@ -262,10 +262,10 @@
             "-Dfrom_compile_definitions",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_OTHER_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -281,10 +281,10 @@
             "-Dfrom_compile_definitions",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_OTHER_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -302,7 +302,7 @@
             "importable": "<BINARY_DIR>/CMakeFiles/export_build_database.dir<CONFIG_OTHER_DIR>/importable<BMIEXT>"
           },
           "requires": [],
-          "source": "PATH:<SOURCE_DIR>/examples/export-build-database/importable.cxx",
+          "source": "PATH:<SOURCE_DIR>/exp-builddb/importable.cxx",
           "work-directory": "<BINARY_DIR>"
         }
       ],
diff --git a/Tests/RunCMake/CXXModules/examples/expect/export-build-database-all.json b/Tests/RunCMake/CXXModulesCompile/expect/exp-builddb-all.json
similarity index 65%
rename from Tests/RunCMake/CXXModules/examples/expect/export-build-database-all.json
rename to Tests/RunCMake/CXXModulesCompile/expect/exp-builddb-all.json
index 4412d35..9b13bd0 100644
--- a/Tests/RunCMake/CXXModules/examples/expect/export-build-database-all.json
+++ b/Tests/RunCMake/CXXModulesCompile/expect/exp-builddb-all.json
@@ -14,10 +14,10 @@
             "-Dfrom_compile_definitions",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -29,7 +29,7 @@
             "PATH:-Ddepflag=\"CMakeFiles/export_build_database.dir<CONFIG_DIR>/lib.cxx<OBJEXT>.d\"",
             "PATH:<OUTPUT_FLAG>CMakeFiles/export_build_database.dir<CONFIG_DIR>/lib.cxx<OBJEXT>",
             "-c",
-            "PATH:<SOURCE_DIR>/examples/export-build-database/lib.cxx"
+            "PATH:<SOURCE_DIR>/exp-builddb/lib.cxx"
           ],
           "baseline-arguments": [
             "-D_MBCS",
@@ -37,10 +37,10 @@
             "-Dfrom_compile_definitions",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -56,10 +56,10 @@
             "-Dfrom_compile_definitions",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -73,7 +73,7 @@
           "private": true,
           "provides": {},
           "requires": ["importable"],
-          "source": "PATH:<SOURCE_DIR>/examples/export-build-database/lib.cxx",
+          "source": "PATH:<SOURCE_DIR>/exp-builddb/lib.cxx",
           "work-directory": "<BINARY_DIR>"
         },
         {
@@ -84,10 +84,10 @@
             "-Dfrom_compile_definitions",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -101,7 +101,7 @@
             "PATH:-Ddepflag=\"CMakeFiles/export_build_database.dir<CONFIG_DIR>/importable.cxx<OBJEXT>.d\"",
             "PATH:<OUTPUT_FLAG>CMakeFiles/export_build_database.dir<CONFIG_DIR>/importable.cxx<OBJEXT>",
             "-c",
-            "PATH:<SOURCE_DIR>/examples/export-build-database/importable.cxx"
+            "PATH:<SOURCE_DIR>/exp-builddb/importable.cxx"
           ],
           "baseline-arguments": [
             "-D_MBCS",
@@ -109,10 +109,10 @@
             "-Dfrom_compile_definitions",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -128,10 +128,10 @@
             "-Dfrom_compile_definitions",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -149,7 +149,7 @@
             "importable": "<BINARY_DIR>/CMakeFiles/export_build_database.dir<CONFIG_DIR>/importable<BMIEXT>"
           },
           "requires": [],
-          "source": "PATH:<SOURCE_DIR>/examples/export-build-database/importable.cxx",
+          "source": "PATH:<SOURCE_DIR>/exp-builddb/importable.cxx",
           "work-directory": "<BINARY_DIR>"
         }
       ],
diff --git a/Tests/RunCMake/CXXModules/examples/expect/export-build-database-config.json b/Tests/RunCMake/CXXModulesCompile/expect/exp-builddb-config.json
similarity index 65%
rename from Tests/RunCMake/CXXModules/examples/expect/export-build-database-config.json
rename to Tests/RunCMake/CXXModulesCompile/expect/exp-builddb-config.json
index 3815df5..0253351 100644
--- a/Tests/RunCMake/CXXModules/examples/expect/export-build-database-config.json
+++ b/Tests/RunCMake/CXXModulesCompile/expect/exp-builddb-config.json
@@ -14,10 +14,10 @@
             "-Dfrom_compile_definitions",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -29,7 +29,7 @@
             "PATH:-Ddepflag=\"CMakeFiles/export_build_database.dir<CONFIG_DIR>/lib.cxx<OBJEXT>.d\"",
             "PATH:<OUTPUT_FLAG>CMakeFiles/export_build_database.dir<CONFIG_DIR>/lib.cxx<OBJEXT>",
             "-c",
-            "PATH:<SOURCE_DIR>/examples/export-build-database/lib.cxx"
+            "PATH:<SOURCE_DIR>/exp-builddb/lib.cxx"
           ],
           "baseline-arguments": [
             "-D_MBCS",
@@ -37,10 +37,10 @@
             "-Dfrom_compile_definitions",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -56,10 +56,10 @@
             "-Dfrom_compile_definitions",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -73,7 +73,7 @@
           "private": true,
           "provides": {},
           "requires": ["importable"],
-          "source": "PATH:<SOURCE_DIR>/examples/export-build-database/lib.cxx",
+          "source": "PATH:<SOURCE_DIR>/exp-builddb/lib.cxx",
           "work-directory": "<BINARY_DIR>"
         },
         {
@@ -84,10 +84,10 @@
             "-Dfrom_compile_definitions",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -101,7 +101,7 @@
             "PATH:-Ddepflag=\"CMakeFiles/export_build_database.dir<CONFIG_DIR>/importable.cxx<OBJEXT>.d\"",
             "PATH:<OUTPUT_FLAG>CMakeFiles/export_build_database.dir<CONFIG_DIR>/importable.cxx<OBJEXT>",
             "-c",
-            "PATH:<SOURCE_DIR>/examples/export-build-database/importable.cxx"
+            "PATH:<SOURCE_DIR>/exp-builddb/importable.cxx"
           ],
           "baseline-arguments": [
             "-D_MBCS",
@@ -109,10 +109,10 @@
             "-Dfrom_compile_definitions",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -128,10 +128,10 @@
             "-Dfrom_compile_definitions",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -149,7 +149,7 @@
             "importable": "PATH:<BINARY_DIR>/CMakeFiles/export_build_database.dir<CONFIG_DIR>/importable<BMIEXT>"
           },
           "requires": [],
-          "source": "PATH:<SOURCE_DIR>/examples/export-build-database/importable.cxx",
+          "source": "PATH:<SOURCE_DIR>/exp-builddb/importable.cxx",
           "work-directory": "<BINARY_DIR>"
         }
       ],
diff --git a/Tests/RunCMake/CXXModules/examples/expect/export-build-database-config.json b/Tests/RunCMake/CXXModulesCompile/expect/exp-builddb-cxx-config.json
similarity index 65%
copy from Tests/RunCMake/CXXModules/examples/expect/export-build-database-config.json
copy to Tests/RunCMake/CXXModulesCompile/expect/exp-builddb-cxx-config.json
index 3815df5..0253351 100644
--- a/Tests/RunCMake/CXXModules/examples/expect/export-build-database-config.json
+++ b/Tests/RunCMake/CXXModulesCompile/expect/exp-builddb-cxx-config.json
@@ -14,10 +14,10 @@
             "-Dfrom_compile_definitions",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -29,7 +29,7 @@
             "PATH:-Ddepflag=\"CMakeFiles/export_build_database.dir<CONFIG_DIR>/lib.cxx<OBJEXT>.d\"",
             "PATH:<OUTPUT_FLAG>CMakeFiles/export_build_database.dir<CONFIG_DIR>/lib.cxx<OBJEXT>",
             "-c",
-            "PATH:<SOURCE_DIR>/examples/export-build-database/lib.cxx"
+            "PATH:<SOURCE_DIR>/exp-builddb/lib.cxx"
           ],
           "baseline-arguments": [
             "-D_MBCS",
@@ -37,10 +37,10 @@
             "-Dfrom_compile_definitions",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -56,10 +56,10 @@
             "-Dfrom_compile_definitions",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -73,7 +73,7 @@
           "private": true,
           "provides": {},
           "requires": ["importable"],
-          "source": "PATH:<SOURCE_DIR>/examples/export-build-database/lib.cxx",
+          "source": "PATH:<SOURCE_DIR>/exp-builddb/lib.cxx",
           "work-directory": "<BINARY_DIR>"
         },
         {
@@ -84,10 +84,10 @@
             "-Dfrom_compile_definitions",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -101,7 +101,7 @@
             "PATH:-Ddepflag=\"CMakeFiles/export_build_database.dir<CONFIG_DIR>/importable.cxx<OBJEXT>.d\"",
             "PATH:<OUTPUT_FLAG>CMakeFiles/export_build_database.dir<CONFIG_DIR>/importable.cxx<OBJEXT>",
             "-c",
-            "PATH:<SOURCE_DIR>/examples/export-build-database/importable.cxx"
+            "PATH:<SOURCE_DIR>/exp-builddb/importable.cxx"
           ],
           "baseline-arguments": [
             "-D_MBCS",
@@ -109,10 +109,10 @@
             "-Dfrom_compile_definitions",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -128,10 +128,10 @@
             "-Dfrom_compile_definitions",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -149,7 +149,7 @@
             "importable": "PATH:<BINARY_DIR>/CMakeFiles/export_build_database.dir<CONFIG_DIR>/importable<BMIEXT>"
           },
           "requires": [],
-          "source": "PATH:<SOURCE_DIR>/examples/export-build-database/importable.cxx",
+          "source": "PATH:<SOURCE_DIR>/exp-builddb/importable.cxx",
           "work-directory": "<BINARY_DIR>"
         }
       ],
diff --git a/Tests/RunCMake/CXXModules/examples/expect/export-build-database-cxx-multi.json b/Tests/RunCMake/CXXModulesCompile/expect/exp-builddb-cxx-multi.json
similarity index 65%
rename from Tests/RunCMake/CXXModules/examples/expect/export-build-database-cxx-multi.json
rename to Tests/RunCMake/CXXModulesCompile/expect/exp-builddb-cxx-multi.json
index 5d2fa07..78cde14 100644
--- a/Tests/RunCMake/CXXModules/examples/expect/export-build-database-cxx-multi.json
+++ b/Tests/RunCMake/CXXModulesCompile/expect/exp-builddb-cxx-multi.json
@@ -14,10 +14,10 @@
             "-Dfrom_compile_definitions",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -29,7 +29,7 @@
             "PATH:-Ddepflag=\"CMakeFiles/export_build_database.dir<CONFIG_DIR>/lib.cxx<OBJEXT>.d\"",
             "PATH:<OUTPUT_FLAG>CMakeFiles/export_build_database.dir<CONFIG_DIR>/lib.cxx<OBJEXT>",
             "-c",
-            "PATH:<SOURCE_DIR>/examples/export-build-database/lib.cxx"
+            "PATH:<SOURCE_DIR>/exp-builddb/lib.cxx"
           ],
           "baseline-arguments": [
             "-D_MBCS",
@@ -37,10 +37,10 @@
             "-Dfrom_compile_definitions",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -56,10 +56,10 @@
             "-Dfrom_compile_definitions",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -73,7 +73,7 @@
           "private": true,
           "provides": {},
           "requires": ["importable"],
-          "source": "PATH:<SOURCE_DIR>/examples/export-build-database/lib.cxx",
+          "source": "PATH:<SOURCE_DIR>/exp-builddb/lib.cxx",
           "work-directory": "<BINARY_DIR>"
         },
         {
@@ -84,10 +84,10 @@
             "-Dfrom_compile_definitions",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -101,7 +101,7 @@
             "PATH:-Ddepflag=\"CMakeFiles/export_build_database.dir<CONFIG_DIR>/importable.cxx<OBJEXT>.d\"",
             "PATH:<OUTPUT_FLAG>CMakeFiles/export_build_database.dir<CONFIG_DIR>/importable.cxx<OBJEXT>",
             "-c",
-            "PATH:<SOURCE_DIR>/examples/export-build-database/importable.cxx"
+            "PATH:<SOURCE_DIR>/exp-builddb/importable.cxx"
           ],
           "baseline-arguments": [
             "-D_MBCS",
@@ -109,10 +109,10 @@
             "-Dfrom_compile_definitions",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -128,10 +128,10 @@
             "-Dfrom_compile_definitions",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -149,7 +149,7 @@
             "importable": "PATH:<BINARY_DIR>/CMakeFiles/export_build_database.dir<CONFIG_DIR>/importable<BMIEXT>"
           },
           "requires": [],
-          "source": "PATH:<SOURCE_DIR>/examples/export-build-database/importable.cxx",
+          "source": "PATH:<SOURCE_DIR>/exp-builddb/importable.cxx",
           "work-directory": "<BINARY_DIR>"
         }
       ],
@@ -167,10 +167,10 @@
             "-Dfrom_compile_definitions",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_OTHER_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -182,7 +182,7 @@
             "PATH:-Ddepflag=\"CMakeFiles/export_build_database.dir<CONFIG_OTHER_DIR>/lib.cxx<OBJEXT>.d\"",
             "PATH:<OUTPUT_FLAG>CMakeFiles/export_build_database.dir<CONFIG_OTHER_DIR>/lib.cxx<OBJEXT>",
             "-c",
-            "PATH:<SOURCE_DIR>/examples/export-build-database/lib.cxx"
+            "PATH:<SOURCE_DIR>/exp-builddb/lib.cxx"
           ],
           "baseline-arguments": [
             "-D_MBCS",
@@ -190,10 +190,10 @@
             "-Dfrom_compile_definitions",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_OTHER_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -209,10 +209,10 @@
             "-Dfrom_compile_definitions",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_OTHER_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -226,7 +226,7 @@
           "private": true,
           "provides": {},
           "requires": ["importable"],
-          "source": "PATH:<SOURCE_DIR>/examples/export-build-database/lib.cxx",
+          "source": "PATH:<SOURCE_DIR>/exp-builddb/lib.cxx",
           "work-directory": "<BINARY_DIR>"
         },
         {
@@ -237,10 +237,10 @@
             "-Dfrom_compile_definitions",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_OTHER_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -254,7 +254,7 @@
             "PATH:-Ddepflag=\"CMakeFiles/export_build_database.dir<CONFIG_OTHER_DIR>/importable.cxx<OBJEXT>.d\"",
             "PATH:<OUTPUT_FLAG>CMakeFiles/export_build_database.dir<CONFIG_OTHER_DIR>/importable.cxx<OBJEXT>",
             "-c",
-            "PATH:<SOURCE_DIR>/examples/export-build-database/importable.cxx"
+            "PATH:<SOURCE_DIR>/exp-builddb/importable.cxx"
           ],
           "baseline-arguments": [
             "-D_MBCS",
@@ -262,10 +262,10 @@
             "-Dfrom_compile_definitions",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_OTHER_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -281,10 +281,10 @@
             "-Dfrom_compile_definitions",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_OTHER_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -302,7 +302,7 @@
             "importable": "PATH:<BINARY_DIR>/CMakeFiles/export_build_database.dir<CONFIG_OTHER_DIR>/importable<BMIEXT>"
           },
           "requires": [],
-          "source": "PATH:<SOURCE_DIR>/examples/export-build-database/importable.cxx",
+          "source": "PATH:<SOURCE_DIR>/exp-builddb/importable.cxx",
           "work-directory": "<BINARY_DIR>"
         }
       ],
diff --git a/Tests/RunCMake/CXXModules/examples/expect/export-build-database-config.json b/Tests/RunCMake/CXXModulesCompile/expect/exp-builddb-cxx.json
similarity index 65%
copy from Tests/RunCMake/CXXModules/examples/expect/export-build-database-config.json
copy to Tests/RunCMake/CXXModulesCompile/expect/exp-builddb-cxx.json
index 3815df5..0253351 100644
--- a/Tests/RunCMake/CXXModules/examples/expect/export-build-database-config.json
+++ b/Tests/RunCMake/CXXModulesCompile/expect/exp-builddb-cxx.json
@@ -14,10 +14,10 @@
             "-Dfrom_compile_definitions",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -29,7 +29,7 @@
             "PATH:-Ddepflag=\"CMakeFiles/export_build_database.dir<CONFIG_DIR>/lib.cxx<OBJEXT>.d\"",
             "PATH:<OUTPUT_FLAG>CMakeFiles/export_build_database.dir<CONFIG_DIR>/lib.cxx<OBJEXT>",
             "-c",
-            "PATH:<SOURCE_DIR>/examples/export-build-database/lib.cxx"
+            "PATH:<SOURCE_DIR>/exp-builddb/lib.cxx"
           ],
           "baseline-arguments": [
             "-D_MBCS",
@@ -37,10 +37,10 @@
             "-Dfrom_compile_definitions",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -56,10 +56,10 @@
             "-Dfrom_compile_definitions",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -73,7 +73,7 @@
           "private": true,
           "provides": {},
           "requires": ["importable"],
-          "source": "PATH:<SOURCE_DIR>/examples/export-build-database/lib.cxx",
+          "source": "PATH:<SOURCE_DIR>/exp-builddb/lib.cxx",
           "work-directory": "<BINARY_DIR>"
         },
         {
@@ -84,10 +84,10 @@
             "-Dfrom_compile_definitions",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -101,7 +101,7 @@
             "PATH:-Ddepflag=\"CMakeFiles/export_build_database.dir<CONFIG_DIR>/importable.cxx<OBJEXT>.d\"",
             "PATH:<OUTPUT_FLAG>CMakeFiles/export_build_database.dir<CONFIG_DIR>/importable.cxx<OBJEXT>",
             "-c",
-            "PATH:<SOURCE_DIR>/examples/export-build-database/importable.cxx"
+            "PATH:<SOURCE_DIR>/exp-builddb/importable.cxx"
           ],
           "baseline-arguments": [
             "-D_MBCS",
@@ -109,10 +109,10 @@
             "-Dfrom_compile_definitions",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -128,10 +128,10 @@
             "-Dfrom_compile_definitions",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -149,7 +149,7 @@
             "importable": "PATH:<BINARY_DIR>/CMakeFiles/export_build_database.dir<CONFIG_DIR>/importable<BMIEXT>"
           },
           "requires": [],
-          "source": "PATH:<SOURCE_DIR>/examples/export-build-database/importable.cxx",
+          "source": "PATH:<SOURCE_DIR>/exp-builddb/importable.cxx",
           "work-directory": "<BINARY_DIR>"
         }
       ],
diff --git a/Tests/RunCMake/CXXModules/examples/expect/export-build-database-imported-all-multi.json b/Tests/RunCMake/CXXModulesCompile/expect/exp-builddb-imped-all-multi.json
similarity index 66%
rename from Tests/RunCMake/CXXModules/examples/expect/export-build-database-imported-all-multi.json
rename to Tests/RunCMake/CXXModulesCompile/expect/exp-builddb-imped-all-multi.json
index de16f8e..cbb5d48 100644
--- a/Tests/RunCMake/CXXModules/examples/expect/export-build-database-imported-all-multi.json
+++ b/Tests/RunCMake/CXXModulesCompile/expect/exp-builddb-imped-all-multi.json
@@ -12,8 +12,8 @@
             "-D_MBCS",
             "-Dtarget_interface_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -22,14 +22,14 @@
             "PATH:-Ddepflag=\"CMakeFiles/use_import_interfaces.dir<CONFIG_DIR>/use.cxx<OBJEXT>.d\"",
             "PATH:<OUTPUT_FLAG>CMakeFiles/use_import_interfaces.dir<CONFIG_DIR>/use.cxx<OBJEXT>",
             "-c",
-            "PATH:<SOURCE_DIR>/examples/import-modules/use.cxx"
+            "PATH:<SOURCE_DIR>/imp-mods/use.cxx"
           ],
           "baseline-arguments": [
             "-D_MBCS",
             "-Dtarget_interface_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -40,8 +40,8 @@
             "-D_MBCS",
             "-Dtarget_interface_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -52,7 +52,7 @@
           "private": true,
           "provides": {},
           "requires": ["importable"],
-          "source": "PATH:<SOURCE_DIR>/examples/import-modules/use.cxx",
+          "source": "PATH:<SOURCE_DIR>/imp-mods/use.cxx",
           "work-directory": "<BINARY_DIR>"
         }
       ],
@@ -68,8 +68,8 @@
             "-D_MBCS",
             "-Dtarget_interface_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_OTHER_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -78,14 +78,14 @@
             "PATH:-Ddepflag=\"CMakeFiles/use_import_interfaces.dir<CONFIG_OTHER_DIR>/use.cxx<OBJEXT>.d\"",
             "PATH:<OUTPUT_FLAG>CMakeFiles/use_import_interfaces.dir<CONFIG_OTHER_DIR>/use.cxx<OBJEXT>",
             "-c",
-            "PATH:<SOURCE_DIR>/examples/import-modules/use.cxx"
+            "PATH:<SOURCE_DIR>/imp-mods/use.cxx"
           ],
           "baseline-arguments": [
             "-D_MBCS",
             "-Dtarget_interface_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_OTHER_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -96,8 +96,8 @@
             "-D_MBCS",
             "-Dtarget_interface_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_OTHER_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -108,7 +108,7 @@
           "private": true,
           "provides": {},
           "requires": ["importable"],
-          "source": "PATH:<SOURCE_DIR>/examples/import-modules/use.cxx",
+          "source": "PATH:<SOURCE_DIR>/imp-mods/use.cxx",
           "work-directory": "<BINARY_DIR>"
         }
       ],
@@ -127,11 +127,11 @@
             "-Dtarget_interface_define",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -144,7 +144,7 @@
             "REGEX:<BMI_ONLY_FLAG>",
             "REGEX:PATH:<OUTPUT_FLAG>CMakeFiles/CXXModules__export_build_database@synth_<HEX>.dir<CONFIG_DIR>/",
             "-c",
-            "PATH:<SOURCE_DIR>/examples/export-build-database/importable.cxx"
+            "PATH:<SOURCE_DIR>/exp-builddb/importable.cxx"
           ],
           "baseline-arguments": [
             "-D_MBCS",
@@ -153,11 +153,11 @@
             "-Dtarget_interface_define",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -174,11 +174,11 @@
             "-Dtarget_interface_define",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -194,7 +194,7 @@
             "importable": "<IGNORE>"
           },
           "requires": [],
-          "source": "PATH:<SOURCE_DIR>/examples/export-build-database/importable.cxx",
+          "source": "PATH:<SOURCE_DIR>/exp-builddb/importable.cxx",
           "work-directory": "<BINARY_DIR>"
         }
       ],
@@ -213,11 +213,11 @@
             "-Dtarget_interface_define",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_OTHER_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -230,7 +230,7 @@
             "REGEX:<BMI_ONLY_FLAG>",
             "REGEX:PATH:<OUTPUT_FLAG>CMakeFiles/CXXModules__export_build_database@synth_<HEX>.dir<CONFIG_OTHER_DIR>/",
             "-c",
-            "PATH:<SOURCE_DIR>/examples/export-build-database/importable.cxx"
+            "PATH:<SOURCE_DIR>/exp-builddb/importable.cxx"
           ],
           "baseline-arguments": [
             "-D_MBCS",
@@ -239,11 +239,11 @@
             "-Dtarget_interface_define",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_OTHER_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -260,11 +260,11 @@
             "-Dtarget_interface_define",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_OTHER_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -280,7 +280,7 @@
             "importable": "<IGNORE>"
           },
           "requires": [],
-          "source": "PATH:<SOURCE_DIR>/examples/export-build-database/importable.cxx",
+          "source": "PATH:<SOURCE_DIR>/exp-builddb/importable.cxx",
           "work-directory": "<BINARY_DIR>"
         }
       ],
diff --git a/Tests/RunCMake/CXXModules/examples/expect/export-build-database-imported-all.json b/Tests/RunCMake/CXXModulesCompile/expect/exp-builddb-imped-all.json
similarity index 66%
rename from Tests/RunCMake/CXXModules/examples/expect/export-build-database-imported-all.json
rename to Tests/RunCMake/CXXModulesCompile/expect/exp-builddb-imped-all.json
index 0e510b8..edcb25a 100644
--- a/Tests/RunCMake/CXXModules/examples/expect/export-build-database-imported-all.json
+++ b/Tests/RunCMake/CXXModulesCompile/expect/exp-builddb-imped-all.json
@@ -12,8 +12,8 @@
             "-D_MBCS",
             "-Dtarget_interface_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -22,14 +22,14 @@
             "PATH:-Ddepflag=\"CMakeFiles/use_import_interfaces.dir<CONFIG_DIR>/use.cxx<OBJEXT>.d\"",
             "PATH:<OUTPUT_FLAG>CMakeFiles/use_import_interfaces.dir<CONFIG_DIR>/use.cxx<OBJEXT>",
             "-c",
-            "PATH:<SOURCE_DIR>/examples/import-modules/use.cxx"
+            "PATH:<SOURCE_DIR>/imp-mods/use.cxx"
           ],
           "baseline-arguments": [
             "-D_MBCS",
             "-Dtarget_interface_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -40,8 +40,8 @@
             "-D_MBCS",
             "-Dtarget_interface_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -52,7 +52,7 @@
           "private": true,
           "provides": {},
           "requires": ["importable"],
-          "source": "PATH:<SOURCE_DIR>/examples/import-modules/use.cxx",
+          "source": "PATH:<SOURCE_DIR>/imp-mods/use.cxx",
           "work-directory": "<BINARY_DIR>"
         }
       ],
@@ -71,11 +71,11 @@
             "-Dtarget_interface_define",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -88,7 +88,7 @@
             "REGEX:<BMI_ONLY_FLAG>",
             "REGEX:PATH:<OUTPUT_FLAG>CMakeFiles/CXXModules__export_build_database@synth_<HEX>.dir<CONFIG_DIR>/",
             "-c",
-            "PATH:<SOURCE_DIR>/examples/export-build-database/importable.cxx"
+            "PATH:<SOURCE_DIR>/exp-builddb/importable.cxx"
           ],
           "baseline-arguments": [
             "-D_MBCS",
@@ -97,11 +97,11 @@
             "-Dtarget_interface_define",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -118,11 +118,11 @@
             "-Dtarget_interface_define",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -138,7 +138,7 @@
             "importable": "<IGNORE>"
           },
           "requires": [],
-          "source": "PATH:<SOURCE_DIR>/examples/export-build-database/importable.cxx",
+          "source": "PATH:<SOURCE_DIR>/exp-builddb/importable.cxx",
           "work-directory": "<BINARY_DIR>"
         }
       ],
diff --git a/Tests/RunCMake/CXXModules/examples/expect/export-build-database-imported-all.json b/Tests/RunCMake/CXXModulesCompile/expect/exp-builddb-imped-config.json
similarity index 66%
copy from Tests/RunCMake/CXXModules/examples/expect/export-build-database-imported-all.json
copy to Tests/RunCMake/CXXModulesCompile/expect/exp-builddb-imped-config.json
index 0e510b8..edcb25a 100644
--- a/Tests/RunCMake/CXXModules/examples/expect/export-build-database-imported-all.json
+++ b/Tests/RunCMake/CXXModulesCompile/expect/exp-builddb-imped-config.json
@@ -12,8 +12,8 @@
             "-D_MBCS",
             "-Dtarget_interface_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -22,14 +22,14 @@
             "PATH:-Ddepflag=\"CMakeFiles/use_import_interfaces.dir<CONFIG_DIR>/use.cxx<OBJEXT>.d\"",
             "PATH:<OUTPUT_FLAG>CMakeFiles/use_import_interfaces.dir<CONFIG_DIR>/use.cxx<OBJEXT>",
             "-c",
-            "PATH:<SOURCE_DIR>/examples/import-modules/use.cxx"
+            "PATH:<SOURCE_DIR>/imp-mods/use.cxx"
           ],
           "baseline-arguments": [
             "-D_MBCS",
             "-Dtarget_interface_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -40,8 +40,8 @@
             "-D_MBCS",
             "-Dtarget_interface_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -52,7 +52,7 @@
           "private": true,
           "provides": {},
           "requires": ["importable"],
-          "source": "PATH:<SOURCE_DIR>/examples/import-modules/use.cxx",
+          "source": "PATH:<SOURCE_DIR>/imp-mods/use.cxx",
           "work-directory": "<BINARY_DIR>"
         }
       ],
@@ -71,11 +71,11 @@
             "-Dtarget_interface_define",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -88,7 +88,7 @@
             "REGEX:<BMI_ONLY_FLAG>",
             "REGEX:PATH:<OUTPUT_FLAG>CMakeFiles/CXXModules__export_build_database@synth_<HEX>.dir<CONFIG_DIR>/",
             "-c",
-            "PATH:<SOURCE_DIR>/examples/export-build-database/importable.cxx"
+            "PATH:<SOURCE_DIR>/exp-builddb/importable.cxx"
           ],
           "baseline-arguments": [
             "-D_MBCS",
@@ -97,11 +97,11 @@
             "-Dtarget_interface_define",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -118,11 +118,11 @@
             "-Dtarget_interface_define",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -138,7 +138,7 @@
             "importable": "<IGNORE>"
           },
           "requires": [],
-          "source": "PATH:<SOURCE_DIR>/examples/export-build-database/importable.cxx",
+          "source": "PATH:<SOURCE_DIR>/exp-builddb/importable.cxx",
           "work-directory": "<BINARY_DIR>"
         }
       ],
diff --git a/Tests/RunCMake/CXXModules/examples/expect/export-build-database-imported-all.json b/Tests/RunCMake/CXXModulesCompile/expect/exp-builddb-imped-cxx-config.json
similarity index 66%
copy from Tests/RunCMake/CXXModules/examples/expect/export-build-database-imported-all.json
copy to Tests/RunCMake/CXXModulesCompile/expect/exp-builddb-imped-cxx-config.json
index 0e510b8..edcb25a 100644
--- a/Tests/RunCMake/CXXModules/examples/expect/export-build-database-imported-all.json
+++ b/Tests/RunCMake/CXXModulesCompile/expect/exp-builddb-imped-cxx-config.json
@@ -12,8 +12,8 @@
             "-D_MBCS",
             "-Dtarget_interface_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -22,14 +22,14 @@
             "PATH:-Ddepflag=\"CMakeFiles/use_import_interfaces.dir<CONFIG_DIR>/use.cxx<OBJEXT>.d\"",
             "PATH:<OUTPUT_FLAG>CMakeFiles/use_import_interfaces.dir<CONFIG_DIR>/use.cxx<OBJEXT>",
             "-c",
-            "PATH:<SOURCE_DIR>/examples/import-modules/use.cxx"
+            "PATH:<SOURCE_DIR>/imp-mods/use.cxx"
           ],
           "baseline-arguments": [
             "-D_MBCS",
             "-Dtarget_interface_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -40,8 +40,8 @@
             "-D_MBCS",
             "-Dtarget_interface_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -52,7 +52,7 @@
           "private": true,
           "provides": {},
           "requires": ["importable"],
-          "source": "PATH:<SOURCE_DIR>/examples/import-modules/use.cxx",
+          "source": "PATH:<SOURCE_DIR>/imp-mods/use.cxx",
           "work-directory": "<BINARY_DIR>"
         }
       ],
@@ -71,11 +71,11 @@
             "-Dtarget_interface_define",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -88,7 +88,7 @@
             "REGEX:<BMI_ONLY_FLAG>",
             "REGEX:PATH:<OUTPUT_FLAG>CMakeFiles/CXXModules__export_build_database@synth_<HEX>.dir<CONFIG_DIR>/",
             "-c",
-            "PATH:<SOURCE_DIR>/examples/export-build-database/importable.cxx"
+            "PATH:<SOURCE_DIR>/exp-builddb/importable.cxx"
           ],
           "baseline-arguments": [
             "-D_MBCS",
@@ -97,11 +97,11 @@
             "-Dtarget_interface_define",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -118,11 +118,11 @@
             "-Dtarget_interface_define",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -138,7 +138,7 @@
             "importable": "<IGNORE>"
           },
           "requires": [],
-          "source": "PATH:<SOURCE_DIR>/examples/export-build-database/importable.cxx",
+          "source": "PATH:<SOURCE_DIR>/exp-builddb/importable.cxx",
           "work-directory": "<BINARY_DIR>"
         }
       ],
diff --git a/Tests/RunCMake/CXXModules/examples/expect/export-build-database-imported-all-multi.json b/Tests/RunCMake/CXXModulesCompile/expect/exp-builddb-imped-cxx-multi.json
similarity index 66%
copy from Tests/RunCMake/CXXModules/examples/expect/export-build-database-imported-all-multi.json
copy to Tests/RunCMake/CXXModulesCompile/expect/exp-builddb-imped-cxx-multi.json
index de16f8e..cbb5d48 100644
--- a/Tests/RunCMake/CXXModules/examples/expect/export-build-database-imported-all-multi.json
+++ b/Tests/RunCMake/CXXModulesCompile/expect/exp-builddb-imped-cxx-multi.json
@@ -12,8 +12,8 @@
             "-D_MBCS",
             "-Dtarget_interface_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -22,14 +22,14 @@
             "PATH:-Ddepflag=\"CMakeFiles/use_import_interfaces.dir<CONFIG_DIR>/use.cxx<OBJEXT>.d\"",
             "PATH:<OUTPUT_FLAG>CMakeFiles/use_import_interfaces.dir<CONFIG_DIR>/use.cxx<OBJEXT>",
             "-c",
-            "PATH:<SOURCE_DIR>/examples/import-modules/use.cxx"
+            "PATH:<SOURCE_DIR>/imp-mods/use.cxx"
           ],
           "baseline-arguments": [
             "-D_MBCS",
             "-Dtarget_interface_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -40,8 +40,8 @@
             "-D_MBCS",
             "-Dtarget_interface_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -52,7 +52,7 @@
           "private": true,
           "provides": {},
           "requires": ["importable"],
-          "source": "PATH:<SOURCE_DIR>/examples/import-modules/use.cxx",
+          "source": "PATH:<SOURCE_DIR>/imp-mods/use.cxx",
           "work-directory": "<BINARY_DIR>"
         }
       ],
@@ -68,8 +68,8 @@
             "-D_MBCS",
             "-Dtarget_interface_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_OTHER_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -78,14 +78,14 @@
             "PATH:-Ddepflag=\"CMakeFiles/use_import_interfaces.dir<CONFIG_OTHER_DIR>/use.cxx<OBJEXT>.d\"",
             "PATH:<OUTPUT_FLAG>CMakeFiles/use_import_interfaces.dir<CONFIG_OTHER_DIR>/use.cxx<OBJEXT>",
             "-c",
-            "PATH:<SOURCE_DIR>/examples/import-modules/use.cxx"
+            "PATH:<SOURCE_DIR>/imp-mods/use.cxx"
           ],
           "baseline-arguments": [
             "-D_MBCS",
             "-Dtarget_interface_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_OTHER_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -96,8 +96,8 @@
             "-D_MBCS",
             "-Dtarget_interface_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_OTHER_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -108,7 +108,7 @@
           "private": true,
           "provides": {},
           "requires": ["importable"],
-          "source": "PATH:<SOURCE_DIR>/examples/import-modules/use.cxx",
+          "source": "PATH:<SOURCE_DIR>/imp-mods/use.cxx",
           "work-directory": "<BINARY_DIR>"
         }
       ],
@@ -127,11 +127,11 @@
             "-Dtarget_interface_define",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -144,7 +144,7 @@
             "REGEX:<BMI_ONLY_FLAG>",
             "REGEX:PATH:<OUTPUT_FLAG>CMakeFiles/CXXModules__export_build_database@synth_<HEX>.dir<CONFIG_DIR>/",
             "-c",
-            "PATH:<SOURCE_DIR>/examples/export-build-database/importable.cxx"
+            "PATH:<SOURCE_DIR>/exp-builddb/importable.cxx"
           ],
           "baseline-arguments": [
             "-D_MBCS",
@@ -153,11 +153,11 @@
             "-Dtarget_interface_define",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -174,11 +174,11 @@
             "-Dtarget_interface_define",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -194,7 +194,7 @@
             "importable": "<IGNORE>"
           },
           "requires": [],
-          "source": "PATH:<SOURCE_DIR>/examples/export-build-database/importable.cxx",
+          "source": "PATH:<SOURCE_DIR>/exp-builddb/importable.cxx",
           "work-directory": "<BINARY_DIR>"
         }
       ],
@@ -213,11 +213,11 @@
             "-Dtarget_interface_define",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_OTHER_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -230,7 +230,7 @@
             "REGEX:<BMI_ONLY_FLAG>",
             "REGEX:PATH:<OUTPUT_FLAG>CMakeFiles/CXXModules__export_build_database@synth_<HEX>.dir<CONFIG_OTHER_DIR>/",
             "-c",
-            "PATH:<SOURCE_DIR>/examples/export-build-database/importable.cxx"
+            "PATH:<SOURCE_DIR>/exp-builddb/importable.cxx"
           ],
           "baseline-arguments": [
             "-D_MBCS",
@@ -239,11 +239,11 @@
             "-Dtarget_interface_define",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_OTHER_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -260,11 +260,11 @@
             "-Dtarget_interface_define",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_OTHER_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -280,7 +280,7 @@
             "importable": "<IGNORE>"
           },
           "requires": [],
-          "source": "PATH:<SOURCE_DIR>/examples/export-build-database/importable.cxx",
+          "source": "PATH:<SOURCE_DIR>/exp-builddb/importable.cxx",
           "work-directory": "<BINARY_DIR>"
         }
       ],
diff --git a/Tests/RunCMake/CXXModules/examples/expect/export-build-database-imported-all.json b/Tests/RunCMake/CXXModulesCompile/expect/exp-builddb-imped-cxx.json
similarity index 66%
copy from Tests/RunCMake/CXXModules/examples/expect/export-build-database-imported-all.json
copy to Tests/RunCMake/CXXModulesCompile/expect/exp-builddb-imped-cxx.json
index 0e510b8..edcb25a 100644
--- a/Tests/RunCMake/CXXModules/examples/expect/export-build-database-imported-all.json
+++ b/Tests/RunCMake/CXXModulesCompile/expect/exp-builddb-imped-cxx.json
@@ -12,8 +12,8 @@
             "-D_MBCS",
             "-Dtarget_interface_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -22,14 +22,14 @@
             "PATH:-Ddepflag=\"CMakeFiles/use_import_interfaces.dir<CONFIG_DIR>/use.cxx<OBJEXT>.d\"",
             "PATH:<OUTPUT_FLAG>CMakeFiles/use_import_interfaces.dir<CONFIG_DIR>/use.cxx<OBJEXT>",
             "-c",
-            "PATH:<SOURCE_DIR>/examples/import-modules/use.cxx"
+            "PATH:<SOURCE_DIR>/imp-mods/use.cxx"
           ],
           "baseline-arguments": [
             "-D_MBCS",
             "-Dtarget_interface_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -40,8 +40,8 @@
             "-D_MBCS",
             "-Dtarget_interface_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -52,7 +52,7 @@
           "private": true,
           "provides": {},
           "requires": ["importable"],
-          "source": "PATH:<SOURCE_DIR>/examples/import-modules/use.cxx",
+          "source": "PATH:<SOURCE_DIR>/imp-mods/use.cxx",
           "work-directory": "<BINARY_DIR>"
         }
       ],
@@ -71,11 +71,11 @@
             "-Dtarget_interface_define",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -88,7 +88,7 @@
             "REGEX:<BMI_ONLY_FLAG>",
             "REGEX:PATH:<OUTPUT_FLAG>CMakeFiles/CXXModules__export_build_database@synth_<HEX>.dir<CONFIG_DIR>/",
             "-c",
-            "PATH:<SOURCE_DIR>/examples/export-build-database/importable.cxx"
+            "PATH:<SOURCE_DIR>/exp-builddb/importable.cxx"
           ],
           "baseline-arguments": [
             "-D_MBCS",
@@ -97,11 +97,11 @@
             "-Dtarget_interface_define",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -118,11 +118,11 @@
             "-Dtarget_interface_define",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -138,7 +138,7 @@
             "importable": "<IGNORE>"
           },
           "requires": [],
-          "source": "PATH:<SOURCE_DIR>/examples/export-build-database/importable.cxx",
+          "source": "PATH:<SOURCE_DIR>/exp-builddb/importable.cxx",
           "work-directory": "<BINARY_DIR>"
         }
       ],
diff --git a/Tests/RunCMake/CXXModules/examples/expect/export-build-database-imported-target.json b/Tests/RunCMake/CXXModulesCompile/expect/exp-builddb-imped-target.json
similarity index 72%
rename from Tests/RunCMake/CXXModules/examples/expect/export-build-database-imported-target.json
rename to Tests/RunCMake/CXXModulesCompile/expect/exp-builddb-imped-target.json
index 1435edc..1263ef0 100644
--- a/Tests/RunCMake/CXXModules/examples/expect/export-build-database-imported-target.json
+++ b/Tests/RunCMake/CXXModulesCompile/expect/exp-builddb-imped-target.json
@@ -12,8 +12,8 @@
             "-D_MBCS",
             "-Dtarget_interface_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -22,14 +22,14 @@
             "PATH:-Ddepflag=\"CMakeFiles/use_import_interfaces.dir<CONFIG_DIR>/use.cxx<OBJEXT>.d\"",
             "PATH:<OUTPUT_FLAG>CMakeFiles/use_import_interfaces.dir<CONFIG_DIR>/use.cxx<OBJEXT>",
             "-c",
-            "PATH:<SOURCE_DIR>/examples/import-modules/use.cxx"
+            "PATH:<SOURCE_DIR>/imp-mods/use.cxx"
           ],
           "baseline-arguments": [
             "-D_MBCS",
             "-Dtarget_interface_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -40,8 +40,8 @@
             "-D_MBCS",
             "-Dtarget_interface_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_interface_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -52,7 +52,7 @@
           "private": true,
           "provides": {},
           "requires": ["importable"],
-          "source": "PATH:<SOURCE_DIR>/examples/import-modules/use.cxx",
+          "source": "PATH:<SOURCE_DIR>/imp-mods/use.cxx",
           "work-directory": "<BINARY_DIR>"
         }
       ],
diff --git a/Tests/RunCMake/CXXModules/examples/expect/export-build-database-all.json b/Tests/RunCMake/CXXModulesCompile/expect/exp-builddb-target.json
similarity index 65%
copy from Tests/RunCMake/CXXModules/examples/expect/export-build-database-all.json
copy to Tests/RunCMake/CXXModulesCompile/expect/exp-builddb-target.json
index 4412d35..9b13bd0 100644
--- a/Tests/RunCMake/CXXModules/examples/expect/export-build-database-all.json
+++ b/Tests/RunCMake/CXXModulesCompile/expect/exp-builddb-target.json
@@ -14,10 +14,10 @@
             "-Dfrom_compile_definitions",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -29,7 +29,7 @@
             "PATH:-Ddepflag=\"CMakeFiles/export_build_database.dir<CONFIG_DIR>/lib.cxx<OBJEXT>.d\"",
             "PATH:<OUTPUT_FLAG>CMakeFiles/export_build_database.dir<CONFIG_DIR>/lib.cxx<OBJEXT>",
             "-c",
-            "PATH:<SOURCE_DIR>/examples/export-build-database/lib.cxx"
+            "PATH:<SOURCE_DIR>/exp-builddb/lib.cxx"
           ],
           "baseline-arguments": [
             "-D_MBCS",
@@ -37,10 +37,10 @@
             "-Dfrom_compile_definitions",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -56,10 +56,10 @@
             "-Dfrom_compile_definitions",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -73,7 +73,7 @@
           "private": true,
           "provides": {},
           "requires": ["importable"],
-          "source": "PATH:<SOURCE_DIR>/examples/export-build-database/lib.cxx",
+          "source": "PATH:<SOURCE_DIR>/exp-builddb/lib.cxx",
           "work-directory": "<BINARY_DIR>"
         },
         {
@@ -84,10 +84,10 @@
             "-Dfrom_compile_definitions",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -101,7 +101,7 @@
             "PATH:-Ddepflag=\"CMakeFiles/export_build_database.dir<CONFIG_DIR>/importable.cxx<OBJEXT>.d\"",
             "PATH:<OUTPUT_FLAG>CMakeFiles/export_build_database.dir<CONFIG_DIR>/importable.cxx<OBJEXT>",
             "-c",
-            "PATH:<SOURCE_DIR>/examples/export-build-database/importable.cxx"
+            "PATH:<SOURCE_DIR>/exp-builddb/importable.cxx"
           ],
           "baseline-arguments": [
             "-D_MBCS",
@@ -109,10 +109,10 @@
             "-Dfrom_compile_definitions",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -128,10 +128,10 @@
             "-Dfrom_compile_definitions",
             "-Dtarget_private_define",
             "-Dtarget_public_define",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/from_include_directories",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_private_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/target_public_include",
-            "PATH:-I<SOURCE_DIR>/examples/export-build-database/dep_interface_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/from_include_directories",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_private_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/target_public_include",
+            "PATH:-I<SOURCE_DIR>/exp-builddb/dep_interface_include",
             "-Dfrom_cmake_cxx_flags",
             "-Dfrom_cmake_cxx_<CONFIG_LOWER>_flags",
             "<CXX20_OPTION>",
@@ -149,7 +149,7 @@
             "importable": "<BINARY_DIR>/CMakeFiles/export_build_database.dir<CONFIG_DIR>/importable<BMIEXT>"
           },
           "requires": [],
-          "source": "PATH:<SOURCE_DIR>/examples/export-build-database/importable.cxx",
+          "source": "PATH:<SOURCE_DIR>/exp-builddb/importable.cxx",
           "work-directory": "<BINARY_DIR>"
         }
       ],
diff --git a/Tests/RunCMake/CXXModules/examples/export-build-database-setup.cmake b/Tests/RunCMake/CXXModulesCompile/export-build-database-setup.cmake
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/export-build-database-setup.cmake
rename to Tests/RunCMake/CXXModulesCompile/export-build-database-setup.cmake
diff --git a/Tests/RunCMake/CXXModules/examples/file-sets-with-dot/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/file-sets-with-dot/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/file-sets-with-dot/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/file-sets-with-dot/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/file-sets-with-dot/importable.cxx b/Tests/RunCMake/CXXModulesCompile/file-sets-with-dot/importable.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/file-sets-with-dot/importable.cxx
rename to Tests/RunCMake/CXXModulesCompile/file-sets-with-dot/importable.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/file-sets-with-dot/main.cxx b/Tests/RunCMake/CXXModulesCompile/file-sets-with-dot/main.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/file-sets-with-dot/main.cxx
rename to Tests/RunCMake/CXXModulesCompile/file-sets-with-dot/main.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/generated/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/generated/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/generated/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/generated/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/generated/importable.cxx.in b/Tests/RunCMake/CXXModulesCompile/generated/importable.cxx.in
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/generated/importable.cxx.in
rename to Tests/RunCMake/CXXModulesCompile/generated/importable.cxx.in
diff --git a/Tests/RunCMake/CXXModules/examples/generated/main.cxx b/Tests/RunCMake/CXXModulesCompile/generated/main.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/generated/main.cxx
rename to Tests/RunCMake/CXXModulesCompile/generated/main.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/import-from-object/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/imp-from-object/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/import-from-object/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/imp-from-object/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/import-from-object/object-a.cxx b/Tests/RunCMake/CXXModulesCompile/imp-from-object/object-a.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/import-from-object/object-a.cxx
rename to Tests/RunCMake/CXXModulesCompile/imp-from-object/object-a.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/import-from-object/object-b.cxx b/Tests/RunCMake/CXXModulesCompile/imp-from-object/object-b.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/import-from-object/object-b.cxx
rename to Tests/RunCMake/CXXModulesCompile/imp-from-object/object-b.cxx
diff --git a/Tests/RunCMake/CXXModulesCompile/imp-mods-exp-builddb-build-check.cmake b/Tests/RunCMake/CXXModulesCompile/imp-mods-exp-builddb-build-check.cmake
new file mode 100644
index 0000000..9612fdb
--- /dev/null
+++ b/Tests/RunCMake/CXXModulesCompile/imp-mods-exp-builddb-build-check.cmake
@@ -0,0 +1,18 @@
+include("${CMAKE_CURRENT_LIST_DIR}/build-database-check.cmake")
+set(item_filter "-ifcOnly")
+
+check_build_database("exp-builddb-imped" "build_database.json" NO_EXIST)
+check_build_database("exp-builddb-imped" "build_database_CXX.json" NO_EXIST)
+if (RunCMake_GENERATOR_IS_MULTI_CONFIG)
+  check_build_database("exp-builddb-imped" "build_database_CXX_Debug.json" NO_EXIST)
+  check_build_database("exp-builddb-imped" "build_database_Debug.json" NO_EXIST)
+  check_build_database("exp-builddb-imped" "CMakeFiles/export-module-commands.dir/Debug/CXX_build_database.json" NO_EXIST)
+
+  check_build_database("exp-builddb-imped" "build_database_CXX_Release.json" NO_EXIST)
+  check_build_database("exp-builddb-imped" "build_database_Release.json" NO_EXIST)
+  check_build_database("exp-builddb-imped" "CMakeFiles/export-module-commands.dir/Release/CXX_build_database.json" NO_EXIST)
+else ()
+  check_build_database("exp-builddb-imped" "CMakeFiles/export-module-commands.dir/CXX_build_database.json" NO_EXIST)
+endif ()
+
+string(REPLACE ";" "\n  " RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}")
diff --git a/Tests/RunCMake/CXXModulesCompile/imp-mods-exp-builddb-check.cmake b/Tests/RunCMake/CXXModulesCompile/imp-mods-exp-builddb-check.cmake
new file mode 100644
index 0000000..9612fdb
--- /dev/null
+++ b/Tests/RunCMake/CXXModulesCompile/imp-mods-exp-builddb-check.cmake
@@ -0,0 +1,18 @@
+include("${CMAKE_CURRENT_LIST_DIR}/build-database-check.cmake")
+set(item_filter "-ifcOnly")
+
+check_build_database("exp-builddb-imped" "build_database.json" NO_EXIST)
+check_build_database("exp-builddb-imped" "build_database_CXX.json" NO_EXIST)
+if (RunCMake_GENERATOR_IS_MULTI_CONFIG)
+  check_build_database("exp-builddb-imped" "build_database_CXX_Debug.json" NO_EXIST)
+  check_build_database("exp-builddb-imped" "build_database_Debug.json" NO_EXIST)
+  check_build_database("exp-builddb-imped" "CMakeFiles/export-module-commands.dir/Debug/CXX_build_database.json" NO_EXIST)
+
+  check_build_database("exp-builddb-imped" "build_database_CXX_Release.json" NO_EXIST)
+  check_build_database("exp-builddb-imped" "build_database_Release.json" NO_EXIST)
+  check_build_database("exp-builddb-imped" "CMakeFiles/export-module-commands.dir/Release/CXX_build_database.json" NO_EXIST)
+else ()
+  check_build_database("exp-builddb-imped" "CMakeFiles/export-module-commands.dir/CXX_build_database.json" NO_EXIST)
+endif ()
+
+string(REPLACE ";" "\n  " RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}")
diff --git a/Tests/RunCMake/CXXModules/examples/export-build-database-stderr.txt b/Tests/RunCMake/CXXModulesCompile/imp-mods-exp-builddb-stderr.txt
similarity index 100%
copy from Tests/RunCMake/CXXModules/examples/export-build-database-stderr.txt
copy to Tests/RunCMake/CXXModulesCompile/imp-mods-exp-builddb-stderr.txt
diff --git a/Tests/RunCMake/CXXModulesCompile/imp-mods-exp-builddb-target-cmake_build_database-check.cmake b/Tests/RunCMake/CXXModulesCompile/imp-mods-exp-builddb-target-cmake_build_database-check.cmake
new file mode 100644
index 0000000..518c20b
--- /dev/null
+++ b/Tests/RunCMake/CXXModulesCompile/imp-mods-exp-builddb-target-cmake_build_database-check.cmake
@@ -0,0 +1,22 @@
+include("${CMAKE_CURRENT_LIST_DIR}/build-database-check.cmake")
+set(item_filter "-ifcOnly")
+
+if (RunCMake_GENERATOR_IS_MULTI_CONFIG)
+  check_build_database("exp-builddb-imped" "build_database.json" ALL_MULTI)
+  check_build_database("exp-builddb-imped" "build_database_CXX.json" JUST_CXX_MULTI)
+
+  check_build_database("exp-builddb-imped" "build_database_CXX_Debug.json" CXX_AND_DEBUG)
+  check_build_database("exp-builddb-imped" "build_database_Debug.json" JUST_DEBUG)
+  check_build_database("exp-builddb-imped" "CMakeFiles/use_import_interfaces.dir/Debug/CXX_build_database.json" JUST_TARGET_DEBUG)
+
+  check_build_database("exp-builddb-imped" "build_database_CXX_Release.json" CXX_AND_RELEASE)
+  check_build_database("exp-builddb-imped" "build_database_Release.json" JUST_RELEASE)
+  check_build_database("exp-builddb-imped" "CMakeFiles/use_import_interfaces.dir/Release/CXX_build_database.json" JUST_TARGET_RELEASE)
+else ()
+  check_build_database("exp-builddb-imped" "build_database.json" ALL)
+  check_build_database("exp-builddb-imped" "build_database_CXX.json" JUST_CXX)
+
+  check_build_database("exp-builddb-imped" "CMakeFiles/use_import_interfaces.dir/CXX_build_database.json" JUST_TARGET)
+endif ()
+
+string(REPLACE ";" "\n  " RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}")
diff --git a/Tests/RunCMake/CXXModulesCompile/imp-mods-exp-builddb-target-cmake_build_database/CXX-check.cmake b/Tests/RunCMake/CXXModulesCompile/imp-mods-exp-builddb-target-cmake_build_database/CXX-check.cmake
new file mode 100644
index 0000000..4cfe667
--- /dev/null
+++ b/Tests/RunCMake/CXXModulesCompile/imp-mods-exp-builddb-target-cmake_build_database/CXX-check.cmake
@@ -0,0 +1,22 @@
+include("${CMAKE_CURRENT_LIST_DIR}/../build-database-check.cmake")
+set(item_filter "-ifcOnly")
+
+check_build_database("exp-builddb-imped" "build_database.json" NO_EXIST)
+
+if (RunCMake_GENERATOR_IS_MULTI_CONFIG)
+  check_build_database("exp-builddb-imped" "build_database_CXX.json" JUST_CXX_MULTI)
+
+  check_build_database("exp-builddb-imped" "build_database_CXX_Debug.json" CXX_AND_DEBUG)
+  check_build_database("exp-builddb-imped" "build_database_Debug.json" JUST_DEBUG)
+  check_build_database("exp-builddb-imped" "CMakeFiles/use_import_interfaces.dir/Debug/CXX_build_database.json" JUST_TARGET_DEBUG)
+
+  check_build_database("exp-builddb-imped" "build_database_CXX_Release.json" CXX_AND_RELEASE)
+  check_build_database("exp-builddb-imped" "build_database_Release.json" JUST_RELEASE)
+  check_build_database("exp-builddb-imped" "CMakeFiles/use_import_interfaces.dir/Release/CXX_build_database.json" JUST_TARGET_RELEASE)
+else ()
+  check_build_database("exp-builddb-imped" "build_database_CXX.json" JUST_CXX)
+
+  check_build_database("exp-builddb-imped" "CMakeFiles/use_import_interfaces.dir/CXX_build_database.json" JUST_TARGET)
+endif ()
+
+string(REPLACE ";" "\n  " RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}")
diff --git a/Tests/RunCMake/CXXModulesCompile/imp-mods-exp-builddb-target-cmake_build_database/CXX/Debug-check.cmake b/Tests/RunCMake/CXXModulesCompile/imp-mods-exp-builddb-target-cmake_build_database/CXX/Debug-check.cmake
new file mode 100644
index 0000000..05e542f
--- /dev/null
+++ b/Tests/RunCMake/CXXModulesCompile/imp-mods-exp-builddb-target-cmake_build_database/CXX/Debug-check.cmake
@@ -0,0 +1,19 @@
+include("${CMAKE_CURRENT_LIST_DIR}/../../build-database-check.cmake")
+set(item_filter "-ifcOnly")
+
+check_build_database("exp-builddb-imped" "build_database.json" NO_EXIST)
+check_build_database("exp-builddb-imped" "build_database_CXX.json" NO_EXIST)
+
+if (RunCMake_GENERATOR_IS_MULTI_CONFIG)
+  check_build_database("exp-builddb-imped" "build_database_CXX_Debug.json" CXX_AND_DEBUG)
+  check_build_database("exp-builddb-imped" "build_database_Debug.json" NO_EXIST)
+  check_build_database("exp-builddb-imped" "CMakeFiles/use_import_interfaces.dir/Debug/CXX_build_database.json" JUST_TARGET_DEBUG)
+
+  check_build_database("exp-builddb-imped" "build_database_CXX_Release.json" NO_EXIST)
+  check_build_database("exp-builddb-imped" "build_database_Release.json" NO_EXIST)
+  check_build_database("exp-builddb-imped" "CMakeFiles/use_import_interfaces.dir/Release/CXX_build_database.json" NO_EXIST)
+else ()
+  check_build_database("exp-builddb-imped" "CMakeFiles/use_import_interfaces.dir/CXX_build_database.json" JUST_TARGET)
+endif ()
+
+string(REPLACE ";" "\n  " RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}")
diff --git a/Tests/RunCMake/CXXModulesCompile/imp-mods-exp-builddb-target-cmake_build_database/CXX/Release-Release-check.cmake b/Tests/RunCMake/CXXModulesCompile/imp-mods-exp-builddb-target-cmake_build_database/CXX/Release-Release-check.cmake
new file mode 100644
index 0000000..5ff723c
--- /dev/null
+++ b/Tests/RunCMake/CXXModulesCompile/imp-mods-exp-builddb-target-cmake_build_database/CXX/Release-Release-check.cmake
@@ -0,0 +1,19 @@
+include("${CMAKE_CURRENT_LIST_DIR}/../../build-database-check.cmake")
+set(item_filter "-ifcOnly")
+
+check_build_database("exp-builddb-imped" "build_database.json" NO_EXIST)
+check_build_database("exp-builddb-imped" "build_database_CXX.json" NO_EXIST)
+
+if (RunCMake_GENERATOR_IS_MULTI_CONFIG)
+  check_build_database("exp-builddb-imped" "build_database_CXX_Debug.json" CXX_AND_DEBUG)
+  check_build_database("exp-builddb-imped" "build_database_Debug.json" JUST_DEBUG)
+  check_build_database("exp-builddb-imped" "CMakeFiles/use_import_interfaces.dir/Debug/CXX_build_database.json" JUST_TARGET_DEBUG)
+
+  check_build_database("exp-builddb-imped" "build_database_CXX_Release.json" CXX_AND_RELEASE)
+  check_build_database("exp-builddb-imped" "build_database_Release.json" NO_EXIST)
+  check_build_database("exp-builddb-imped" "CMakeFiles/use_import_interfaces.dir/Release/CXX_build_database.json" JUST_TARGET_RELEASE)
+else ()
+  check_build_database("exp-builddb-imped" "CMakeFiles/use_import_interfaces.dir/CXX_build_database.json" JUST_TARGET)
+endif ()
+
+string(REPLACE ";" "\n  " RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}")
diff --git a/Tests/RunCMake/CXXModulesCompile/imp-mods-exp-builddb-target-cmake_build_database/Debug-check.cmake b/Tests/RunCMake/CXXModulesCompile/imp-mods-exp-builddb-target-cmake_build_database/Debug-check.cmake
new file mode 100644
index 0000000..7a7598e
--- /dev/null
+++ b/Tests/RunCMake/CXXModulesCompile/imp-mods-exp-builddb-target-cmake_build_database/Debug-check.cmake
@@ -0,0 +1,19 @@
+include("${CMAKE_CURRENT_LIST_DIR}/../build-database-check.cmake")
+set(item_filter "-ifcOnly")
+
+check_build_database("exp-builddb-imped" "build_database.json" NO_EXIST)
+check_build_database("exp-builddb-imped" "build_database_CXX.json" NO_EXIST)
+
+if (RunCMake_GENERATOR_IS_MULTI_CONFIG)
+  check_build_database("exp-builddb-imped" "build_database_CXX_Debug.json" CXX_AND_DEBUG)
+  check_build_database("exp-builddb-imped" "build_database_Debug.json" JUST_DEBUG)
+  check_build_database("exp-builddb-imped" "CMakeFiles/use_import_interfaces.dir/Debug/CXX_build_database.json" JUST_TARGET_DEBUG)
+
+  check_build_database("exp-builddb-imped" "build_database_CXX_Release.json" NO_EXIST)
+  check_build_database("exp-builddb-imped" "build_database_Release.json" NO_EXIST)
+  check_build_database("exp-builddb-imped" "CMakeFiles/use_import_interfaces.dir/Release/CXX_build_database.json" NO_EXIST)
+else ()
+  check_build_database("exp-builddb-imped" "CMakeFiles/use_import_interfaces.dir/CXX_build_database.json" JUST_TARGET)
+endif ()
+
+string(REPLACE ";" "\n  " RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}")
diff --git a/Tests/RunCMake/CXXModulesCompile/imp-mods-exp-builddb-target-cmake_build_database/Release-check.cmake b/Tests/RunCMake/CXXModulesCompile/imp-mods-exp-builddb-target-cmake_build_database/Release-check.cmake
new file mode 100644
index 0000000..1ea6a23
--- /dev/null
+++ b/Tests/RunCMake/CXXModulesCompile/imp-mods-exp-builddb-target-cmake_build_database/Release-check.cmake
@@ -0,0 +1,19 @@
+include("${CMAKE_CURRENT_LIST_DIR}/../build-database-check.cmake")
+set(item_filter "-ifcOnly")
+
+check_build_database("exp-builddb-imped" "build_database.json" NO_EXIST)
+check_build_database("exp-builddb-imped" "build_database_CXX.json" JUST_CXX)
+
+if (RunCMake_GENERATOR_IS_MULTI_CONFIG)
+  check_build_database("exp-builddb-imped" "build_database_CXX_Debug.json" CXX_AND_DEBUG)
+  check_build_database("exp-builddb-imped" "build_database_Debug.json" JUST_DEBUG)
+  check_build_database("exp-builddb-imped" "CMakeFiles/use_import_interfaces.dir/Debug/CXX_build_database.json" JUST_TARGET_DEBUG)
+
+  check_build_database("exp-builddb-imped" "build_database_CXX_Release.json" CXX_AND_RELEASE)
+  check_build_database("exp-builddb-imped" "build_database_Release.json" JUST_RELEASE)
+  check_build_database("exp-builddb-imped" "CMakeFiles/use_import_interfaces.dir/Release/CXX_build_database.json" JUST_TARGET_RELEASE)
+else ()
+  check_build_database("exp-builddb-imped" "CMakeFiles/use_import_interfaces.dir/CXX_build_database.json" JUST_TARGET)
+endif ()
+
+string(REPLACE ";" "\n  " RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}")
diff --git a/Tests/RunCMake/CXXModules/examples/import-modules/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/imp-mods/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/import-modules/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/imp-mods/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/import-modules/use.cxx b/Tests/RunCMake/CXXModulesCompile/imp-mods/use.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/import-modules/use.cxx
rename to Tests/RunCMake/CXXModulesCompile/imp-mods/use.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-build-stderr.txt b/Tests/RunCMake/CXXModulesCompile/imp-std-exp-no-std-build-stderr.txt
similarity index 95%
rename from Tests/RunCMake/CXXModules/examples/import-std-export-no-std-build-stderr.txt
rename to Tests/RunCMake/CXXModulesCompile/imp-std-exp-no-std-build-stderr.txt
index 583556f..f7d2858 100644
--- a/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-build-stderr.txt
+++ b/Tests/RunCMake/CXXModulesCompile/imp-std-exp-no-std-build-stderr.txt
@@ -2,7 +2,7 @@
   CMake's support for `import std;` in C\+\+23 and newer is experimental\.  It
   is meant only for experimentation and feedback to CMake developers\.
 Call Stack \(most recent call first\):
-  .*/Modules/CMakeDetermineCompilerSupport\.cmake:[0-9]* \(cmake_create_cxx_import_std\)
+  .*/Modules/CMakeDetermineCompilerSupport\.cmake:[0-9]* \(cmake_cxx_find_modules_json\)
   .*/Modules/CMakeTestCXXCompiler\.cmake:[0-9]* \(CMAKE_DETERMINE_COMPILER_SUPPORT\)
   CMakeLists\.txt:[0-9]* \(project\)
 This warning is for project developers\.  Use -Wno-dev to suppress it\.
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-build/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/imp-std-exp-no-std-build/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/import-std-export-no-std-build/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/imp-std-exp-no-std-build/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-build/impl-uses-std.cxx b/Tests/RunCMake/CXXModulesCompile/imp-std-exp-no-std-build/impl-uses-std.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/import-std-export-no-std-build/impl-uses-std.cxx
rename to Tests/RunCMake/CXXModulesCompile/imp-std-exp-no-std-build/impl-uses-std.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-build/main.cxx b/Tests/RunCMake/CXXModulesCompile/imp-std-exp-no-std-build/main.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/import-std-export-no-std-build/main.cxx
rename to Tests/RunCMake/CXXModulesCompile/imp-std-exp-no-std-build/main.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-build/test/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/imp-std-exp-no-std-build/test/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/import-std-export-no-std-build/test/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/imp-std-exp-no-std-build/test/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-build/uses-std.cxx b/Tests/RunCMake/CXXModulesCompile/imp-std-exp-no-std-build/uses-std.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/import-std-export-no-std-build/uses-std.cxx
rename to Tests/RunCMake/CXXModulesCompile/imp-std-exp-no-std-build/uses-std.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-build-stderr.txt b/Tests/RunCMake/CXXModulesCompile/imp-std-exp-no-std-install-stderr.txt
similarity index 95%
copy from Tests/RunCMake/CXXModules/examples/import-std-export-no-std-build-stderr.txt
copy to Tests/RunCMake/CXXModulesCompile/imp-std-exp-no-std-install-stderr.txt
index 583556f..f7d2858 100644
--- a/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-build-stderr.txt
+++ b/Tests/RunCMake/CXXModulesCompile/imp-std-exp-no-std-install-stderr.txt
@@ -2,7 +2,7 @@
   CMake's support for `import std;` in C\+\+23 and newer is experimental\.  It
   is meant only for experimentation and feedback to CMake developers\.
 Call Stack \(most recent call first\):
-  .*/Modules/CMakeDetermineCompilerSupport\.cmake:[0-9]* \(cmake_create_cxx_import_std\)
+  .*/Modules/CMakeDetermineCompilerSupport\.cmake:[0-9]* \(cmake_cxx_find_modules_json\)
   .*/Modules/CMakeTestCXXCompiler\.cmake:[0-9]* \(CMAKE_DETERMINE_COMPILER_SUPPORT\)
   CMakeLists\.txt:[0-9]* \(project\)
 This warning is for project developers\.  Use -Wno-dev to suppress it\.
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-install/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/imp-std-exp-no-std-install/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/import-std-export-no-std-install/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/imp-std-exp-no-std-install/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-install/impl-uses-std.cxx b/Tests/RunCMake/CXXModulesCompile/imp-std-exp-no-std-install/impl-uses-std.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/import-std-export-no-std-install/impl-uses-std.cxx
rename to Tests/RunCMake/CXXModulesCompile/imp-std-exp-no-std-install/impl-uses-std.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-install/main.cxx b/Tests/RunCMake/CXXModulesCompile/imp-std-exp-no-std-install/main.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/import-std-export-no-std-install/main.cxx
rename to Tests/RunCMake/CXXModulesCompile/imp-std-exp-no-std-install/main.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-install/test/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/imp-std-exp-no-std-install/test/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/import-std-export-no-std-install/test/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/imp-std-exp-no-std-install/test/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-install/uses-std.cxx b/Tests/RunCMake/CXXModulesCompile/imp-std-exp-no-std-install/uses-std.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/import-std-export-no-std-install/uses-std.cxx
rename to Tests/RunCMake/CXXModulesCompile/imp-std-exp-no-std-install/uses-std.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-no-std-property-build-result.txt b/Tests/RunCMake/CXXModulesCompile/imp-std-no-std-prop-build-result.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/import-std-no-std-property-build-result.txt
rename to Tests/RunCMake/CXXModulesCompile/imp-std-no-std-prop-build-result.txt
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-no-std-property-build-stdout.txt b/Tests/RunCMake/CXXModulesCompile/imp-std-no-std-prop-build-stdout.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/import-std-no-std-property-build-stdout.txt
rename to Tests/RunCMake/CXXModulesCompile/imp-std-no-std-prop-build-stdout.txt
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-build-stderr.txt b/Tests/RunCMake/CXXModulesCompile/imp-std-no-std-prop-stderr.txt
similarity index 95%
copy from Tests/RunCMake/CXXModules/examples/import-std-export-no-std-build-stderr.txt
copy to Tests/RunCMake/CXXModulesCompile/imp-std-no-std-prop-stderr.txt
index 583556f..f7d2858 100644
--- a/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-build-stderr.txt
+++ b/Tests/RunCMake/CXXModulesCompile/imp-std-no-std-prop-stderr.txt
@@ -2,7 +2,7 @@
   CMake's support for `import std;` in C\+\+23 and newer is experimental\.  It
   is meant only for experimentation and feedback to CMake developers\.
 Call Stack \(most recent call first\):
-  .*/Modules/CMakeDetermineCompilerSupport\.cmake:[0-9]* \(cmake_create_cxx_import_std\)
+  .*/Modules/CMakeDetermineCompilerSupport\.cmake:[0-9]* \(cmake_cxx_find_modules_json\)
   .*/Modules/CMakeTestCXXCompiler\.cmake:[0-9]* \(CMAKE_DETERMINE_COMPILER_SUPPORT\)
   CMakeLists\.txt:[0-9]* \(project\)
 This warning is for project developers\.  Use -Wno-dev to suppress it\.
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-no-std-property/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/imp-std-no-std-prop/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/import-std-no-std-property/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/imp-std-no-std-prop/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-no-std-property/main.cxx b/Tests/RunCMake/CXXModulesCompile/imp-std-no-std-prop/main.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/import-std-no-std-property/main.cxx
rename to Tests/RunCMake/CXXModulesCompile/imp-std-no-std-prop/main.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-build-stderr.txt b/Tests/RunCMake/CXXModulesCompile/imp-std-not-in-exp-build-stderr.txt
similarity index 95%
copy from Tests/RunCMake/CXXModules/examples/import-std-export-no-std-build-stderr.txt
copy to Tests/RunCMake/CXXModulesCompile/imp-std-not-in-exp-build-stderr.txt
index 583556f..f7d2858 100644
--- a/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-build-stderr.txt
+++ b/Tests/RunCMake/CXXModulesCompile/imp-std-not-in-exp-build-stderr.txt
@@ -2,7 +2,7 @@
   CMake's support for `import std;` in C\+\+23 and newer is experimental\.  It
   is meant only for experimentation and feedback to CMake developers\.
 Call Stack \(most recent call first\):
-  .*/Modules/CMakeDetermineCompilerSupport\.cmake:[0-9]* \(cmake_create_cxx_import_std\)
+  .*/Modules/CMakeDetermineCompilerSupport\.cmake:[0-9]* \(cmake_cxx_find_modules_json\)
   .*/Modules/CMakeTestCXXCompiler\.cmake:[0-9]* \(CMAKE_DETERMINE_COMPILER_SUPPORT\)
   CMakeLists\.txt:[0-9]* \(project\)
 This warning is for project developers\.  Use -Wno-dev to suppress it\.
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-not-in-export-build/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/imp-std-not-in-exp-build/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/import-std-not-in-export-build/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/imp-std-not-in-exp-build/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-build/main.cxx b/Tests/RunCMake/CXXModulesCompile/imp-std-not-in-exp-build/main.cxx
similarity index 100%
copy from Tests/RunCMake/CXXModules/examples/import-std-export-no-std-build/main.cxx
copy to Tests/RunCMake/CXXModulesCompile/imp-std-not-in-exp-build/main.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-not-in-export-build/test/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/imp-std-not-in-exp-build/test/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/import-std-not-in-export-build/test/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/imp-std-not-in-exp-build/test/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-not-in-export-build/uses-std.cxx b/Tests/RunCMake/CXXModulesCompile/imp-std-not-in-exp-build/uses-std.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/import-std-not-in-export-build/uses-std.cxx
rename to Tests/RunCMake/CXXModulesCompile/imp-std-not-in-exp-build/uses-std.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-build-stderr.txt b/Tests/RunCMake/CXXModulesCompile/imp-std-not-in-exp-install-stderr.txt
similarity index 95%
copy from Tests/RunCMake/CXXModules/examples/import-std-export-no-std-build-stderr.txt
copy to Tests/RunCMake/CXXModulesCompile/imp-std-not-in-exp-install-stderr.txt
index 583556f..f7d2858 100644
--- a/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-build-stderr.txt
+++ b/Tests/RunCMake/CXXModulesCompile/imp-std-not-in-exp-install-stderr.txt
@@ -2,7 +2,7 @@
   CMake's support for `import std;` in C\+\+23 and newer is experimental\.  It
   is meant only for experimentation and feedback to CMake developers\.
 Call Stack \(most recent call first\):
-  .*/Modules/CMakeDetermineCompilerSupport\.cmake:[0-9]* \(cmake_create_cxx_import_std\)
+  .*/Modules/CMakeDetermineCompilerSupport\.cmake:[0-9]* \(cmake_cxx_find_modules_json\)
   .*/Modules/CMakeTestCXXCompiler\.cmake:[0-9]* \(CMAKE_DETERMINE_COMPILER_SUPPORT\)
   CMakeLists\.txt:[0-9]* \(project\)
 This warning is for project developers\.  Use -Wno-dev to suppress it\.
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-not-in-export-install/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/imp-std-not-in-exp-install/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/import-std-not-in-export-install/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/imp-std-not-in-exp-install/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-install/main.cxx b/Tests/RunCMake/CXXModulesCompile/imp-std-not-in-exp-install/main.cxx
similarity index 100%
copy from Tests/RunCMake/CXXModules/examples/import-std-export-no-std-install/main.cxx
copy to Tests/RunCMake/CXXModulesCompile/imp-std-not-in-exp-install/main.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-not-in-export-install/test/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/imp-std-not-in-exp-install/test/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/import-std-not-in-export-install/test/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/imp-std-not-in-exp-install/test/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-not-in-export-install/uses-std.cxx b/Tests/RunCMake/CXXModulesCompile/imp-std-not-in-exp-install/uses-std.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/import-std-not-in-export-install/uses-std.cxx
rename to Tests/RunCMake/CXXModulesCompile/imp-std-not-in-exp-install/uses-std.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-build-stderr.txt b/Tests/RunCMake/CXXModulesCompile/imp-std-stderr.txt
similarity index 95%
copy from Tests/RunCMake/CXXModules/examples/import-std-export-no-std-build-stderr.txt
copy to Tests/RunCMake/CXXModulesCompile/imp-std-stderr.txt
index 583556f..f7d2858 100644
--- a/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-build-stderr.txt
+++ b/Tests/RunCMake/CXXModulesCompile/imp-std-stderr.txt
@@ -2,7 +2,7 @@
   CMake's support for `import std;` in C\+\+23 and newer is experimental\.  It
   is meant only for experimentation and feedback to CMake developers\.
 Call Stack \(most recent call first\):
-  .*/Modules/CMakeDetermineCompilerSupport\.cmake:[0-9]* \(cmake_create_cxx_import_std\)
+  .*/Modules/CMakeDetermineCompilerSupport\.cmake:[0-9]* \(cmake_cxx_find_modules_json\)
   .*/Modules/CMakeTestCXXCompiler\.cmake:[0-9]* \(CMAKE_DETERMINE_COMPILER_SUPPORT\)
   CMakeLists\.txt:[0-9]* \(project\)
 This warning is for project developers\.  Use -Wno-dev to suppress it\.
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-build-stderr.txt b/Tests/RunCMake/CXXModulesCompile/imp-std-trans-exp-no-std-build-stderr.txt
similarity index 95%
copy from Tests/RunCMake/CXXModules/examples/import-std-export-no-std-build-stderr.txt
copy to Tests/RunCMake/CXXModulesCompile/imp-std-trans-exp-no-std-build-stderr.txt
index 583556f..f7d2858 100644
--- a/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-build-stderr.txt
+++ b/Tests/RunCMake/CXXModulesCompile/imp-std-trans-exp-no-std-build-stderr.txt
@@ -2,7 +2,7 @@
   CMake's support for `import std;` in C\+\+23 and newer is experimental\.  It
   is meant only for experimentation and feedback to CMake developers\.
 Call Stack \(most recent call first\):
-  .*/Modules/CMakeDetermineCompilerSupport\.cmake:[0-9]* \(cmake_create_cxx_import_std\)
+  .*/Modules/CMakeDetermineCompilerSupport\.cmake:[0-9]* \(cmake_cxx_find_modules_json\)
   .*/Modules/CMakeTestCXXCompiler\.cmake:[0-9]* \(CMAKE_DETERMINE_COMPILER_SUPPORT\)
   CMakeLists\.txt:[0-9]* \(project\)
 This warning is for project developers\.  Use -Wno-dev to suppress it\.
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-build-stderr.txt b/Tests/RunCMake/CXXModulesCompile/imp-std-trans-exp-no-std-install-stderr.txt
similarity index 95%
copy from Tests/RunCMake/CXXModules/examples/import-std-export-no-std-build-stderr.txt
copy to Tests/RunCMake/CXXModulesCompile/imp-std-trans-exp-no-std-install-stderr.txt
index 583556f..f7d2858 100644
--- a/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-build-stderr.txt
+++ b/Tests/RunCMake/CXXModulesCompile/imp-std-trans-exp-no-std-install-stderr.txt
@@ -2,7 +2,7 @@
   CMake's support for `import std;` in C\+\+23 and newer is experimental\.  It
   is meant only for experimentation and feedback to CMake developers\.
 Call Stack \(most recent call first\):
-  .*/Modules/CMakeDetermineCompilerSupport\.cmake:[0-9]* \(cmake_create_cxx_import_std\)
+  .*/Modules/CMakeDetermineCompilerSupport\.cmake:[0-9]* \(cmake_cxx_find_modules_json\)
   .*/Modules/CMakeTestCXXCompiler\.cmake:[0-9]* \(CMAKE_DETERMINE_COMPILER_SUPPORT\)
   CMakeLists\.txt:[0-9]* \(project\)
 This warning is for project developers\.  Use -Wno-dev to suppress it\.
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-build-stderr.txt b/Tests/RunCMake/CXXModulesCompile/imp-std-trans-not-in-exp-build-stderr.txt
similarity index 95%
copy from Tests/RunCMake/CXXModules/examples/import-std-export-no-std-build-stderr.txt
copy to Tests/RunCMake/CXXModulesCompile/imp-std-trans-not-in-exp-build-stderr.txt
index 583556f..f7d2858 100644
--- a/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-build-stderr.txt
+++ b/Tests/RunCMake/CXXModulesCompile/imp-std-trans-not-in-exp-build-stderr.txt
@@ -2,7 +2,7 @@
   CMake's support for `import std;` in C\+\+23 and newer is experimental\.  It
   is meant only for experimentation and feedback to CMake developers\.
 Call Stack \(most recent call first\):
-  .*/Modules/CMakeDetermineCompilerSupport\.cmake:[0-9]* \(cmake_create_cxx_import_std\)
+  .*/Modules/CMakeDetermineCompilerSupport\.cmake:[0-9]* \(cmake_cxx_find_modules_json\)
   .*/Modules/CMakeTestCXXCompiler\.cmake:[0-9]* \(CMAKE_DETERMINE_COMPILER_SUPPORT\)
   CMakeLists\.txt:[0-9]* \(project\)
 This warning is for project developers\.  Use -Wno-dev to suppress it\.
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-build-stderr.txt b/Tests/RunCMake/CXXModulesCompile/imp-std-trans-not-in-exp-install-stderr.txt
similarity index 95%
copy from Tests/RunCMake/CXXModules/examples/import-std-export-no-std-build-stderr.txt
copy to Tests/RunCMake/CXXModulesCompile/imp-std-trans-not-in-exp-install-stderr.txt
index 583556f..f7d2858 100644
--- a/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-build-stderr.txt
+++ b/Tests/RunCMake/CXXModulesCompile/imp-std-trans-not-in-exp-install-stderr.txt
@@ -2,7 +2,7 @@
   CMake's support for `import std;` in C\+\+23 and newer is experimental\.  It
   is meant only for experimentation and feedback to CMake developers\.
 Call Stack \(most recent call first\):
-  .*/Modules/CMakeDetermineCompilerSupport\.cmake:[0-9]* \(cmake_create_cxx_import_std\)
+  .*/Modules/CMakeDetermineCompilerSupport\.cmake:[0-9]* \(cmake_cxx_find_modules_json\)
   .*/Modules/CMakeTestCXXCompiler\.cmake:[0-9]* \(CMAKE_DETERMINE_COMPILER_SUPPORT\)
   CMakeLists\.txt:[0-9]* \(project\)
 This warning is for project developers\.  Use -Wno-dev to suppress it\.
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-transitive/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/imp-std-trans/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/import-std-transitive/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/imp-std-trans/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-transitive/main.cxx b/Tests/RunCMake/CXXModulesCompile/imp-std-trans/main.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/import-std-transitive/main.cxx
rename to Tests/RunCMake/CXXModulesCompile/imp-std-trans/main.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/import-std/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/imp-std/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/import-std/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/imp-std/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/import-std/main.cxx b/Tests/RunCMake/CXXModulesCompile/imp-std/main.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/import-std/main.cxx
rename to Tests/RunCMake/CXXModulesCompile/imp-std/main.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/install-bmi-and-interfaces/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/install-bmi-and-ifaces/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/install-bmi-and-interfaces/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/install-bmi-and-ifaces/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/install-bmi-and-interfaces/check-for-bmi.cmake b/Tests/RunCMake/CXXModulesCompile/install-bmi-and-ifaces/check-for-bmi.cmake
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/install-bmi-and-interfaces/check-for-bmi.cmake
rename to Tests/RunCMake/CXXModulesCompile/install-bmi-and-ifaces/check-for-bmi.cmake
diff --git a/Tests/RunCMake/CXXModules/examples/install-bmi-and-interfaces/importable.cxx b/Tests/RunCMake/CXXModulesCompile/install-bmi-and-ifaces/importable.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/install-bmi-and-interfaces/importable.cxx
rename to Tests/RunCMake/CXXModulesCompile/install-bmi-and-ifaces/importable.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/install-bmi/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/install-bmi/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/install-bmi/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/install-bmi/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/install-bmi/check-for-bmi.cmake b/Tests/RunCMake/CXXModulesCompile/install-bmi/check-for-bmi.cmake
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/install-bmi/check-for-bmi.cmake
rename to Tests/RunCMake/CXXModulesCompile/install-bmi/check-for-bmi.cmake
diff --git a/Tests/RunCMake/CXXModules/examples/install-bmi/importable.cxx b/Tests/RunCMake/CXXModulesCompile/install-bmi/importable.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/install-bmi/importable.cxx
rename to Tests/RunCMake/CXXModulesCompile/install-bmi/importable.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/internal-partitions/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/internal-partitions/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/internal-partitions/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/internal-partitions/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/internal-partitions/importable.cxx b/Tests/RunCMake/CXXModulesCompile/internal-partitions/importable.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/internal-partitions/importable.cxx
rename to Tests/RunCMake/CXXModulesCompile/internal-partitions/importable.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/internal-partitions/internal.cxx b/Tests/RunCMake/CXXModulesCompile/internal-partitions/internal.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/internal-partitions/internal.cxx
rename to Tests/RunCMake/CXXModulesCompile/internal-partitions/internal.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/internal-partitions/main.cxx b/Tests/RunCMake/CXXModulesCompile/internal-partitions/main.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/internal-partitions/main.cxx
rename to Tests/RunCMake/CXXModulesCompile/internal-partitions/main.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/internal-partitions/partition.cxx b/Tests/RunCMake/CXXModulesCompile/internal-partitions/partition.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/internal-partitions/partition.cxx
rename to Tests/RunCMake/CXXModulesCompile/internal-partitions/partition.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/library/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/library/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/library/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/library/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/library/importable.cxx b/Tests/RunCMake/CXXModulesCompile/library/importable.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/library/importable.cxx
rename to Tests/RunCMake/CXXModulesCompile/library/importable.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/library/main.cxx b/Tests/RunCMake/CXXModulesCompile/library/main.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/library/main.cxx
rename to Tests/RunCMake/CXXModulesCompile/library/main.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/ninja-cmp0154-build-check.cmake b/Tests/RunCMake/CXXModulesCompile/ninja-cmp0154-build-check.cmake
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/ninja-cmp0154-build-check.cmake
rename to Tests/RunCMake/CXXModulesCompile/ninja-cmp0154-build-check.cmake
diff --git a/Tests/RunCMake/CXXModules/examples/ninja-cmp0154/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/ninja-cmp0154/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/ninja-cmp0154/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/ninja-cmp0154/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/ninja-cmp0154/importable.cxx.in b/Tests/RunCMake/CXXModulesCompile/ninja-cmp0154/importable.cxx.in
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/ninja-cmp0154/importable.cxx.in
rename to Tests/RunCMake/CXXModulesCompile/ninja-cmp0154/importable.cxx.in
diff --git a/Tests/RunCMake/CXXModules/examples/ninja-cmp0154/main.cxx b/Tests/RunCMake/CXXModulesCompile/ninja-cmp0154/main.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/ninja-cmp0154/main.cxx
rename to Tests/RunCMake/CXXModulesCompile/ninja-cmp0154/main.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/ninja-cmp0154/unrelated.cxx b/Tests/RunCMake/CXXModulesCompile/ninja-cmp0154/unrelated.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/ninja-cmp0154/unrelated.cxx
rename to Tests/RunCMake/CXXModulesCompile/ninja-cmp0154/unrelated.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/non-trivial-collation-order-randomized/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/non-trivial-collation-order-randomized/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/non-trivial-collation-order-randomized/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/non-trivial-collation-order-randomized/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/non-trivial-collation-order/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/non-trivial-collation-order/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/main.cxx b/Tests/RunCMake/CXXModulesCompile/non-trivial-collation-order/main.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/main.cxx
rename to Tests/RunCMake/CXXModulesCompile/non-trivial-collation-order/main.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/module_level/mod1.cxx b/Tests/RunCMake/CXXModulesCompile/non-trivial-collation-order/module_level/mod1.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/module_level/mod1.cxx
rename to Tests/RunCMake/CXXModulesCompile/non-trivial-collation-order/module_level/mod1.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/module_level/mod2.cxx b/Tests/RunCMake/CXXModulesCompile/non-trivial-collation-order/module_level/mod2.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/module_level/mod2.cxx
rename to Tests/RunCMake/CXXModulesCompile/non-trivial-collation-order/module_level/mod2.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/module_level/mod3.cxx b/Tests/RunCMake/CXXModulesCompile/non-trivial-collation-order/module_level/mod3.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/module_level/mod3.cxx
rename to Tests/RunCMake/CXXModulesCompile/non-trivial-collation-order/module_level/mod3.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/module_level/mod4.cxx b/Tests/RunCMake/CXXModulesCompile/non-trivial-collation-order/module_level/mod4.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/module_level/mod4.cxx
rename to Tests/RunCMake/CXXModulesCompile/non-trivial-collation-order/module_level/mod4.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/module_level/mod5.cxx b/Tests/RunCMake/CXXModulesCompile/non-trivial-collation-order/module_level/mod5.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/module_level/mod5.cxx
rename to Tests/RunCMake/CXXModulesCompile/non-trivial-collation-order/module_level/mod5.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/module_level/mod6.cxx b/Tests/RunCMake/CXXModulesCompile/non-trivial-collation-order/module_level/mod6.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/module_level/mod6.cxx
rename to Tests/RunCMake/CXXModulesCompile/non-trivial-collation-order/module_level/mod6.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/module_level/mod7.cxx b/Tests/RunCMake/CXXModulesCompile/non-trivial-collation-order/module_level/mod7.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/module_level/mod7.cxx
rename to Tests/RunCMake/CXXModulesCompile/non-trivial-collation-order/module_level/mod7.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/partition_level/impl-non-partition.cxx b/Tests/RunCMake/CXXModulesCompile/non-trivial-collation-order/partition_level/impl-non-partition.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/partition_level/impl-non-partition.cxx
rename to Tests/RunCMake/CXXModulesCompile/non-trivial-collation-order/partition_level/impl-non-partition.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/partition_level/impl1.cxx b/Tests/RunCMake/CXXModulesCompile/non-trivial-collation-order/partition_level/impl1.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/partition_level/impl1.cxx
rename to Tests/RunCMake/CXXModulesCompile/non-trivial-collation-order/partition_level/impl1.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/partition_level/impl2.cxx b/Tests/RunCMake/CXXModulesCompile/non-trivial-collation-order/partition_level/impl2.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/partition_level/impl2.cxx
rename to Tests/RunCMake/CXXModulesCompile/non-trivial-collation-order/partition_level/impl2.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/partition_level/impl3.cxx b/Tests/RunCMake/CXXModulesCompile/non-trivial-collation-order/partition_level/impl3.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/partition_level/impl3.cxx
rename to Tests/RunCMake/CXXModulesCompile/non-trivial-collation-order/partition_level/impl3.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/partition_level/impl4.cxx b/Tests/RunCMake/CXXModulesCompile/non-trivial-collation-order/partition_level/impl4.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/partition_level/impl4.cxx
rename to Tests/RunCMake/CXXModulesCompile/non-trivial-collation-order/partition_level/impl4.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/partition_level/impl5.cxx b/Tests/RunCMake/CXXModulesCompile/non-trivial-collation-order/partition_level/impl5.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/partition_level/impl5.cxx
rename to Tests/RunCMake/CXXModulesCompile/non-trivial-collation-order/partition_level/impl5.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/partition_level/impl6.cxx b/Tests/RunCMake/CXXModulesCompile/non-trivial-collation-order/partition_level/impl6.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/partition_level/impl6.cxx
rename to Tests/RunCMake/CXXModulesCompile/non-trivial-collation-order/partition_level/impl6.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/partition_level/impl7.cxx b/Tests/RunCMake/CXXModulesCompile/non-trivial-collation-order/partition_level/impl7.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/partition_level/impl7.cxx
rename to Tests/RunCMake/CXXModulesCompile/non-trivial-collation-order/partition_level/impl7.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/partition_level/intf1.cxx b/Tests/RunCMake/CXXModulesCompile/non-trivial-collation-order/partition_level/intf1.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/partition_level/intf1.cxx
rename to Tests/RunCMake/CXXModulesCompile/non-trivial-collation-order/partition_level/intf1.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/partition_level/intf2.cxx b/Tests/RunCMake/CXXModulesCompile/non-trivial-collation-order/partition_level/intf2.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/partition_level/intf2.cxx
rename to Tests/RunCMake/CXXModulesCompile/non-trivial-collation-order/partition_level/intf2.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/partition_level/intf3.cxx b/Tests/RunCMake/CXXModulesCompile/non-trivial-collation-order/partition_level/intf3.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/partition_level/intf3.cxx
rename to Tests/RunCMake/CXXModulesCompile/non-trivial-collation-order/partition_level/intf3.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/partition_level/intf4.cxx b/Tests/RunCMake/CXXModulesCompile/non-trivial-collation-order/partition_level/intf4.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/partition_level/intf4.cxx
rename to Tests/RunCMake/CXXModulesCompile/non-trivial-collation-order/partition_level/intf4.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/partition_level/intf5.cxx b/Tests/RunCMake/CXXModulesCompile/non-trivial-collation-order/partition_level/intf5.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/partition_level/intf5.cxx
rename to Tests/RunCMake/CXXModulesCompile/non-trivial-collation-order/partition_level/intf5.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/partition_level/intf6.cxx b/Tests/RunCMake/CXXModulesCompile/non-trivial-collation-order/partition_level/intf6.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/partition_level/intf6.cxx
rename to Tests/RunCMake/CXXModulesCompile/non-trivial-collation-order/partition_level/intf6.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/partition_level/intf7.cxx b/Tests/RunCMake/CXXModulesCompile/non-trivial-collation-order/partition_level/intf7.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/partition_level/intf7.cxx
rename to Tests/RunCMake/CXXModulesCompile/non-trivial-collation-order/partition_level/intf7.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/partition_level/partition_level.cxx b/Tests/RunCMake/CXXModulesCompile/non-trivial-collation-order/partition_level/partition_level.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/partition_level/partition_level.cxx
rename to Tests/RunCMake/CXXModulesCompile/non-trivial-collation-order/partition_level/partition_level.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/target_level/target1.cxx b/Tests/RunCMake/CXXModulesCompile/non-trivial-collation-order/target_level/target1.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/target_level/target1.cxx
rename to Tests/RunCMake/CXXModulesCompile/non-trivial-collation-order/target_level/target1.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/target_level/target2.cxx b/Tests/RunCMake/CXXModulesCompile/non-trivial-collation-order/target_level/target2.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/target_level/target2.cxx
rename to Tests/RunCMake/CXXModulesCompile/non-trivial-collation-order/target_level/target2.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/target_level/target3.cxx b/Tests/RunCMake/CXXModulesCompile/non-trivial-collation-order/target_level/target3.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/target_level/target3.cxx
rename to Tests/RunCMake/CXXModulesCompile/non-trivial-collation-order/target_level/target3.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/target_level/target4.cxx b/Tests/RunCMake/CXXModulesCompile/non-trivial-collation-order/target_level/target4.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/target_level/target4.cxx
rename to Tests/RunCMake/CXXModulesCompile/non-trivial-collation-order/target_level/target4.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/target_level/target5.cxx b/Tests/RunCMake/CXXModulesCompile/non-trivial-collation-order/target_level/target5.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/target_level/target5.cxx
rename to Tests/RunCMake/CXXModulesCompile/non-trivial-collation-order/target_level/target5.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/target_level/target6.cxx b/Tests/RunCMake/CXXModulesCompile/non-trivial-collation-order/target_level/target6.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/target_level/target6.cxx
rename to Tests/RunCMake/CXXModulesCompile/non-trivial-collation-order/target_level/target6.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/target_level/target7.cxx b/Tests/RunCMake/CXXModulesCompile/non-trivial-collation-order/target_level/target7.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/non-trivial-collation-order/target_level/target7.cxx
rename to Tests/RunCMake/CXXModulesCompile/non-trivial-collation-order/target_level/target7.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/object-library/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/object-library/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/object-library/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/object-library/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/object-library/importable.cxx b/Tests/RunCMake/CXXModulesCompile/object-library/importable.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/object-library/importable.cxx
rename to Tests/RunCMake/CXXModulesCompile/object-library/importable.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/object-library/main.cxx b/Tests/RunCMake/CXXModulesCompile/object-library/main.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/object-library/main.cxx
rename to Tests/RunCMake/CXXModulesCompile/object-library/main.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/partitions/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/partitions/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/partitions/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/partitions/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/partitions/importable.cxx b/Tests/RunCMake/CXXModulesCompile/partitions/importable.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/partitions/importable.cxx
rename to Tests/RunCMake/CXXModulesCompile/partitions/importable.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/partitions/main.cxx b/Tests/RunCMake/CXXModulesCompile/partitions/main.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/partitions/main.cxx
rename to Tests/RunCMake/CXXModulesCompile/partitions/main.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/partitions/partition.cxx b/Tests/RunCMake/CXXModulesCompile/partitions/partition.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/partitions/partition.cxx
rename to Tests/RunCMake/CXXModulesCompile/partitions/partition.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/circular-build-result.txt b/Tests/RunCMake/CXXModulesCompile/public-req-priv-build-result.txt
similarity index 100%
copy from Tests/RunCMake/CXXModules/examples/circular-build-result.txt
copy to Tests/RunCMake/CXXModulesCompile/public-req-priv-build-result.txt
diff --git a/Tests/RunCMake/CXXModulesCompile/public-req-priv-build-stdout.txt b/Tests/RunCMake/CXXModulesCompile/public-req-priv-build-stdout.txt
new file mode 100644
index 0000000..5df83a5
--- /dev/null
+++ b/Tests/RunCMake/CXXModulesCompile/public-req-priv-build-stdout.txt
@@ -0,0 +1 @@
+CMake Error: Public C\+\+ module source `.*/Tests/RunCMake/CXXModulesCompile/public-req-priv/pub\.cxx` requires the `priv` C\+\+ module which is provided by a private source
diff --git a/Tests/RunCMake/CXXModules/examples/public-req-private/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/public-req-priv/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/public-req-private/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/public-req-priv/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/public-req-private/priv.cxx b/Tests/RunCMake/CXXModulesCompile/public-req-priv/priv.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/public-req-private/priv.cxx
rename to Tests/RunCMake/CXXModulesCompile/public-req-priv/priv.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/public-req-private/pub.cxx b/Tests/RunCMake/CXXModulesCompile/public-req-priv/pub.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/public-req-private/pub.cxx
rename to Tests/RunCMake/CXXModulesCompile/public-req-priv/pub.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/req-private-other-target-build-result.txt b/Tests/RunCMake/CXXModulesCompile/req-priv-other-target-build-result.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/req-private-other-target-build-result.txt
rename to Tests/RunCMake/CXXModulesCompile/req-priv-other-target-build-result.txt
diff --git a/Tests/RunCMake/CXXModules/examples/req-private-other-target-build-stdout.txt b/Tests/RunCMake/CXXModulesCompile/req-priv-other-target-build-stdout.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/req-private-other-target-build-stdout.txt
rename to Tests/RunCMake/CXXModulesCompile/req-priv-other-target-build-stdout.txt
diff --git a/Tests/RunCMake/CXXModules/examples/req-private-other-target/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/req-priv-other-target/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/req-private-other-target/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/req-priv-other-target/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/req-private-other-target/lib.cxx b/Tests/RunCMake/CXXModulesCompile/req-priv-other-target/lib.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/req-private-other-target/lib.cxx
rename to Tests/RunCMake/CXXModulesCompile/req-priv-other-target/lib.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/req-private-other-target/main.cxx b/Tests/RunCMake/CXXModulesCompile/req-priv-other-target/main.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/req-private-other-target/main.cxx
rename to Tests/RunCMake/CXXModulesCompile/req-priv-other-target/main.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/req-private-other-target/priv.cxx b/Tests/RunCMake/CXXModulesCompile/req-priv-other-target/priv.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/req-private-other-target/priv.cxx
rename to Tests/RunCMake/CXXModulesCompile/req-priv-other-target/priv.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/same-src-name/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/same-src-name/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/same-src-name/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/same-src-name/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/same-src-name/a/same.cxx b/Tests/RunCMake/CXXModulesCompile/same-src-name/a/same.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/same-src-name/a/same.cxx
rename to Tests/RunCMake/CXXModulesCompile/same-src-name/a/same.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/same-src-name/b/same.cxx b/Tests/RunCMake/CXXModulesCompile/same-src-name/b/same.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/same-src-name/b/same.cxx
rename to Tests/RunCMake/CXXModulesCompile/same-src-name/b/same.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/same-src-name/main.cxx b/Tests/RunCMake/CXXModulesCompile/same-src-name/main.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/same-src-name/main.cxx
rename to Tests/RunCMake/CXXModulesCompile/same-src-name/main.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/scan-with-pch/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/scan-with-pch/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/scan-with-pch/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/scan-with-pch/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/scan-with-pch/main.cxx b/Tests/RunCMake/CXXModulesCompile/scan-with-pch/main.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/scan-with-pch/main.cxx
rename to Tests/RunCMake/CXXModulesCompile/scan-with-pch/main.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/scan-with-pch/pch.h b/Tests/RunCMake/CXXModulesCompile/scan-with-pch/pch.h
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/scan-with-pch/pch.h
rename to Tests/RunCMake/CXXModulesCompile/scan-with-pch/pch.h
diff --git a/Tests/RunCMake/CXXModules/examples/scan_properties/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/scan_props/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/scan_properties/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/scan_props/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/scan_properties/always_scan.cxx b/Tests/RunCMake/CXXModulesCompile/scan_props/always_scan.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/scan_properties/always_scan.cxx
rename to Tests/RunCMake/CXXModulesCompile/scan_props/always_scan.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/scan_properties/join.cxx b/Tests/RunCMake/CXXModulesCompile/scan_props/join.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/scan_properties/join.cxx
rename to Tests/RunCMake/CXXModulesCompile/scan_props/join.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/scan_properties/main.cxx b/Tests/RunCMake/CXXModulesCompile/scan_props/main.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/scan_properties/main.cxx
rename to Tests/RunCMake/CXXModulesCompile/scan_props/main.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/scan_properties/module.cxx b/Tests/RunCMake/CXXModulesCompile/scan_props/module.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/scan_properties/module.cxx
rename to Tests/RunCMake/CXXModulesCompile/scan_props/module.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/scan_properties/never_scan.ixx b/Tests/RunCMake/CXXModulesCompile/scan_props/never_scan.ixx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/scan_properties/never_scan.ixx
rename to Tests/RunCMake/CXXModulesCompile/scan_props/never_scan.ixx
diff --git a/Tests/RunCMake/CXXModules/examples/simple/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/simple/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/simple/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/simple/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/simple/importable.cxx b/Tests/RunCMake/CXXModulesCompile/simple/importable.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/simple/importable.cxx
rename to Tests/RunCMake/CXXModulesCompile/simple/importable.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/simple/main.cxx b/Tests/RunCMake/CXXModulesCompile/simple/main.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/simple/main.cxx
rename to Tests/RunCMake/CXXModulesCompile/simple/main.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/target-objects/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/target-objects/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/target-objects/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/target-objects/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/target-objects/importable.cxx b/Tests/RunCMake/CXXModulesCompile/target-objects/importable.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/target-objects/importable.cxx
rename to Tests/RunCMake/CXXModulesCompile/target-objects/importable.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/target-objects/main.cxx b/Tests/RunCMake/CXXModulesCompile/target-objects/main.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/target-objects/main.cxx
rename to Tests/RunCMake/CXXModulesCompile/target-objects/main.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/try-compile/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/try-compile/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/try-compile/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/try-compile/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/try-compile/importable.cxx b/Tests/RunCMake/CXXModulesCompile/try-compile/importable.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/try-compile/importable.cxx
rename to Tests/RunCMake/CXXModulesCompile/try-compile/importable.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/try-compile/use_importable.cxx b/Tests/RunCMake/CXXModulesCompile/try-compile/use_importable.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/try-compile/use_importable.cxx
rename to Tests/RunCMake/CXXModulesCompile/try-compile/use_importable.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/try-run/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/try-run/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/try-run/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/try-run/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/try-run/importable.cxx b/Tests/RunCMake/CXXModulesCompile/try-run/importable.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/try-run/importable.cxx
rename to Tests/RunCMake/CXXModulesCompile/try-run/importable.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/try-run/main.cxx b/Tests/RunCMake/CXXModulesCompile/try-run/main.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/try-run/main.cxx
rename to Tests/RunCMake/CXXModulesCompile/try-run/main.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/unity-build/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/unity-build/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/unity-build/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/unity-build/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/unity-build/importable.cxx b/Tests/RunCMake/CXXModulesCompile/unity-build/importable.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/unity-build/importable.cxx
rename to Tests/RunCMake/CXXModulesCompile/unity-build/importable.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/unity-build/main.cxx b/Tests/RunCMake/CXXModulesCompile/unity-build/main.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/unity-build/main.cxx
rename to Tests/RunCMake/CXXModulesCompile/unity-build/main.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/unity-build/unity.h b/Tests/RunCMake/CXXModulesCompile/unity-build/unity.h
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/unity-build/unity.h
rename to Tests/RunCMake/CXXModulesCompile/unity-build/unity.h
diff --git a/Tests/RunCMake/CXXModules/examples/unity-build/unity1.cxx b/Tests/RunCMake/CXXModulesCompile/unity-build/unity1.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/unity-build/unity1.cxx
rename to Tests/RunCMake/CXXModulesCompile/unity-build/unity1.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/unity-build/unity2.cxx b/Tests/RunCMake/CXXModulesCompile/unity-build/unity2.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/unity-build/unity2.cxx
rename to Tests/RunCMake/CXXModulesCompile/unity-build/unity2.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/vs-without-flags/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/vs-without-flags/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/vs-without-flags/CMakeLists.txt
rename to Tests/RunCMake/CXXModulesCompile/vs-without-flags/CMakeLists.txt
diff --git a/Tests/RunCMake/CXXModules/examples/vs-without-flags/main.cxx b/Tests/RunCMake/CXXModulesCompile/vs-without-flags/main.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/vs-without-flags/main.cxx
rename to Tests/RunCMake/CXXModulesCompile/vs-without-flags/main.cxx
diff --git a/Tests/RunCMake/CXXModules/examples/vs-without-flags/module.cxx b/Tests/RunCMake/CXXModulesCompile/vs-without-flags/module.cxx
similarity index 100%
rename from Tests/RunCMake/CXXModules/examples/vs-without-flags/module.cxx
rename to Tests/RunCMake/CXXModulesCompile/vs-without-flags/module.cxx
diff --git a/Tests/RunCMake/CommandLine/E_copy_directory-three-source-files-target-is-file-stderr.txt b/Tests/RunCMake/CommandLine/E_copy_directory-three-source-files-target-is-file-stderr.txt
index 6e1a614..5120983 100644
--- a/Tests/RunCMake/CommandLine/E_copy_directory-three-source-files-target-is-file-stderr.txt
+++ b/Tests/RunCMake/CommandLine/E_copy_directory-three-source-files-target-is-file-stderr.txt
@@ -1,3 +1,3 @@
-^Error copying directory from .* to .*file_for_test\.txt\".*
-Error copying directory from .* to .*file_for_test\.txt\".*
-Error copying directory from .* to .*file_for_test\.txt\"\.$
+^Error copying directory from "[^"]+" to "[^"]+file_for_test\.txt": File exists
+Error copying directory from "[^"]+" to "[^"]+file_for_test\.txt": File exists
+Error copying directory from "[^"]+" to "[^"]+file_for_test\.txt": File exists$
diff --git a/Tests/RunCMake/CommandLine/E_copy_directory_if_newer-nonexistent-source-stderr.txt b/Tests/RunCMake/CommandLine/E_copy_directory_if_newer-nonexistent-source-stderr.txt
index 248ebb4..8533666 100644
--- a/Tests/RunCMake/CommandLine/E_copy_directory_if_newer-nonexistent-source-stderr.txt
+++ b/Tests/RunCMake/CommandLine/E_copy_directory_if_newer-nonexistent-source-stderr.txt
@@ -1 +1 @@
-^Error copying directory from ".+" to ".+"\.$
+^Error copying directory from "[^"]+" to "[^"]+": (No such file or directory|The system cannot find the path specified\.)$
diff --git a/Tests/RunCMake/CommandLine/E_copy_if_different-nonexistent-source-stderr.txt b/Tests/RunCMake/CommandLine/E_copy_if_different-nonexistent-source-stderr.txt
index ce1099b..f54f4ae 100644
--- a/Tests/RunCMake/CommandLine/E_copy_if_different-nonexistent-source-stderr.txt
+++ b/Tests/RunCMake/CommandLine/E_copy_if_different-nonexistent-source-stderr.txt
@@ -1 +1 @@
-^Error copying file \(if different\) from ".+" to ".+"\.$
+^Error copying file \(if different\) from "[^"]+" to "[^"]+": No such file or directory$
diff --git a/Tests/RunCMake/CommandLine/E_copy_if_newer-nonexistent-source-stderr.txt b/Tests/RunCMake/CommandLine/E_copy_if_newer-nonexistent-source-stderr.txt
index 52e51bc..cbe1f46 100644
--- a/Tests/RunCMake/CommandLine/E_copy_if_newer-nonexistent-source-stderr.txt
+++ b/Tests/RunCMake/CommandLine/E_copy_if_newer-nonexistent-source-stderr.txt
@@ -1 +1 @@
-^Error copying file \(if newer\) from ".+" to ".+"\.$
+^Error copying file \(if newer\) from "[^"]+" to "[^"]+": No such file or directory$
diff --git a/Tests/RunCMake/CommandLine/E_make_directory-two-directories-and-file-stderr.txt b/Tests/RunCMake/CommandLine/E_make_directory-two-directories-and-file-stderr.txt
index 17c68ed..992a4b0 100644
--- a/Tests/RunCMake/CommandLine/E_make_directory-two-directories-and-file-stderr.txt
+++ b/Tests/RunCMake/CommandLine/E_make_directory-two-directories-and-file-stderr.txt
@@ -1 +1 @@
-^Error creating directory .*file_for_test\.txt\"\.$
+^Error creating directory "[^"]+file_for_test\.txt": File exists$
diff --git a/Tests/RunCMake/GenEx-STRING/APPEND.cmake.in b/Tests/RunCMake/GenEx-STRING/APPEND.cmake.in
new file mode 100644
index 0000000..6c1767b
--- /dev/null
+++ b/Tests/RunCMake/GenEx-STRING/APPEND.cmake.in
@@ -0,0 +1,22 @@
+
+cmake_minimum_required(VERSION 4.2...4.3)
+
+include ("${RunCMake_SOURCE_DIR}/check_errors.cmake")
+unset (errors)
+
+set(reference "abcd")
+string(APPEND reference  "efg" "ABCD")
+set(output "$<STRING:APPEND,abcd,efg,ABCD>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:APPEND,abcd,efg,ABCD> returns bad data: ${output}")
+endif()
+
+unset(reference)
+string(APPEND reference  "efg" "ABCD")
+set(output "$<STRING:APPEND,,efg,ABCD>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:APPEND,,efg,ABCD> returns bad data: ${output}")
+endif()
+
+
+check_errors("STRING:APPEND" ${errors})
diff --git a/Tests/RunCMake/file/CREATE_LINK-noarg-result.txt b/Tests/RunCMake/GenEx-STRING/ASCII-WrongArguments-result.txt
similarity index 100%
copy from Tests/RunCMake/file/CREATE_LINK-noarg-result.txt
copy to Tests/RunCMake/GenEx-STRING/ASCII-WrongArguments-result.txt
diff --git a/Tests/RunCMake/GenEx-STRING/ASCII-WrongArguments-stderr.txt b/Tests/RunCMake/GenEx-STRING/ASCII-WrongArguments-stderr.txt
new file mode 100644
index 0000000..d14cdea
--- /dev/null
+++ b/Tests/RunCMake/GenEx-STRING/ASCII-WrongArguments-stderr.txt
@@ -0,0 +1,38 @@
+CMake Error at ASCII-WrongArguments\.cmake:[0-9]+ \(add_custom_target\):
+  Error evaluating generator expression:
+
+    \$<STRING:ASCII,foo>
+
+  Character with code foo does not exist.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
+
+
+CMake Error at ASCII-WrongArguments\.cmake:[0-9]+ \(add_custom_target\):
+  Error evaluating generator expression:
+
+    \$<STRING:ASCII,256>
+
+  Character with code 256 does not exist.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
+
+
+CMake Error at ASCII-WrongArguments\.cmake:[0-9]+ \(add_custom_target\):
+  Error evaluating generator expression:
+
+    \$<STRING:ASCII,32,256>
+
+  Character with code 256 does not exist.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
+
+
+CMake Error at ASCII-WrongArguments\.cmake:[0-9]+ \(add_custom_target\):
+  Error evaluating generator expression:
+
+    \$<STRING:ASCII,32,-1>
+
+  Character with code -1 does not exist.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-STRING/ASCII-WrongArguments.cmake b/Tests/RunCMake/GenEx-STRING/ASCII-WrongArguments.cmake
new file mode 100644
index 0000000..d26a341
--- /dev/null
+++ b/Tests/RunCMake/GenEx-STRING/ASCII-WrongArguments.cmake
@@ -0,0 +1,7 @@
+
+add_custom_target(check ALL COMMAND check
+  $<STRING:ASCII,foo>
+  $<STRING:ASCII,256>
+  $<STRING:ASCII,32,256>
+  $<STRING:ASCII,32,-1>
+VERBATIM)
diff --git a/Tests/RunCMake/GenEx-STRING/ASCII.cmake.in b/Tests/RunCMake/GenEx-STRING/ASCII.cmake.in
new file mode 100644
index 0000000..4075af4
--- /dev/null
+++ b/Tests/RunCMake/GenEx-STRING/ASCII.cmake.in
@@ -0,0 +1,20 @@
+
+cmake_minimum_required(VERSION 4.2...4.3)
+
+include ("${RunCMake_SOURCE_DIR}/check_errors.cmake")
+unset (errors)
+
+string(ASCII 32 reference)
+set(output "$<STRING:ASCII,32>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:ASCII,32> returns bad data: ${output}")
+endif()
+
+string(ASCII 32 64 reference)
+set(output "$<STRING:ASCII,32,64>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:ASCII,32,64> returns bad data: ${output}")
+endif()
+
+
+check_errors("STRING:ASCII" ${errors})
diff --git a/Tests/RunCMake/GenEx-STRING/CMakeLists.txt b/Tests/RunCMake/GenEx-STRING/CMakeLists.txt
new file mode 100644
index 0000000..5161b99
--- /dev/null
+++ b/Tests/RunCMake/GenEx-STRING/CMakeLists.txt
@@ -0,0 +1,5 @@
+cmake_minimum_required(VERSION 3.18...3.25)
+
+project(${RunCMake_TEST} NONE)
+
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/file/CREATE_LINK-noarg-result.txt b/Tests/RunCMake/GenEx-STRING/FIND-WrongArguments-result.txt
similarity index 100%
copy from Tests/RunCMake/file/CREATE_LINK-noarg-result.txt
copy to Tests/RunCMake/GenEx-STRING/FIND-WrongArguments-result.txt
diff --git a/Tests/RunCMake/GenEx-STRING/FIND-WrongArguments-stderr.txt b/Tests/RunCMake/GenEx-STRING/FIND-WrongArguments-stderr.txt
new file mode 100644
index 0000000..ad767a1
--- /dev/null
+++ b/Tests/RunCMake/GenEx-STRING/FIND-WrongArguments-stderr.txt
@@ -0,0 +1,18 @@
+CMake Error at FIND-WrongArguments\.cmake:[0-9]+ \(add_custom_target\):
+  Error evaluating generator expression:
+
+    \$<STRING:FIND,string,OTHER,foo>
+
+  Expected option 'FROM:' is missing.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
+
+
+CMake Error at FIND-WrongArguments\.cmake:[0-9]+ \(add_custom_target\):
+  Error evaluating generator expression:
+
+    \$<STRING:FIND,string,FROM:OTHER,foo>
+
+  Invalid value for 'FROM:' option.  'BEGIN' or 'END' expected.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-STRING/FIND-WrongArguments.cmake b/Tests/RunCMake/GenEx-STRING/FIND-WrongArguments.cmake
new file mode 100644
index 0000000..fbcdd94
--- /dev/null
+++ b/Tests/RunCMake/GenEx-STRING/FIND-WrongArguments.cmake
@@ -0,0 +1,5 @@
+
+add_custom_target(check ALL COMMAND check
+  $<STRING:FIND,string,OTHER,foo>
+  $<STRING:FIND,string,FROM:OTHER,foo>
+VERBATIM)
diff --git a/Tests/RunCMake/GenEx-STRING/FIND.cmake.in b/Tests/RunCMake/GenEx-STRING/FIND.cmake.in
new file mode 100644
index 0000000..1d11d35
--- /dev/null
+++ b/Tests/RunCMake/GenEx-STRING/FIND.cmake.in
@@ -0,0 +1,48 @@
+
+cmake_minimum_required(VERSION 4.2...4.3)
+
+include ("${RunCMake_SOURCE_DIR}/check_errors.cmake")
+unset (errors)
+
+string(FIND  "abcdabcd" "cd" reference)
+set(output "$<STRING:FIND,abcdabcd,cd>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:FIND,abcdabcd,cd> returns bad data: ${output}")
+endif()
+set(output "$<STRING:FIND,abcdabcd,FROM:BEGIN,cd>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:FIND,abcdabcd,FROM:BEGIN,cd> returns bad data: ${output}")
+endif()
+set(output "$<STRING:FIND,abcdabcd,cd,FROM:BEGIN>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:FIND,abcdabcd,cd,FROM:BEGIN> returns bad data: ${output}")
+endif()
+
+string(FIND  "abcdabcd" "cd" reference REVERSE)
+set(output "$<STRING:FIND,abcdabcd,FROM:END,cd>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:FIND,abcdabcd,FROM:END,cd> returns bad data: ${output}")
+endif()
+set(output "$<STRING:FIND,abcdabcd,cd,FROM:END>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:FIND,abcdabcd,cd,FROM:END> returns bad data: ${output}")
+endif()
+
+string(FIND  "abcdabcd" "xy" reference)
+set(output "$<STRING:FIND,abcdabcd,xy>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:FIND,abcdabcd,xy> returns bad data: ${output}")
+endif()
+set(output "$<STRING:FIND,abcdabcd,xy,FROM:BEGIN>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:FIND,abcdabcd,xy,FROM:BEGIN> returns bad data: ${output}")
+endif()
+
+string(FIND  "abcdabcd" "xy" reference REVERSE)
+set(output "$<STRING:FIND,abcdabcd,xy,FROM:END>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:FIND,abcdabcd,xy,FROM:END> returns bad data: ${output}")
+endif()
+
+
+check_errors("STRING:FIND" ${errors})
diff --git a/Tests/RunCMake/file/CREATE_LINK-noarg-result.txt b/Tests/RunCMake/GenEx-STRING/HASH-WrongArguments-result.txt
similarity index 100%
copy from Tests/RunCMake/file/CREATE_LINK-noarg-result.txt
copy to Tests/RunCMake/GenEx-STRING/HASH-WrongArguments-result.txt
diff --git a/Tests/RunCMake/GenEx-STRING/HASH-WrongArguments-stderr.txt b/Tests/RunCMake/GenEx-STRING/HASH-WrongArguments-stderr.txt
new file mode 100644
index 0000000..6edb7f7
--- /dev/null
+++ b/Tests/RunCMake/GenEx-STRING/HASH-WrongArguments-stderr.txt
@@ -0,0 +1,18 @@
+CMake Error at HASH-WrongArguments\.cmake:[0-9]+ \(add_custom_target\):
+  Error evaluating generator expression:
+
+    \$<STRING:HASH,string,ALGORITHM:>
+
+  Missing value for 'ALGORITHM:' option.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
+
+
+CMake Error at HASH-WrongArguments\.cmake:[0-9]+ \(add_custom_target\):
+  Error evaluating generator expression:
+
+    \$<STRING:HASH,string,ALGORITHM:FOO>
+
+  FOO: invalid hash algorithm.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-STRING/HASH-WrongArguments.cmake b/Tests/RunCMake/GenEx-STRING/HASH-WrongArguments.cmake
new file mode 100644
index 0000000..3b9fa82
--- /dev/null
+++ b/Tests/RunCMake/GenEx-STRING/HASH-WrongArguments.cmake
@@ -0,0 +1,5 @@
+
+add_custom_target(check ALL COMMAND check
+  $<STRING:HASH,string,ALGORITHM:>
+  $<STRING:HASH,string,ALGORITHM:FOO>
+VERBATIM)
diff --git a/Tests/RunCMake/GenEx-STRING/HASH.cmake.in b/Tests/RunCMake/GenEx-STRING/HASH.cmake.in
new file mode 100644
index 0000000..e1fe2c7
--- /dev/null
+++ b/Tests/RunCMake/GenEx-STRING/HASH.cmake.in
@@ -0,0 +1,69 @@
+
+cmake_minimum_required(VERSION 4.2...4.3)
+
+include ("${RunCMake_SOURCE_DIR}/check_errors.cmake")
+unset (errors)
+
+# foreach(hash IN ITEMS MD5 SHA1 SHA224 SHA256 SHA384 SHA512 SHA3_224 SHA3_256 SHA3_384 SHA3_512)
+
+string(MD5 reference "sample input string")
+set(output "$<STRING:HASH,sample input string,ALGORITHM:MD5>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:HASH,sample input string,MD5> returns bad data: ${output}")
+endif()
+
+string(SHA1 reference "sample input string")
+set(output "$<STRING:HASH,sample input string,ALGORITHM:SHA1>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:HASH,sample input string,SHA1> returns bad data: ${output}")
+endif()
+
+string(SHA224 reference "sample input string")
+set(output "$<STRING:HASH,sample input string,ALGORITHM:SHA224>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:HASH,sample input string,SHA224> returns bad data: ${output}")
+endif()
+
+string(SHA256 reference "sample input string")
+set(output "$<STRING:HASH,sample input string,ALGORITHM:SHA256>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:HASH,sample input string,SHA256> returns bad data: ${output}")
+endif()
+
+string(SHA384 reference "sample input string")
+set(output "$<STRING:HASH,sample input string,ALGORITHM:SHA384>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:HASH,sample input string,SHA384> returns bad data: ${output}")
+endif()
+
+string(SHA512 reference "sample input string")
+set(output "$<STRING:HASH,sample input string,ALGORITHM:SHA512>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:HASH,sample input string,SHA512> returns bad data: ${output}")
+endif()
+
+string(SHA3_224 reference "sample input string")
+set(output "$<STRING:HASH,sample input string,ALGORITHM:SHA3_224>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:HASH,sample input string,SHA3_224> returns bad data: ${output}")
+endif()
+
+string(SHA3_256 reference "sample input string")
+set(output "$<STRING:HASH,sample input string,ALGORITHM:SHA3_256>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:HASH,sample input string,SHA3_256> returns bad data: ${output}")
+endif()
+
+string(SHA3_384 reference "sample input string")
+set(output "$<STRING:HASH,sample input string,ALGORITHM:SHA3_384>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:HASH,sample input string,SHA3_384> returns bad data: ${output}")
+endif()
+
+string(SHA3_512 reference "sample input string")
+set(output "$<STRING:HASH,sample input string,ALGORITHM:SHA3_512>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:HASH,sample input string,SHA3_512> returns bad data: ${output}")
+endif()
+
+check_errors("STRING:HASH" ${errors})
diff --git a/Tests/RunCMake/GenEx-STRING/HEX.cmake.in b/Tests/RunCMake/GenEx-STRING/HEX.cmake.in
new file mode 100644
index 0000000..3fff995
--- /dev/null
+++ b/Tests/RunCMake/GenEx-STRING/HEX.cmake.in
@@ -0,0 +1,20 @@
+
+cmake_minimum_required(VERSION 4.2...4.3)
+
+include ("${RunCMake_SOURCE_DIR}/check_errors.cmake")
+unset (errors)
+
+string(HEX "The quick brown fox jumps over the lazy dog." reference)
+set(output "$<STRING:HEX,The quick brown fox jumps over the lazy dog.>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:HEX,The quick brown fox jumps over the lazy dog.> returns bad data: ${output}")
+endif()
+
+string(HEX "Ash nazg durbatulûk. Ash nazg gimbatul. Ash nazg thrakatulûk. Agh burzum-ishi krimpatul" reference)
+set(output "$<STRING:HEX,Ash nazg durbatulûk. Ash nazg gimbatul. Ash nazg thrakatulûk. Agh burzum-ishi krimpatul>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:HEX,Ash nazg durbatulûk. Ash nazg gimbatul. Ash nazg thrakatulûk. Agh burzum-ishi krimpatul> returns bad data: ${output}")
+endif()
+
+
+check_errors("STRING:HEX" ${errors})
diff --git a/Tests/RunCMake/GenEx-STRING/JOIN.cmake.in b/Tests/RunCMake/GenEx-STRING/JOIN.cmake.in
new file mode 100644
index 0000000..2441a13
--- /dev/null
+++ b/Tests/RunCMake/GenEx-STRING/JOIN.cmake.in
@@ -0,0 +1,32 @@
+
+cmake_minimum_required(VERSION 4.2...4.3)
+
+include ("${RunCMake_SOURCE_DIR}/check_errors.cmake")
+unset (errors)
+
+string(JOIN "|" reference "ab" "cd")
+set(output "$<STRING:JOIN,|,ab,cd>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:JOIN,|,ab,cd> returns bad data: ${output}")
+endif()
+
+string(JOIN "" reference "ab" "cd")
+set(output "$<STRING:JOIN,,ab,cd>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:JOIN,,ab,cd> returns bad data: ${output}")
+endif()
+
+string(JOIN "|" reference)
+set(output "$<STRING:JOIN,|,>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:JOIN,|,> returns bad data: ${output}")
+endif()
+
+string(JOIN "" reference)
+set(output "$<STRING:JOIN,,>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:JOIN,,> returns bad data: ${output}")
+endif()
+
+
+check_errors("STRING:JOIN" ${errors})
diff --git a/Tests/RunCMake/GenEx-STRING/LENGTH.cmake.in b/Tests/RunCMake/GenEx-STRING/LENGTH.cmake.in
new file mode 100644
index 0000000..5f28f0c
--- /dev/null
+++ b/Tests/RunCMake/GenEx-STRING/LENGTH.cmake.in
@@ -0,0 +1,21 @@
+
+cmake_minimum_required(VERSION 4.2...4.3)
+
+include ("${RunCMake_SOURCE_DIR}/check_errors.cmake")
+unset (errors)
+
+string(LENGTH  "abc" reference)
+set(output "$<STRING:LENGTH,abc>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:LENGTH,abc> returns bad data: ${output}")
+endif()
+
+
+string(LENGTH  "" reference)
+set(output "$<STRING:LENGTH,>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:LENGTH,> returns bad data: ${output}")
+endif()
+
+
+check_errors("STRING:LENGTH" ${errors})
diff --git a/Tests/RunCMake/file/CREATE_LINK-noarg-result.txt b/Tests/RunCMake/GenEx-STRING/MATCH-WrongArguments-result.txt
similarity index 100%
copy from Tests/RunCMake/file/CREATE_LINK-noarg-result.txt
copy to Tests/RunCMake/GenEx-STRING/MATCH-WrongArguments-result.txt
diff --git a/Tests/RunCMake/GenEx-STRING/MATCH-WrongArguments-stderr.txt b/Tests/RunCMake/GenEx-STRING/MATCH-WrongArguments-stderr.txt
new file mode 100644
index 0000000..a7034a7
--- /dev/null
+++ b/Tests/RunCMake/GenEx-STRING/MATCH-WrongArguments-stderr.txt
@@ -0,0 +1,28 @@
+CMake Error at MATCH-WrongArguments\.cmake:[0-9]+ \(add_custom_target\):
+  Error evaluating generator expression:
+
+    \$<STRING:MATCH,string,\(>
+
+  Failed to compile regex "\("
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
+
+
+CMake Error at MATCH-WrongArguments\.cmake:[0-9]+ \(add_custom_target\):
+  Error evaluating generator expression:
+
+    \$<STRING:MATCH,string,FOO,\.\+>
+
+  Expected option 'SEEK:' is missing.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
+
+
+CMake Error at MATCH-WrongArguments\.cmake:[0-9]+ \(add_custom_target\):
+  Error evaluating generator expression:
+
+    \$<STRING:MATCH,string,SEEK:FOO,\.\+>
+
+  Invalid value for 'SEEK:' option.  'ONCE' or 'ALL' expected.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-STRING/MATCH-WrongArguments.cmake b/Tests/RunCMake/GenEx-STRING/MATCH-WrongArguments.cmake
new file mode 100644
index 0000000..f7d8044
--- /dev/null
+++ b/Tests/RunCMake/GenEx-STRING/MATCH-WrongArguments.cmake
@@ -0,0 +1,8 @@
+
+add_custom_target(check ALL COMMAND check
+  [[
+     $<STRING:MATCH,string,(>
+     $<STRING:MATCH,string,FOO,.+>
+     $<STRING:MATCH,string,SEEK:FOO,.+>
+  ]]
+VERBATIM)
diff --git a/Tests/RunCMake/GenEx-STRING/MATCH.cmake.in b/Tests/RunCMake/GenEx-STRING/MATCH.cmake.in
new file mode 100644
index 0000000..1e7abf7
--- /dev/null
+++ b/Tests/RunCMake/GenEx-STRING/MATCH.cmake.in
@@ -0,0 +1,40 @@
+
+cmake_minimum_required(VERSION 4.2...4.3)
+
+include ("${RunCMake_SOURCE_DIR}/check_errors.cmake")
+unset (errors)
+
+string(REGEX MATCH "cd" reference "abcdabcd")
+set(output "$<STRING:MATCH,abcdabcd,cd>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:MATCH,abcdabcd,cd> returns bad data: ${output}")
+endif()
+set(output "$<STRING:MATCH,abcdabcd,SEEK:ONCE,cd>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:MATCH,abcdabcd,SEEK:ONCE,cd> returns bad data: ${output}")
+endif()
+
+string(REGEX MATCH "(b|B)cd" reference "abcdABcd")
+set(output "$<STRING:MATCH,abcdABcd,(b|B)cd>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:MATCH,abcdABcd,B(cd)> returns bad data: ${output}")
+endif()
+set(output "$<STRING:MATCH,abcdABcd,(b|B)cd,SEEK:ONCE>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:MATCH,abcdABcd,B(cd),SEEK:ONCE> returns bad data: ${output}")
+endif()
+
+string(REGEX MATCHALL "cd" reference "abcdabcd")
+set(output "$<STRING:MATCH,abcdabcd,SEEK:ALL,cd>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:MATCH,abcdabcd,SEEK:ALL,cd> returns bad data: ${output}")
+endif()
+
+string(REGEX MATCHALL "(b|B)cd" reference "abcdABcd")
+set(output "$<STRING:MATCH,abcdABcd,(b|B)cd,SEEK:ALL>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:MATCH,abcdABcd,B(cd),SEEK:ALL> returns bad data: ${output}")
+endif()
+
+
+check_errors("STRING:MATCH" ${errors})
diff --git a/Tests/RunCMake/GenEx-STRING/PREPEND.cmake.in b/Tests/RunCMake/GenEx-STRING/PREPEND.cmake.in
new file mode 100644
index 0000000..93542ec
--- /dev/null
+++ b/Tests/RunCMake/GenEx-STRING/PREPEND.cmake.in
@@ -0,0 +1,22 @@
+
+cmake_minimum_required(VERSION 4.2...4.3)
+
+include ("${RunCMake_SOURCE_DIR}/check_errors.cmake")
+unset (errors)
+
+set(reference "abcd")
+string(PREPEND reference  "efg" "ABCD")
+set(output "$<STRING:PREPEND,abcd,efg,ABCD>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:PREPEND,abcd,efg,ABCD> returns bad data: ${output}")
+endif()
+
+unset(reference)
+string(PREPEND reference  "efg" "ABCD")
+set(output "$<STRING:PREPEND,,efg,ABCD>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:PREPEND,,efg,ABCD> returns bad data: ${output}")
+endif()
+
+
+check_errors("STRING:PREPEND" ${errors})
diff --git a/Tests/RunCMake/file/CREATE_LINK-noarg-result.txt b/Tests/RunCMake/GenEx-STRING/QUOTE-WrongArguments-result.txt
similarity index 100%
copy from Tests/RunCMake/file/CREATE_LINK-noarg-result.txt
copy to Tests/RunCMake/GenEx-STRING/QUOTE-WrongArguments-result.txt
diff --git a/Tests/RunCMake/GenEx-STRING/QUOTE-WrongArguments-stderr.txt b/Tests/RunCMake/GenEx-STRING/QUOTE-WrongArguments-stderr.txt
new file mode 100644
index 0000000..8270c94
--- /dev/null
+++ b/Tests/RunCMake/GenEx-STRING/QUOTE-WrongArguments-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at QUOTE-WrongArguments\.cmake:[0-9]+ \(add_custom_target\):
+  Error evaluating generator expression:
+
+    \$<STRING:QUOTE,FOO,string>
+
+  'FOO' is unexpected.  'REGEX' expected.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-STRING/QUOTE-WrongArguments.cmake b/Tests/RunCMake/GenEx-STRING/QUOTE-WrongArguments.cmake
new file mode 100644
index 0000000..0ddbbf4
--- /dev/null
+++ b/Tests/RunCMake/GenEx-STRING/QUOTE-WrongArguments.cmake
@@ -0,0 +1,6 @@
+
+add_custom_target(check ALL COMMAND check
+  [[
+     $<STRING:QUOTE,FOO,string>
+  ]]
+VERBATIM)
diff --git a/Tests/RunCMake/GenEx-STRING/QUOTE.cmake.in b/Tests/RunCMake/GenEx-STRING/QUOTE.cmake.in
new file mode 100644
index 0000000..2bcb238
--- /dev/null
+++ b/Tests/RunCMake/GenEx-STRING/QUOTE.cmake.in
@@ -0,0 +1,21 @@
+
+cmake_minimum_required(VERSION 4.2...4.3)
+
+include ("${RunCMake_SOURCE_DIR}/check_errors.cmake")
+unset (errors)
+
+string(REGEX QUOTE reference "abcd")
+set(output "$<STRING:QUOTE,REGEX,abcd>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:QUOTE,REGEX,abcd> returns bad data: ${output}")
+endif()
+
+string(REGEX QUOTE reference "ab|c+12?3[x-z]$(y)\\t\\r\\n.cma*ke^[:alpha:] ")
+set(output [[
+$<STRING:QUOTE,REGEX,ab|c+12?3[x-z]$(y)\t\r\n.cma*ke^[:alpha:]> ]])
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:QUOTE,REGEX,ab|c+12?3[x-z]$(y)\\t\\r\\n.cma*ke^[:alpha:]> returns bad data: ${output}")
+endif()
+
+
+check_errors("STRING:QUOTE" ${errors})
diff --git a/Tests/RunCMake/file/CREATE_LINK-noarg-result.txt b/Tests/RunCMake/GenEx-STRING/RANDOM-WrongArguments-result.txt
similarity index 100%
copy from Tests/RunCMake/file/CREATE_LINK-noarg-result.txt
copy to Tests/RunCMake/GenEx-STRING/RANDOM-WrongArguments-result.txt
diff --git a/Tests/RunCMake/GenEx-STRING/RANDOM-WrongArguments-stderr.txt b/Tests/RunCMake/GenEx-STRING/RANDOM-WrongArguments-stderr.txt
new file mode 100644
index 0000000..3f0b042
--- /dev/null
+++ b/Tests/RunCMake/GenEx-STRING/RANDOM-WrongArguments-stderr.txt
@@ -0,0 +1,18 @@
+CMake Error at RANDOM-WrongArguments\.cmake:[0-9]+ \(add_custom_target\):
+  Error evaluating generator expression:
+
+    \$<STRING:RANDOM,LENGTH:foo>
+
+  LENGTH:foo: invalid numeric value for 'LENGTH:' option.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
+
+
+CMake Error at RANDOM-WrongArguments\.cmake:[0-9]+ \(add_custom_target\):
+  Error evaluating generator expression:
+
+    \$<STRING:RANDOM,RANDOM_SEED:foo>
+
+  RANDOM_SEED:foo: invalid numeric value for 'RANDOM_SEED:' option.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-STRING/RANDOM-WrongArguments.cmake b/Tests/RunCMake/GenEx-STRING/RANDOM-WrongArguments.cmake
new file mode 100644
index 0000000..ac089d6
--- /dev/null
+++ b/Tests/RunCMake/GenEx-STRING/RANDOM-WrongArguments.cmake
@@ -0,0 +1,5 @@
+
+add_custom_target(check ALL COMMAND check
+  $<STRING:RANDOM,LENGTH:foo>
+   $<STRING:RANDOM,RANDOM_SEED:foo>
+VERBATIM)
diff --git a/Tests/RunCMake/GenEx-STRING/RANDOM.cmake.in b/Tests/RunCMake/GenEx-STRING/RANDOM.cmake.in
new file mode 100644
index 0000000..e90e1d9
--- /dev/null
+++ b/Tests/RunCMake/GenEx-STRING/RANDOM.cmake.in
@@ -0,0 +1,32 @@
+
+cmake_minimum_required(VERSION 4.2...4.3)
+
+include ("${RunCMake_SOURCE_DIR}/check_errors.cmake")
+unset (errors)
+
+string(RANDOM RANDOM_SEED 123 reference)
+set(output "$<STRING:RANDOM,RANDOM_SEED:123>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:RANDOM,RANDOM_SEED:123> returns bad data: ${output}")
+endif()
+
+string(RANDOM LENGTH 9 RANDOM_SEED 5 reference)
+set(output "$<STRING:RANDOM,LENGTH:9,RANDOM_SEED:5>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:RANDOM,LENGTH:9,RANDOM_SEED:5> returns bad data: ${output}")
+endif()
+
+string(RANDOM LENGTH 9 RANDOM_SEED 5 ALPHABET "" reference)
+set(output "$<STRING:RANDOM,LENGTH:9,RANDOM_SEED:5,ALPHABET:>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:RANDOM,LENGTH:9,RANDOM_SEED:5,ALPHABET:> returns bad data: ${output}")
+endif()
+
+string(RANDOM LENGTH 9 RANDOM_SEED 5 ALPHABET "abcdef123456789" reference)
+set(output "$<STRING:RANDOM,LENGTH:9,RANDOM_SEED:5,ALPHABET:abcdef123456789>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:RANDOM,LENGTH:9,RANDOM_SEED:5,ALPHABET:abcdef123456789> returns bad data: ${output}")
+endif()
+
+
+check_errors("STRING:RANDOM" ${errors})
diff --git a/Tests/RunCMake/file/CREATE_LINK-noarg-result.txt b/Tests/RunCMake/GenEx-STRING/REPLACE-WrongArguments-result.txt
similarity index 100%
copy from Tests/RunCMake/file/CREATE_LINK-noarg-result.txt
copy to Tests/RunCMake/GenEx-STRING/REPLACE-WrongArguments-result.txt
diff --git a/Tests/RunCMake/GenEx-STRING/REPLACE-WrongArguments-stderr.txt b/Tests/RunCMake/GenEx-STRING/REPLACE-WrongArguments-stderr.txt
new file mode 100644
index 0000000..843a104
--- /dev/null
+++ b/Tests/RunCMake/GenEx-STRING/REPLACE-WrongArguments-stderr.txt
@@ -0,0 +1,18 @@
+CMake Error at REPLACE-WrongArguments\.cmake:[0-9]+ \(add_custom_target\):
+  Error evaluating generator expression:
+
+    \$<STRING:REPLACE,FOO,string,\.\+,>
+
+  'FOO' is unexpected.  'STRING' or 'REGEX' expected.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
+
+
+CMake Error at REPLACE-WrongArguments\.cmake:[0-9]+ \(add_custom_target\):
+  Error evaluating generator expression:
+
+    \$<STRING:REPLACE,REGEX,string,\(,>
+
+  Failed to compile regex "\("
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-STRING/REPLACE-WrongArguments.cmake b/Tests/RunCMake/GenEx-STRING/REPLACE-WrongArguments.cmake
new file mode 100644
index 0000000..80085b1
--- /dev/null
+++ b/Tests/RunCMake/GenEx-STRING/REPLACE-WrongArguments.cmake
@@ -0,0 +1,7 @@
+
+add_custom_target(check ALL COMMAND check
+  [[
+     $<STRING:REPLACE,FOO,string,.+,>
+     $<STRING:REPLACE,REGEX,string,(,>
+  ]]
+VERBATIM)
diff --git a/Tests/RunCMake/GenEx-STRING/REPLACE.cmake.in b/Tests/RunCMake/GenEx-STRING/REPLACE.cmake.in
new file mode 100644
index 0000000..559ad7d
--- /dev/null
+++ b/Tests/RunCMake/GenEx-STRING/REPLACE.cmake.in
@@ -0,0 +1,44 @@
+
+cmake_minimum_required(VERSION 4.2...4.3)
+
+include ("${RunCMake_SOURCE_DIR}/check_errors.cmake")
+unset (errors)
+
+string(REPLACE  "bcd" "BCD" reference "abcdabcd")
+set(output "$<STRING:REPLACE,abcdabcd,bcd,BCD>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:REPLACE,abcdabcd,bcd,BCD> returns bad data: ${output}")
+endif()
+set(output "$<STRING:REPLACE,STRING,abcdabcd,bcd,BCD>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:REPLACE,STRING,abcdabcd,bcd,BCD> returns bad data: ${output}")
+endif()
+
+string(REPLACE  "bcd" "" reference "abcdabcd")
+set(output "$<STRING:REPLACE,abcdabcd,bcd,>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:REPLACE,abcdabcd,bcd,> returns bad data: ${output}")
+endif()
+set(output "$<STRING:REPLACE,STRING,abcdabcd,bcd,>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:REPLACE,STRING,abcdabcd,bcd,> returns bad data: ${output}")
+endif()
+
+string(REPLACE  "xyz" "BCD" reference "abcdabcd")
+set(output "$<STRING:REPLACE,abcdabcd,xyz,BCD>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:REPLACE,abcdabcd,xyz,BCD> returns bad data: ${output}")
+endif()
+set(output "$<STRING:REPLACE,STRING,abcdabcd,xyz,BCD>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:REPLACE,STRING,abcdabcd,xyz,BCD> returns bad data: ${output}")
+endif()
+
+string(REGEX REPLACE  "bcd" "BCD" reference "abcdabcd")
+set(output "$<STRING:REPLACE,REGEX,abcdabcd,bcd,BCD>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:REPLACE,REGEX,abcdabcd,bcd,BCD> returns bad data: ${output}")
+endif()
+
+
+check_errors("STRING:REPLACE" ${errors})
diff --git a/Tests/RunCMake/GenEx-STRING/RunCMakeTest.cmake b/Tests/RunCMake/GenEx-STRING/RunCMakeTest.cmake
new file mode 100644
index 0000000..d3dba10
--- /dev/null
+++ b/Tests/RunCMake/GenEx-STRING/RunCMakeTest.cmake
@@ -0,0 +1,80 @@
+
+include(RunCMake)
+
+run_cmake(no-arguments)
+run_cmake(bad-option)
+
+function(check_string_syntax name test)
+  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${name}-${test}-build)
+  set(RunCMake_TEST_VARIANT_DESCRIPTION " - ${name}")
+  run_cmake_with_options(${test} ${ARGN})
+endfunction()
+
+## Unexpected arguments
+### sub-commands with one argument
+foreach (subcommand IN ITEMS LENGTH TOLOWER TOUPPER HEX MAKE_C_IDENTIFIER)
+  check_string_syntax (${subcommand} unexpected-arg "-DSTRING_ARGUMENTS=${subcommand},ARG1,ARG2")
+endforeach()
+
+### sub-commands with two arguments
+foreach (subcommand IN ITEMS HASH STRIP QUOTE)
+  check_string_syntax (${subcommand} unexpected-arg "-DSTRING_ARGUMENTS=${subcommand},ARG1,ARG2,ARG3")
+endforeach()
+
+### sub-commands with three arguments
+foreach (subcommand IN ITEMS SUBSTRING)
+  check_string_syntax (${subcommand} unexpected-arg "-DSTRING_ARGUMENTS=${subcommand},ARG1,ARG2,ARG3,ARG4")
+endforeach()
+foreach (subcommand IN ITEMS FIND MATCH RANDOM)
+  check_string_syntax (${subcommand} unexpected-arg2 "-DSTRING_ARGUMENTS=${subcommand},ARG1,ARG2,ARG3,ARG4")
+endforeach()
+
+### sub-commands with four arguments
+foreach (subcommand IN ITEMS REPLACE)
+  check_string_syntax (${subcommand} unexpected-arg2 "-DSTRING_ARGUMENTS=${subcommand},ARG1,ARG2,ARG3,ARG4,ARG5")
+endforeach()
+
+run_cmake(SUBSTRING-WrongArguments)
+run_cmake(FIND-WrongArguments)
+run_cmake(MATCH-WrongArguments)
+run_cmaKE(ASCII-WrongArguments)
+run_cmake(TIMESTAMP-WrongArguments)
+run_cmake(RANDOM-WrongArguments)
+run_cmake(UUID-WrongArguments)
+run_cmake(REPLACE-WrongArguments)
+run_cmake(STRIP-WrongArguments)
+run_cmake(QUOTE-WrongArguments)
+run_cmake(HASH-WrongArguments)
+
+
+function(check_string_execution name)
+  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${name}-build)
+  if(RunCMake_GENERATOR_IS_MULTI_CONFIG)
+    set(CONFIG_OPTION -DCMAKE_CONFIGURATION_TYPES=Debug)
+  else()
+    set(CONFIG_OPTION -DCMAKE_BUILD_TYPE=Debug)
+  endif()
+  set(RunCMake_TEST_NO_CLEAN 1)
+  set(RunCMake_TEST_VARIANT_DESCRIPTION " - ${name}")
+  run_cmake_with_options(generate -DSTRING_TEST=${name} ${CONFIG_OPTION})
+  run_cmake_command(check "${CMAKE_COMMAND}" "-DRunCMake_SOURCE_DIR=${RunCMake_SOURCE_DIR}" -P "${RunCMake_TEST_BINARY_DIR}/${name}.cmake")
+endfunction()
+
+check_string_execution (LENGTH)
+check_string_execution (SUBSTRING)
+check_string_execution (FIND)
+check_string_execution (MATCH)
+check_string_execution (JOIN)
+check_string_execution (ASCII)
+check_string_execution (TIMESTAMP)
+check_string_execution (RANDOM)
+check_string_execution (UUID)
+check_string_execution (REPLACE)
+check_string_execution (APPEND)
+check_string_execution (PREPEND)
+check_string_execution (TOLOWER)
+check_string_execution (TOUPPER)
+check_string_execution (STRIP)
+check_string_execution (QUOTE)
+check_string_execution (HEX)
+check_string_execution (HASH)
diff --git a/Tests/RunCMake/file/CREATE_LINK-noarg-result.txt b/Tests/RunCMake/GenEx-STRING/STRIP-WrongArguments-result.txt
similarity index 100%
copy from Tests/RunCMake/file/CREATE_LINK-noarg-result.txt
copy to Tests/RunCMake/GenEx-STRING/STRIP-WrongArguments-result.txt
diff --git a/Tests/RunCMake/GenEx-STRING/STRIP-WrongArguments-stderr.txt b/Tests/RunCMake/GenEx-STRING/STRIP-WrongArguments-stderr.txt
new file mode 100644
index 0000000..6663aa4
--- /dev/null
+++ b/Tests/RunCMake/GenEx-STRING/STRIP-WrongArguments-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at STRIP-WrongArguments\.cmake:[0-9]+ \(add_custom_target\):
+  Error evaluating generator expression:
+
+    \$<STRING:STRIP,FOO,string>
+
+  'FOO' is unexpected.  'SPACES' expected.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-STRING/STRIP-WrongArguments.cmake b/Tests/RunCMake/GenEx-STRING/STRIP-WrongArguments.cmake
new file mode 100644
index 0000000..357f2b4
--- /dev/null
+++ b/Tests/RunCMake/GenEx-STRING/STRIP-WrongArguments.cmake
@@ -0,0 +1,6 @@
+
+add_custom_target(check ALL COMMAND check
+  [[
+     $<STRING:STRIP,FOO,string>
+  ]]
+VERBATIM)
diff --git a/Tests/RunCMake/GenEx-STRING/STRIP.cmake.in b/Tests/RunCMake/GenEx-STRING/STRIP.cmake.in
new file mode 100644
index 0000000..4f51c02
--- /dev/null
+++ b/Tests/RunCMake/GenEx-STRING/STRIP.cmake.in
@@ -0,0 +1,14 @@
+
+cmake_minimum_required(VERSION 4.2...4.3)
+
+include ("${RunCMake_SOURCE_DIR}/check_errors.cmake")
+unset (errors)
+
+string(STRIP " ABCD  "  reference)
+set(output "$<STRING:STRIP,SPACES, ABCD  >")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:STRIP,SPACES, ABCD  > returns bad data: ${output}")
+endif()
+
+
+check_errors("STRING:STRIP" ${errors})
diff --git a/Tests/RunCMake/file/CREATE_LINK-noarg-result.txt b/Tests/RunCMake/GenEx-STRING/SUBSTRING-WrongArguments-result.txt
similarity index 100%
copy from Tests/RunCMake/file/CREATE_LINK-noarg-result.txt
copy to Tests/RunCMake/GenEx-STRING/SUBSTRING-WrongArguments-result.txt
diff --git a/Tests/RunCMake/GenEx-STRING/SUBSTRING-WrongArguments-stderr.txt b/Tests/RunCMake/GenEx-STRING/SUBSTRING-WrongArguments-stderr.txt
new file mode 100644
index 0000000..7d65b41
--- /dev/null
+++ b/Tests/RunCMake/GenEx-STRING/SUBSTRING-WrongArguments-stderr.txt
@@ -0,0 +1,38 @@
+CMake Error at SUBSTRING-WrongArguments\.cmake:[0-9]+ \(add_custom_target\):
+  Error evaluating generator expression:
+
+    \$<STRING:SUBSTRING,string,foo,1>
+
+  index: "foo" is not a valid index
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
+
+
+CMake Error at SUBSTRING-WrongArguments\.cmake:[0-9]+ \(add_custom_target\):
+  Error evaluating generator expression:
+
+    \$<STRING:SUBSTRING,string,1,foo>
+
+  index: "foo" is not a valid index
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
+
+
+CMake Error at SUBSTRING-WrongArguments\.cmake:[0-9]+ \(add_custom_target\):
+  Error evaluating generator expression:
+
+    \$<STRING:SUBSTRING,string,-1,2>
+
+  begin index: -1 is out of range 0 - 6
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
+
+
+CMake Error at SUBSTRING-WrongArguments\.cmake:[0-9]+ \(add_custom_target\):
+  Error evaluating generator expression:
+
+    \$<STRING:SUBSTRING,string,1,-2>
+
+  end index: -2 should be -1 or greater
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-STRING/SUBSTRING-WrongArguments.cmake b/Tests/RunCMake/GenEx-STRING/SUBSTRING-WrongArguments.cmake
new file mode 100644
index 0000000..1c39a37
--- /dev/null
+++ b/Tests/RunCMake/GenEx-STRING/SUBSTRING-WrongArguments.cmake
@@ -0,0 +1,7 @@
+
+add_custom_target(check ALL COMMAND check
+  $<STRING:SUBSTRING,string,foo,1>
+  $<STRING:SUBSTRING,string,1,foo>
+  $<STRING:SUBSTRING,string,-1,2>
+  $<STRING:SUBSTRING,string,1,-2>
+VERBATIM)
diff --git a/Tests/RunCMake/GenEx-STRING/SUBSTRING.cmake.in b/Tests/RunCMake/GenEx-STRING/SUBSTRING.cmake.in
new file mode 100644
index 0000000..6ff4ad4
--- /dev/null
+++ b/Tests/RunCMake/GenEx-STRING/SUBSTRING.cmake.in
@@ -0,0 +1,26 @@
+
+cmake_minimum_required(VERSION 4.2...4.3)
+
+include ("${RunCMake_SOURCE_DIR}/check_errors.cmake")
+unset (errors)
+
+string(SUBSTRING  "abcd" 1 2 reference)
+set(output "$<STRING:SUBSTRING,abcd,1,2>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:SUBSTRING,abcd,1,2> returns bad data: ${output}")
+endif()
+
+string(SUBSTRING  "abcd" 1 -1 reference)
+set(output "$<STRING:SUBSTRING,abcd,1,-1>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:SUBSTRING,abcd,1,-1> returns bad data: ${output}")
+endif()
+
+string(SUBSTRING  "abcd" 1 5 reference)
+set(output "$<STRING:SUBSTRING,abcd,1,5>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:SUBSTRING,abcd,1,5> returns bad data: ${output}")
+endif()
+
+
+check_errors("STRING:SUBSTRING" ${errors})
diff --git a/Tests/RunCMake/file/CREATE_LINK-noarg-result.txt b/Tests/RunCMake/GenEx-STRING/TIMESTAMP-WrongArguments-result.txt
similarity index 100%
copy from Tests/RunCMake/file/CREATE_LINK-noarg-result.txt
copy to Tests/RunCMake/GenEx-STRING/TIMESTAMP-WrongArguments-result.txt
diff --git a/Tests/RunCMake/GenEx-STRING/TIMESTAMP-WrongArguments-stderr.txt b/Tests/RunCMake/GenEx-STRING/TIMESTAMP-WrongArguments-stderr.txt
new file mode 100644
index 0000000..ebcb19e
--- /dev/null
+++ b/Tests/RunCMake/GenEx-STRING/TIMESTAMP-WrongArguments-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at TIMESTAMP-WrongArguments\.cmake:[0-9]+ \(add_custom_target\):
+  Error evaluating generator expression:
+
+    \$<STRING:TIMESTAMP,%s,%s>
+
+  'UTC' option is expected.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-STRING/TIMESTAMP-WrongArguments.cmake b/Tests/RunCMake/GenEx-STRING/TIMESTAMP-WrongArguments.cmake
new file mode 100644
index 0000000..012aaf7
--- /dev/null
+++ b/Tests/RunCMake/GenEx-STRING/TIMESTAMP-WrongArguments.cmake
@@ -0,0 +1,4 @@
+
+add_custom_target(check ALL COMMAND check
+  $<STRING:TIMESTAMP,%s,%s>
+VERBATIM)
diff --git a/Tests/RunCMake/GenEx-STRING/TIMESTAMP.cmake.in b/Tests/RunCMake/GenEx-STRING/TIMESTAMP.cmake.in
new file mode 100644
index 0000000..adc2b98
--- /dev/null
+++ b/Tests/RunCMake/GenEx-STRING/TIMESTAMP.cmake.in
@@ -0,0 +1,27 @@
+
+cmake_minimum_required(VERSION 4.2...4.3)
+
+include ("${RunCMake_SOURCE_DIR}/check_errors.cmake")
+unset (errors)
+
+set(ENV{SOURCE_DATE_EPOCH} "1123456789")
+
+string(TIMESTAMP reference "%Y-%m-%d %H:%M:%S.%f %A=%a %B=%b %y day=%j wd=%w week=%U w_iso=%V %%I=%I epoch=%s TZ=%Z tz=%z")
+set(output "$<STRING:TIMESTAMP,%Y-%m-%d %H:%M:%S.%f %A=%a %B=%b %y day=%j wd=%w week=%U w_iso=%V %%I=%I epoch=%s TZ=%Z tz=%z>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:TIMESTAMP,%Y-%m-%d %H:%M:%S.%f %A=%a %B=%b %y day=%j wd=%w week=%U w_iso=%V %%I=%I epoch=%s TZ=%Z tz=%z> returns bad data: ${output}")
+endif()
+
+
+string(TIMESTAMP reference "%Y-%m-%d %H:%M:%S.%f %A=%a %B=%b %y day=%j wd=%w week=%U w_iso=%V %%I=%I epoch=%s TZ=%Z tz=%z" UTC)
+set(output "$<STRING:TIMESTAMP,%Y-%m-%d %H:%M:%S.%f %A=%a %B=%b %y day=%j wd=%w week=%U w_iso=%V %%I=%I epoch=%s TZ=%Z tz=%z,UTC>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:TIMESTAMP,%Y-%m-%d %H:%M:%S.%f %A=%a %B=%b %y day=%j wd=%w week=%U w_iso=%V %%I=%I epoch=%s TZ=%Z tz=%z,UTC> returns bad data: ${output}")
+endif()
+set(output "$<STRING:TIMESTAMP,UTC,%Y-%m-%d %H:%M:%S.%f %A=%a %B=%b %y day=%j wd=%w week=%U w_iso=%V %%I=%I epoch=%s TZ=%Z tz=%z>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:TIMESTAMP,UTC,%Y-%m-%d %H:%M:%S.%f %A=%a %B=%b %y day=%j wd=%w week=%U w_iso=%V %%I=%I epoch=%s TZ=%Z tz=%z> returns bad data: ${output}")
+endif()
+
+
+check_errors("STRING:TIMESTAMP" ${errors})
diff --git a/Tests/RunCMake/GenEx-STRING/TOLOWER.cmake.in b/Tests/RunCMake/GenEx-STRING/TOLOWER.cmake.in
new file mode 100644
index 0000000..dfb18d6
--- /dev/null
+++ b/Tests/RunCMake/GenEx-STRING/TOLOWER.cmake.in
@@ -0,0 +1,26 @@
+
+cmake_minimum_required(VERSION 4.2...4.3)
+
+include ("${RunCMake_SOURCE_DIR}/check_errors.cmake")
+unset (errors)
+
+string(TOLOWER "ABCD"  reference)
+set(output "$<STRING:TOLOWER,ABCD>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:TOLOWER,ABCD> returns bad data: ${output}")
+endif()
+
+string(TOLOWER "abcd"  reference)
+set(output "$<STRING:TOLOWER,abcd>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:TOLOWER,abcd> returns bad data: ${output}")
+endif()
+
+string(TOLOWER "abcdABCD12@!"  reference)
+set(output "$<STRING:TOLOWER,abcdABCD12@!>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:TOLOWER,abcdABCD12@!> returns bad data: ${output}")
+endif()
+
+
+check_errors("STRING:TOLOWER" ${errors})
diff --git a/Tests/RunCMake/GenEx-STRING/TOUPPER.cmake.in b/Tests/RunCMake/GenEx-STRING/TOUPPER.cmake.in
new file mode 100644
index 0000000..562c4f1
--- /dev/null
+++ b/Tests/RunCMake/GenEx-STRING/TOUPPER.cmake.in
@@ -0,0 +1,26 @@
+
+cmake_minimum_required(VERSION 4.2...4.3)
+
+include ("${RunCMake_SOURCE_DIR}/check_errors.cmake")
+unset (errors)
+
+string(TOUPPER "abcd"  reference)
+set(output "$<STRING:TOUPPER,abcd>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:TOUPPER,abcd> returns bad data: ${output}")
+endif()
+
+string(TOUPPER "ABCD"  reference)
+set(output "$<STRING:TOUPPER,ABCD>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:TOUPPER,ABCD> returns bad data: ${output}")
+endif()
+
+string(TOUPPER "abcdABCD12@!"  reference)
+set(output "$<STRING:TOUPPER,abcdABCD12@!>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:TOUPPER,abcdABCD12@!> returns bad data: ${output}")
+endif()
+
+
+check_errors("STRING:TOUPPER" ${errors})
diff --git a/Tests/RunCMake/file/CREATE_LINK-noarg-result.txt b/Tests/RunCMake/GenEx-STRING/UUID-WrongArguments-result.txt
similarity index 100%
copy from Tests/RunCMake/file/CREATE_LINK-noarg-result.txt
copy to Tests/RunCMake/GenEx-STRING/UUID-WrongArguments-result.txt
diff --git a/Tests/RunCMake/GenEx-STRING/UUID-WrongArguments-stderr.txt b/Tests/RunCMake/GenEx-STRING/UUID-WrongArguments-stderr.txt
new file mode 100644
index 0000000..e2e4317
--- /dev/null
+++ b/Tests/RunCMake/GenEx-STRING/UUID-WrongArguments-stderr.txt
@@ -0,0 +1,28 @@
+CMake Error at UUID-WrongArguments\.cmake:[0-9]+ \(add_custom_target\):
+  Error evaluating generator expression:
+
+    \$<STRING:UUID,TYPE:MD5,NAMESPACE:>
+
+  Invalid value for 'NAMESPACE:' option.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
+
+
+CMake Error at UUID-WrongArguments\.cmake:[0-9]+ \(add_custom_target\):
+  Error evaluating generator expression:
+
+    \$<STRING:UUID,NAMESPACE:foo,TYPE:FOO>
+
+  Invalid value for 'TYPE:' option.  'MD5' or 'SHA1' expected.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
+
+
+CMake Error at UUID-WrongArguments\.cmake:[0-9]+ \(add_custom_target\):
+  Error evaluating generator expression:
+
+    \$<STRING:UUID,NAMESPACE:foo,TYPE:MD5,CASE:FOO>
+
+  Invalid value for 'CASE:' option.  'UPPER' or 'LOWER' expected.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-STRING/UUID-WrongArguments.cmake b/Tests/RunCMake/GenEx-STRING/UUID-WrongArguments.cmake
new file mode 100644
index 0000000..72783b8
--- /dev/null
+++ b/Tests/RunCMake/GenEx-STRING/UUID-WrongArguments.cmake
@@ -0,0 +1,6 @@
+
+add_custom_target(check ALL COMMAND check
+  $<STRING:UUID,TYPE:MD5,NAMESPACE:>
+  $<STRING:UUID,NAMESPACE:foo,TYPE:FOO>
+  $<STRING:UUID,NAMESPACE:foo,TYPE:MD5,CASE:FOO>
+VERBATIM)
diff --git a/Tests/RunCMake/GenEx-STRING/UUID.cmake.in b/Tests/RunCMake/GenEx-STRING/UUID.cmake.in
new file mode 100644
index 0000000..47b7690
--- /dev/null
+++ b/Tests/RunCMake/GenEx-STRING/UUID.cmake.in
@@ -0,0 +1,32 @@
+
+cmake_minimum_required(VERSION 4.2...4.3)
+
+include ("${RunCMake_SOURCE_DIR}/check_errors.cmake")
+unset (errors)
+
+set(UUID_DNS_NAMESPACE 6ba7b810-9dad-11d1-80b4-00c04fd430c8)
+
+string(UUID reference NAMESPACE ${UUID_DNS_NAMESPACE} NAME www.example.com TYPE MD5)
+set(output "$<STRING:UUID,NAMESPACE:6ba7b810-9dad-11d1-80b4-00c04fd430c8,NAME:www.example.com,TYPE:MD5>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:UUID,NAMESPACE:6ba7b810-9dad-11d1-80b4-00c04fd430c8,NAME:www.example.com,TYPE:MD5> returns bad data: ${output}")
+endif()
+set(output "$<STRING:UUID,NAMESPACE:6ba7b810-9dad-11d1-80b4-00c04fd430c8,NAME:www.example.com,TYPE:MD5,CASE:LOWER>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:UUID,NAMESPACE:6ba7b810-9dad-11d1-80b4-00c04fd430c8,NAME:www.example.com,TYPE:MD5,CASE:LOWER> returns bad data: ${output}")
+endif()
+
+string(UUID reference NAMESPACE ${UUID_DNS_NAMESPACE} NAME www.example.com TYPE MD5 UPPER)
+set(output "$<STRING:UUID,NAMESPACE:6ba7b810-9dad-11d1-80b4-00c04fd430c8,NAME:www.example.com,TYPE:MD5,CASE:UPPER>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:UUID,NAMESPACE:6ba7b810-9dad-11d1-80b4-00c04fd430c8,NAME:www.example.com,TYPE:MD5,CASE:UPPER> returns bad data: ${output}")
+endif()
+
+string(UUID reference NAMESPACE ${UUID_DNS_NAMESPACE} NAME www.example.com TYPE SHA1)
+set(output "$<STRING:UUID,NAMESPACE:6ba7b810-9dad-11d1-80b4-00c04fd430c8,NAME:www.example.com,TYPE:SHA1>")
+if (NOT output STREQUAL reference)
+  list (APPEND errors "<STRING:UUID,NAMESPACE:6ba7b810-9dad-11d1-80b4-00c04fd430c8,NAME:www.example.com,TYPE:SHA1> returns bad data: ${output}")
+endif()
+
+
+check_errors("STRING:UUID" ${errors})
diff --git a/Tests/RunCMake/CXXModules/examples/circular-build-result.txt b/Tests/RunCMake/GenEx-STRING/bad-option-result.txt
similarity index 100%
copy from Tests/RunCMake/CXXModules/examples/circular-build-result.txt
copy to Tests/RunCMake/GenEx-STRING/bad-option-result.txt
diff --git a/Tests/RunCMake/GenEx-STRING/bad-option-stderr.txt b/Tests/RunCMake/GenEx-STRING/bad-option-stderr.txt
new file mode 100644
index 0000000..2c86102
--- /dev/null
+++ b/Tests/RunCMake/GenEx-STRING/bad-option-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at bad-option\.cmake:[0-9]+ \(file\):
+  Error evaluating generator expression:
+
+    \$<STRING:BAD_OPTION>
+
+  BAD_OPTION: invalid option.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-STRING/bad-option.cmake b/Tests/RunCMake/GenEx-STRING/bad-option.cmake
new file mode 100644
index 0000000..c6ca817
--- /dev/null
+++ b/Tests/RunCMake/GenEx-STRING/bad-option.cmake
@@ -0,0 +1,2 @@
+
+file(GENERATE OUTPUT result.txt CONTENT "$<STRING:BAD_OPTION>")
diff --git a/Tests/RunCMake/GenEx-STRING/check_errors.cmake b/Tests/RunCMake/GenEx-STRING/check_errors.cmake
new file mode 100644
index 0000000..462475c
--- /dev/null
+++ b/Tests/RunCMake/GenEx-STRING/check_errors.cmake
@@ -0,0 +1,13 @@
+
+function (CHECK_ERRORS command)
+  set (errors ${ARGN})
+  set (command "$<${command}>")
+  if (errors)
+    string (LENGTH "${command}" length)
+    math (EXPR count "${length} + 2")
+    string (REPEAT " " ${count} shift)
+    list (TRANSFORM errors PREPEND "${shift}$")
+    list (JOIN errors "\n" msg)
+    message (FATAL_ERROR "${command}: ${msg}")
+  endif()
+endfunction()
diff --git a/Tests/RunCMake/GenEx-STRING/generate.cmake b/Tests/RunCMake/GenEx-STRING/generate.cmake
new file mode 100644
index 0000000..8d3d409
--- /dev/null
+++ b/Tests/RunCMake/GenEx-STRING/generate.cmake
@@ -0,0 +1,6 @@
+
+if (STRING_TEST STREQUAL "TIMESTAMP")
+  set(ENV{SOURCE_DATE_EPOCH} "1123456789")
+endif()
+
+file(GENERATE OUTPUT "${STRING_TEST}.cmake" INPUT "${STRING_TEST}.cmake.in")
diff --git a/Tests/RunCMake/CXXModules/examples/circular-build-result.txt b/Tests/RunCMake/GenEx-STRING/no-arguments-result.txt
similarity index 100%
copy from Tests/RunCMake/CXXModules/examples/circular-build-result.txt
copy to Tests/RunCMake/GenEx-STRING/no-arguments-result.txt
diff --git a/Tests/RunCMake/GenEx-STRING/no-arguments-stderr.txt b/Tests/RunCMake/GenEx-STRING/no-arguments-stderr.txt
new file mode 100644
index 0000000..6f789bb
--- /dev/null
+++ b/Tests/RunCMake/GenEx-STRING/no-arguments-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at no-arguments\.cmake:[0-9]+ \(file\):
+  Error evaluating generator expression:
+
+    \$<STRING:>
+
+  \$<STRING> expression requires at least one parameter.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-STRING/no-arguments.cmake b/Tests/RunCMake/GenEx-STRING/no-arguments.cmake
new file mode 100644
index 0000000..ee47380
--- /dev/null
+++ b/Tests/RunCMake/GenEx-STRING/no-arguments.cmake
@@ -0,0 +1,2 @@
+
+file(GENERATE OUTPUT result.txt CONTENT "$<STRING:>")
diff --git a/Tests/RunCMake/file/CREATE_LINK-noarg-result.txt b/Tests/RunCMake/GenEx-STRING/unexpected-arg-result.txt
similarity index 100%
copy from Tests/RunCMake/file/CREATE_LINK-noarg-result.txt
copy to Tests/RunCMake/GenEx-STRING/unexpected-arg-result.txt
diff --git a/Tests/RunCMake/GenEx-STRING/unexpected-arg-stderr.txt b/Tests/RunCMake/GenEx-STRING/unexpected-arg-stderr.txt
new file mode 100644
index 0000000..ef0c038
--- /dev/null
+++ b/Tests/RunCMake/GenEx-STRING/unexpected-arg-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at unexpected-arg\.cmake:[0-9]+ \(file\):
+  Error evaluating generator expression:
+
+    \$<STRING:[A-Z_]+,.+>
+
+  \$<STRING:[A-Z_:]+(,[A-Z_:]+(,[A-Z_:]+)?)?> expression requires exactly (one|two|three) parameters?.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-STRING/unexpected-arg.cmake b/Tests/RunCMake/GenEx-STRING/unexpected-arg.cmake
new file mode 100644
index 0000000..793fbb1
--- /dev/null
+++ b/Tests/RunCMake/GenEx-STRING/unexpected-arg.cmake
@@ -0,0 +1,2 @@
+
+file(GENERATE OUTPUT result.txt CONTENT "$<STRING:${STRING_ARGUMENTS}>")
diff --git a/Tests/RunCMake/file/CREATE_LINK-noarg-result.txt b/Tests/RunCMake/GenEx-STRING/unexpected-arg2-result.txt
similarity index 100%
copy from Tests/RunCMake/file/CREATE_LINK-noarg-result.txt
copy to Tests/RunCMake/GenEx-STRING/unexpected-arg2-result.txt
diff --git a/Tests/RunCMake/GenEx-STRING/unexpected-arg2-stderr.txt b/Tests/RunCMake/GenEx-STRING/unexpected-arg2-stderr.txt
new file mode 100644
index 0000000..27c8b1a
--- /dev/null
+++ b/Tests/RunCMake/GenEx-STRING/unexpected-arg2-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at unexpected-arg2\.cmake:[0-9]+ \(file\):
+  Error evaluating generator expression:
+
+    \$<STRING:[A-Z_]+,.+>
+
+  \$<STRING:[A-Z_:]+(,[A-Z_:]+(,[A-Z_:]+)?)?> expression expects at most (two|three|four) parameters?.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-STRING/unexpected-arg2.cmake b/Tests/RunCMake/GenEx-STRING/unexpected-arg2.cmake
new file mode 100644
index 0000000..793fbb1
--- /dev/null
+++ b/Tests/RunCMake/GenEx-STRING/unexpected-arg2.cmake
@@ -0,0 +1,2 @@
+
+file(GENERATE OUTPUT result.txt CONTENT "$<STRING:${STRING_ARGUMENTS}>")
diff --git a/Tests/RunCMake/CXXModules/examples/circular-build-result.txt b/Tests/RunCMake/GeneratorExpression/BadStrGreater-result.txt
similarity index 100%
copy from Tests/RunCMake/CXXModules/examples/circular-build-result.txt
copy to Tests/RunCMake/GeneratorExpression/BadStrGreater-result.txt
diff --git a/Tests/RunCMake/GeneratorExpression/BadStrGreater-stderr.txt b/Tests/RunCMake/GeneratorExpression/BadStrGreater-stderr.txt
new file mode 100644
index 0000000..b6e1513
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/BadStrGreater-stderr.txt
@@ -0,0 +1,40 @@
+CMake Error at BadStrGreater.cmake:1 \(add_custom_target\):
+  Error evaluating generator expression:
+
+    \$<STRGREATER>
+
+  \$<STRGREATER> expression requires 2 comma separated parameters, but got 0
+  instead.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
++CMake Error at BadStrGreater.cmake:1 \(add_custom_target\):
+  Error evaluating generator expression:
+
+    \$<STRGREATER:>
+
+  \$<STRGREATER> expression requires 2 comma separated parameters, but got 1
+  instead.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
++
+CMake Error at BadStrGreater.cmake:1 \(add_custom_target\):
+  Error evaluating generator expression:
+
+    \$<STRGREATER:,,>
+
+  \$<STRGREATER> expression requires 2 comma separated parameters, but got 3
+  instead.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
++
+CMake Error at BadStrGreater.cmake:1 \(add_custom_target\):
+  Error evaluating generator expression:
+
+    \$<STRGREATER:something,,>
+
+  \$<STRGREATER> expression requires 2 comma separated parameters, but got 3
+  instead.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
++
+CMake Generate step failed\.  Build files cannot be regenerated correctly\.$
diff --git a/Tests/RunCMake/GeneratorExpression/BadStrGreater.cmake b/Tests/RunCMake/GeneratorExpression/BadStrGreater.cmake
new file mode 100644
index 0000000..ea8324b
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/BadStrGreater.cmake
@@ -0,0 +1,6 @@
+add_custom_target(check ALL COMMAND check
+  $<STRGREATER>
+  $<STRGREATER:>
+  $<STRGREATER:,,>
+  $<STRGREATER:something,,>
+  VERBATIM)
diff --git a/Tests/RunCMake/CXXModules/examples/circular-build-result.txt b/Tests/RunCMake/GeneratorExpression/BadStrGreaterEqual-result.txt
similarity index 100%
copy from Tests/RunCMake/CXXModules/examples/circular-build-result.txt
copy to Tests/RunCMake/GeneratorExpression/BadStrGreaterEqual-result.txt
diff --git a/Tests/RunCMake/GeneratorExpression/BadStrGreaterEqual-stderr.txt b/Tests/RunCMake/GeneratorExpression/BadStrGreaterEqual-stderr.txt
new file mode 100644
index 0000000..04d1e76
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/BadStrGreaterEqual-stderr.txt
@@ -0,0 +1,40 @@
+CMake Error at BadStrGreaterEqual.cmake:1 \(add_custom_target\):
+  Error evaluating generator expression:
+
+    \$<STRGREATER_EQUAL>
+
+  \$<STRGREATER_EQUAL> expression requires 2 comma separated parameters, but
+  got 0 instead.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
++CMake Error at BadStrGreaterEqual.cmake:1 \(add_custom_target\):
+  Error evaluating generator expression:
+
+    \$<STRGREATER_EQUAL:>
+
+  \$<STRGREATER_EQUAL> expression requires 2 comma separated parameters, but
+  got 1 instead.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
++
+CMake Error at BadStrGreaterEqual.cmake:1 \(add_custom_target\):
+  Error evaluating generator expression:
+
+    \$<STRGREATER_EQUAL:,,>
+
+  \$<STRGREATER_EQUAL> expression requires 2 comma separated parameters, but
+  got 3 instead.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
++
+CMake Error at BadStrGreaterEqual.cmake:1 \(add_custom_target\):
+  Error evaluating generator expression:
+
+    \$<STRGREATER_EQUAL:something,,>
+
+  \$<STRGREATER_EQUAL> expression requires 2 comma separated parameters, but
+  got 3 instead.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
++
+CMake Generate step failed\.  Build files cannot be regenerated correctly\.$
diff --git a/Tests/RunCMake/GeneratorExpression/BadStrGreaterEqual.cmake b/Tests/RunCMake/GeneratorExpression/BadStrGreaterEqual.cmake
new file mode 100644
index 0000000..53af1e1
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/BadStrGreaterEqual.cmake
@@ -0,0 +1,6 @@
+add_custom_target(check ALL COMMAND check
+  $<STRGREATER_EQUAL>
+  $<STRGREATER_EQUAL:>
+  $<STRGREATER_EQUAL:,,>
+  $<STRGREATER_EQUAL:something,,>
+  VERBATIM)
diff --git a/Tests/RunCMake/CXXModules/examples/circular-build-result.txt b/Tests/RunCMake/GeneratorExpression/BadStrLess-result.txt
similarity index 100%
copy from Tests/RunCMake/CXXModules/examples/circular-build-result.txt
copy to Tests/RunCMake/GeneratorExpression/BadStrLess-result.txt
diff --git a/Tests/RunCMake/GeneratorExpression/BadStrLess-stderr.txt b/Tests/RunCMake/GeneratorExpression/BadStrLess-stderr.txt
new file mode 100644
index 0000000..321423b
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/BadStrLess-stderr.txt
@@ -0,0 +1,40 @@
+CMake Error at BadStrLess.cmake:1 \(add_custom_target\):
+  Error evaluating generator expression:
+
+    \$<STRLESS>
+
+  \$<STRLESS> expression requires 2 comma separated parameters, but got 0
+  instead.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
++CMake Error at BadStrLess.cmake:1 \(add_custom_target\):
+  Error evaluating generator expression:
+
+    \$<STRLESS:>
+
+  \$<STRLESS> expression requires 2 comma separated parameters, but got 1
+  instead.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
++
+CMake Error at BadStrLess.cmake:1 \(add_custom_target\):
+  Error evaluating generator expression:
+
+    \$<STRLESS:,,>
+
+  \$<STRLESS> expression requires 2 comma separated parameters, but got 3
+  instead.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
++
+CMake Error at BadStrLess.cmake:1 \(add_custom_target\):
+  Error evaluating generator expression:
+
+    \$<STRLESS:something,,>
+
+  \$<STRLESS> expression requires 2 comma separated parameters, but got 3
+  instead.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
++
+CMake Generate step failed\.  Build files cannot be regenerated correctly\.$
diff --git a/Tests/RunCMake/GeneratorExpression/BadStrLess.cmake b/Tests/RunCMake/GeneratorExpression/BadStrLess.cmake
new file mode 100644
index 0000000..06cd868
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/BadStrLess.cmake
@@ -0,0 +1,6 @@
+add_custom_target(check ALL COMMAND check
+  $<STRLESS>
+  $<STRLESS:>
+  $<STRLESS:,,>
+  $<STRLESS:something,,>
+  VERBATIM)
diff --git a/Tests/RunCMake/CXXModules/examples/circular-build-result.txt b/Tests/RunCMake/GeneratorExpression/BadStrLessEqual-result.txt
similarity index 100%
copy from Tests/RunCMake/CXXModules/examples/circular-build-result.txt
copy to Tests/RunCMake/GeneratorExpression/BadStrLessEqual-result.txt
diff --git a/Tests/RunCMake/GeneratorExpression/BadStrLessEqual-stderr.txt b/Tests/RunCMake/GeneratorExpression/BadStrLessEqual-stderr.txt
new file mode 100644
index 0000000..7fbbf38
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/BadStrLessEqual-stderr.txt
@@ -0,0 +1,40 @@
+CMake Error at BadStrLessEqual.cmake:1 \(add_custom_target\):
+  Error evaluating generator expression:
+
+    \$<STRLESS_EQUAL>
+
+  \$<STRLESS_EQUAL> expression requires 2 comma separated parameters, but got
+  0 instead.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
++CMake Error at BadStrLessEqual.cmake:1 \(add_custom_target\):
+  Error evaluating generator expression:
+
+    \$<STRLESS_EQUAL:>
+
+  \$<STRLESS_EQUAL> expression requires 2 comma separated parameters, but got
+  1 instead.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
++
+CMake Error at BadStrLessEqual.cmake:1 \(add_custom_target\):
+  Error evaluating generator expression:
+
+    \$<STRLESS_EQUAL:,,>
+
+  \$<STRLESS_EQUAL> expression requires 2 comma separated parameters, but got
+  3 instead.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
++
+CMake Error at BadStrLessEqual.cmake:1 \(add_custom_target\):
+  Error evaluating generator expression:
+
+    \$<STRLESS_EQUAL:something,,>
+
+  \$<STRLESS_EQUAL> expression requires 2 comma separated parameters, but got
+  3 instead.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
++
+CMake Generate step failed\.  Build files cannot be regenerated correctly\.$
diff --git a/Tests/RunCMake/GeneratorExpression/BadStrLessEqual.cmake b/Tests/RunCMake/GeneratorExpression/BadStrLessEqual.cmake
new file mode 100644
index 0000000..10b6edd
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/BadStrLessEqual.cmake
@@ -0,0 +1,6 @@
+add_custom_target(check ALL COMMAND check
+  $<STRLESS_EQUAL>
+  $<STRLESS_EQUAL:>
+  $<STRLESS_EQUAL:,,>
+  $<STRLESS_EQUAL:something,,>
+  VERBATIM)
diff --git a/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake b/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake
index 9c968c6..a53cf87 100644
--- a/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake
+++ b/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake
@@ -7,6 +7,15 @@
 run_cmake(BadAND)
 run_cmake(BadNOT)
 run_cmake(BadStrEqual)
+run_cmake(BadStrLess)
+run_cmake(BadStrLessEqual)
+run_cmake(BadStrGreater)
+run_cmake(BadStrGreaterEqual)
+run_cmake(STREQUAL)
+run_cmake(STRLESS)
+run_cmake(STRLESS_EQUAL)
+run_cmake(STRGREATER)
+run_cmake(STRGREATER_EQUAL)
 run_cmake(BadZero)
 run_cmake(BadTargetName)
 run_cmake(BadTargetTypeInterface)
diff --git a/Tests/RunCMake/GeneratorExpression/STREQUAL-check.cmake b/Tests/RunCMake/GeneratorExpression/STREQUAL-check.cmake
new file mode 100644
index 0000000..13b5aba
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/STREQUAL-check.cmake
@@ -0,0 +1,6 @@
+file(READ "${RunCMake_TEST_BINARY_DIR}/STREQUAL-generated.txt" content)
+
+set(expected "1:0")
+if(NOT content STREQUAL expected)
+  set(RunCMake_TEST_FAILED "$<STREQUAL>: actual content:\n [[${content}]]\nbut expected:\n [[${expected}]]")
+endif()
diff --git a/Tests/RunCMake/GeneratorExpression/STREQUAL.cmake b/Tests/RunCMake/GeneratorExpression/STREQUAL.cmake
new file mode 100644
index 0000000..e1f8669
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/STREQUAL.cmake
@@ -0,0 +1,3 @@
+cmake_policy(VERSION 4.2)
+
+file(GENERATE OUTPUT "STREQUAL-generated.txt" CONTENT "$<STREQUAL:AA,AA>:$<STREQUAL:AA,BB>")
diff --git a/Tests/RunCMake/GeneratorExpression/STRGREATER-check.cmake b/Tests/RunCMake/GeneratorExpression/STRGREATER-check.cmake
new file mode 100644
index 0000000..a361b40
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/STRGREATER-check.cmake
@@ -0,0 +1,6 @@
+file(READ "${RunCMake_TEST_BINARY_DIR}/STRGREATER-generated.txt" content)
+
+set(expected "0:0:0:1")
+if(NOT content STREQUAL expected)
+  set(RunCMake_TEST_FAILED "$<STRGREATER>: actual content:\n [[${content}]]\nbut expected:\n [[${expected}]]")
+endif()
diff --git a/Tests/RunCMake/GeneratorExpression/STRGREATER.cmake b/Tests/RunCMake/GeneratorExpression/STRGREATER.cmake
new file mode 100644
index 0000000..8a82a54
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/STRGREATER.cmake
@@ -0,0 +1,3 @@
+cmake_policy(VERSION 4.2)
+
+file(GENERATE OUTPUT "STRGREATER-generated.txt" CONTENT "$<STRGREATER:A,AA>:$<STRGREATER:AA,BB>:$<STRGREATER:AA,AA>:$<STRGREATER:BB,AA>")
diff --git a/Tests/RunCMake/GeneratorExpression/STRGREATER_EQUAL-check.cmake b/Tests/RunCMake/GeneratorExpression/STRGREATER_EQUAL-check.cmake
new file mode 100644
index 0000000..d866228
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/STRGREATER_EQUAL-check.cmake
@@ -0,0 +1,6 @@
+file(READ "${RunCMake_TEST_BINARY_DIR}/STRGREATER_EQUAL-generated.txt" content)
+
+set(expected "0:0:1:1")
+if(NOT content STREQUAL expected)
+  set(RunCMake_TEST_FAILED "$<STRGREATER_EQUAL>: actual content:\n [[${content}]]\nbut expected:\n [[${expected}]]")
+endif()
diff --git a/Tests/RunCMake/GeneratorExpression/STRGREATER_EQUAL.cmake b/Tests/RunCMake/GeneratorExpression/STRGREATER_EQUAL.cmake
new file mode 100644
index 0000000..50e604b
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/STRGREATER_EQUAL.cmake
@@ -0,0 +1,4 @@
+cmake_policy(VERSION 4.2)
+
+file(GENERATE OUTPUT "STRGREATER_EQUAL-generated.txt"
+              CONTENT "$<STRGREATER_EQUAL:A,AA>:$<STRGREATER_EQUAL:AA,BB>:$<STRGREATER_EQUAL:AA,AA>:$<STRGREATER_EQUAL:BB,AA>")
diff --git a/Tests/RunCMake/GeneratorExpression/STRLESS-check.cmake b/Tests/RunCMake/GeneratorExpression/STRLESS-check.cmake
new file mode 100644
index 0000000..08d5206
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/STRLESS-check.cmake
@@ -0,0 +1,6 @@
+file(READ "${RunCMake_TEST_BINARY_DIR}/STRLESS-generated.txt" content)
+
+set(expected "1:1:0:0")
+if(NOT content STREQUAL expected)
+  set(RunCMake_TEST_FAILED "$<STRLESS>: actual content:\n [[${content}]]\nbut expected:\n [[${expected}]]")
+endif()
diff --git a/Tests/RunCMake/GeneratorExpression/STRLESS.cmake b/Tests/RunCMake/GeneratorExpression/STRLESS.cmake
new file mode 100644
index 0000000..59a2799
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/STRLESS.cmake
@@ -0,0 +1,3 @@
+cmake_policy(VERSION 4.2)
+
+file(GENERATE OUTPUT "STRLESS-generated.txt" CONTENT "$<STRLESS:A,AA>:$<STRLESS:AA,BB>:$<STRLESS:AA,AA>:$<STRLESS:BB,AA>")
diff --git a/Tests/RunCMake/GeneratorExpression/STRLESS_EQUAL-check.cmake b/Tests/RunCMake/GeneratorExpression/STRLESS_EQUAL-check.cmake
new file mode 100644
index 0000000..3ad56e4
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/STRLESS_EQUAL-check.cmake
@@ -0,0 +1,6 @@
+file(READ "${RunCMake_TEST_BINARY_DIR}/STRLESS_EQUAL-generated.txt" content)
+
+set(expected "1:1:1:0")
+if(NOT content STREQUAL expected)
+  set(RunCMake_TEST_FAILED "$<STRLESS_EQUAL>: actual content:\n [[${content}]]\nbut expected:\n [[${expected}]]")
+endif()
diff --git a/Tests/RunCMake/GeneratorExpression/STRLESS_EQUAL.cmake b/Tests/RunCMake/GeneratorExpression/STRLESS_EQUAL.cmake
new file mode 100644
index 0000000..3e3fd36
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/STRLESS_EQUAL.cmake
@@ -0,0 +1,4 @@
+cmake_policy(VERSION 4.2)
+
+file(GENERATE OUTPUT "STRLESS_EQUAL-generated.txt"
+              CONTENT "$<STRLESS_EQUAL:A,AA>:$<STRLESS_EQUAL:AA,BB>:$<STRLESS_EQUAL:AA,AA>:$<STRLESS_EQUAL:BB,AA>")
diff --git a/Tests/RunCMake/GoogleTest/GoogleTest-discovery-POST_BUILD-timeout-build-stdout.txt b/Tests/RunCMake/GoogleTest/GoogleTest-discovery-POST_BUILD-timeout-build-stdout.txt
index a7d7151..def5cf3 100644
--- a/Tests/RunCMake/GoogleTest/GoogleTest-discovery-POST_BUILD-timeout-build-stdout.txt
+++ b/Tests/RunCMake/GoogleTest/GoogleTest-discovery-POST_BUILD-timeout-build-stdout.txt
@@ -1,8 +1,10 @@
-( *|[0-9]+>)CMake Error at .*GoogleTestAddTests\.cmake:[0-9]+ \(message\):
+( *|[0-9]+>)CMake Error at [^
+]*GoogleTestAddTests\.cmake:[0-9]+ \(message\):
 ( *|[0-9]+>)  Error running test executable\.
 ?( *|[0-9]+>)
-( *|[0-9]+>)    Path: '.*discovery_timeout_test(\.exe)?'
+( *|[0-9]+>)    Path: '[^']*discovery_timeout_test(\.exe)?'
 ( *|[0-9]+>)    Working directory: '[^']*/Tests/RunCMake/GoogleTest/GoogleTest-discovery-timeout'
+( *|[0-9]+>)    Timeout: '[^']*'
 ( *|[0-9]+>)    Result: Process terminated due to timeout
 ( *|[0-9]+>)    Output:
 ( *|[0-9]+>)     +
diff --git a/Tests/RunCMake/GoogleTest/GoogleTest-discovery-PRE_TEST-timeout-test-stderr.txt b/Tests/RunCMake/GoogleTest/GoogleTest-discovery-PRE_TEST-timeout-test-stderr.txt
index 72c6ce1..9518930 100644
--- a/Tests/RunCMake/GoogleTest/GoogleTest-discovery-PRE_TEST-timeout-test-stderr.txt
+++ b/Tests/RunCMake/GoogleTest/GoogleTest-discovery-PRE_TEST-timeout-test-stderr.txt
@@ -1,8 +1,10 @@
-CMake Error at .*GoogleTestAddTests\.cmake:[0-9]+ \(message\):
+CMake Error at [^
+]*GoogleTestAddTests\.cmake:[0-9]+ \(message\):
 [ \t]*Error running test executable\.
 +
-[ \t]*Path: '.*discovery_timeout_test(\.exe)?'
+[ \t]*Path: '[^']*discovery_timeout_test(\.exe)?'
 [ \t]*Working directory: '[^']*/Tests/RunCMake/GoogleTest/GoogleTest-discovery-timeout'
+[ \t]*Timeout: '[^']*'
 [ \t]*Result: Process terminated due to timeout
 [ \t]*Output:
 [ \t]*timeout\.
diff --git a/Tests/RunCMake/InstallExportsAsPackageInfo/Assertions.cmake b/Tests/RunCMake/InstallExportsAsPackageInfo/Assertions.cmake
new file mode 100644
index 0000000..068074d
--- /dev/null
+++ b/Tests/RunCMake/InstallExportsAsPackageInfo/Assertions.cmake
@@ -0,0 +1,39 @@
+macro(_expect entity op actual expected)
+  if(NOT "${actual}" ${op} "${expected}")
+    list(JOIN ARGN "." name)
+    set(RunCMake_TEST_FAILED
+      "Attribute '${name}' ${entity} '${actual}' does not match expected ${entity} '${expected}'" PARENT_SCOPE)
+    return()
+  endif()
+endmacro()
+
+function(expect_value content expected_value)
+  string(JSON actual_value GET "${content}" ${ARGN})
+  _expect("value" STREQUAL "${actual_value}" "${expected_value}" ${ARGN})
+endfunction()
+
+function(expect_array content expected_length)
+  string(JSON actual_type TYPE "${content}" ${ARGN})
+  _expect("type" STREQUAL "${actual_type}" "ARRAY" ${ARGN})
+
+  string(JSON actual_length LENGTH "${content}" ${ARGN})
+  _expect("length" EQUAL "${actual_length}" "${expected_length}" ${ARGN})
+endfunction()
+
+function(expect_object content)
+  string(JSON actual_type TYPE "${content}" ${ARGN})
+  _expect("type" STREQUAL "${actual_type}" "OBJECT" ${ARGN})
+endfunction()
+
+function(expect_null content)
+  string(JSON actual_type TYPE "${content}" ${ARGN})
+  _expect("type" STREQUAL "${actual_type}" "NULL" ${ARGN})
+endfunction()
+
+function(expect_missing content)
+  string(JSON value ERROR_VARIABLE error GET "${content}" ${ARGN})
+  if(NOT value MATCHES "^(.*-)?NOTFOUND$")
+    set(RunCMake_TEST_FAILED
+      "Attribute '${ARGN}' is unexpectedly present" PARENT_SCOPE)
+  endif()
+endfunction()
diff --git a/Tests/RunCMake/CXXModules/examples/circular-build-result.txt b/Tests/RunCMake/InstallExportsAsPackageInfo/BadDirective-result.txt
similarity index 100%
copy from Tests/RunCMake/CXXModules/examples/circular-build-result.txt
copy to Tests/RunCMake/InstallExportsAsPackageInfo/BadDirective-result.txt
diff --git a/Tests/RunCMake/InstallExportsAsPackageInfo/BadDirective-stderr.txt b/Tests/RunCMake/InstallExportsAsPackageInfo/BadDirective-stderr.txt
new file mode 100644
index 0000000..10cead8
--- /dev/null
+++ b/Tests/RunCMake/InstallExportsAsPackageInfo/BadDirective-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at BadDirective\.cmake:2 \(install\):
+  install CMAKE_INSTALL_EXPORTS_AS_PACKAGE_INFO given unrecognized directive
+  "error"\.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:3 \(include\)
diff --git a/Tests/RunCMake/InstallExportsAsPackageInfo/BadDirective.cmake b/Tests/RunCMake/InstallExportsAsPackageInfo/BadDirective.cmake
new file mode 100644
index 0000000..e967511
--- /dev/null
+++ b/Tests/RunCMake/InstallExportsAsPackageInfo/BadDirective.cmake
@@ -0,0 +1,2 @@
+set(CMAKE_INSTALL_EXPORTS_AS_PACKAGE_INFO foo:foo/error)
+install(EXPORT foo FILE foo-targets.cmake DESTINATION .)
diff --git a/Tests/RunCMake/InstallExportsAsPackageInfo/CMakeLists.txt b/Tests/RunCMake/InstallExportsAsPackageInfo/CMakeLists.txt
new file mode 100644
index 0000000..abd58e2
--- /dev/null
+++ b/Tests/RunCMake/InstallExportsAsPackageInfo/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 4.2)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/InstallExportsAsPackageInfo/ExperimentalGate.cmake b/Tests/RunCMake/InstallExportsAsPackageInfo/ExperimentalGate.cmake
new file mode 100644
index 0000000..6675f62
--- /dev/null
+++ b/Tests/RunCMake/InstallExportsAsPackageInfo/ExperimentalGate.cmake
@@ -0,0 +1,6 @@
+unset(CMAKE_EXPERIMENTAL_MAPPED_PACKAGE_INFO)
+set(CMAKE_INSTALL_EXPORTS_AS_PACKAGE_INFO foo:)
+
+add_library(foo INTERFACE)
+install(TARGETS foo EXPORT foo DESTINATION .)
+install(EXPORT foo FILE foo-targets.cmake DESTINATION .)
diff --git a/Tests/RunCMake/InstallExportsAsPackageInfo/ExperimentalWarning-stderr.txt b/Tests/RunCMake/InstallExportsAsPackageInfo/ExperimentalWarning-stderr.txt
new file mode 100644
index 0000000..b761f9c
--- /dev/null
+++ b/Tests/RunCMake/InstallExportsAsPackageInfo/ExperimentalWarning-stderr.txt
@@ -0,0 +1,7 @@
+CMake Warning \(dev\) at ExperimentalWarning\.cmake:13 \(install\):
+  CMake's support for generating package information in the Common Package
+  Specification format from CMake script exports is experimental\.  It is
+  meant only for experimentation and feedback to CMake developers\.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:3 \(include\)
+This warning is for project developers\.  Use -Wno-dev to suppress it\.
diff --git a/Tests/RunCMake/InstallExportsAsPackageInfo/ExperimentalWarning.cmake b/Tests/RunCMake/InstallExportsAsPackageInfo/ExperimentalWarning.cmake
new file mode 100644
index 0000000..22fcb46
--- /dev/null
+++ b/Tests/RunCMake/InstallExportsAsPackageInfo/ExperimentalWarning.cmake
@@ -0,0 +1,13 @@
+set(
+  CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO
+  "b80be207-778e-46ba-8080-b23bba22639e"
+  )
+set(
+  CMAKE_EXPERIMENTAL_MAPPED_PACKAGE_INFO
+  "ababa1b5-7099-495f-a9cd-e22d38f274f2"
+  )
+unset(CMAKE_INSTALL_EXPORTS_AS_PACKAGE_INFO)
+
+add_library(foo INTERFACE)
+install(TARGETS foo EXPORT foo DESTINATION .)
+install(EXPORT foo FILE foo-targets.cmake DESTINATION .)
diff --git a/Tests/RunCMake/InstallExportsAsPackageInfo/LowerCase-check.cmake b/Tests/RunCMake/InstallExportsAsPackageInfo/LowerCase-check.cmake
new file mode 100644
index 0000000..09a7246
--- /dev/null
+++ b/Tests/RunCMake/InstallExportsAsPackageInfo/LowerCase-check.cmake
@@ -0,0 +1,27 @@
+include(${CMAKE_CURRENT_LIST_DIR}/Assertions.cmake)
+
+set(out_dir "${RunCMake_BINARY_DIR}/LowerCase-build/CMakeFiles/Export/510c5684a4a8a792eadfb55bc9744983")
+
+function(expect_in_list list value)
+  list(FIND ${list} "${value}" index)
+  if(${index} EQUAL -1)
+    set(RunCMake_TEST_FAILED
+      "Expected '${value}' in ${list} ('${${list}}'), but it was not found" PARENT_SCOPE)
+  endif()
+endfunction()
+
+file(GLOB files
+  LIST_DIRECTORIES false
+  RELATIVE "${out_dir}"
+  "${out_dir}/*.cps"
+)
+expect_in_list(files "farm.cps")
+expect_in_list(files "farm-extra.cps")
+
+file(READ "${out_dir}/farm.cps" content)
+expect_value("${content}" "Farm" "name")
+expect_value("${content}" "interface" "components" "Cow" "type")
+
+file(READ "${out_dir}/farm-extra.cps" content)
+expect_value("${content}" "Farm" "name")
+expect_value("${content}" "interface" "components" "Pig" "type")
diff --git a/Tests/RunCMake/InstallExportsAsPackageInfo/LowerCase.cmake b/Tests/RunCMake/InstallExportsAsPackageInfo/LowerCase.cmake
new file mode 100644
index 0000000..f08f39f
--- /dev/null
+++ b/Tests/RunCMake/InstallExportsAsPackageInfo/LowerCase.cmake
@@ -0,0 +1,12 @@
+set(CMAKE_INSTALL_EXPORTS_AS_PACKAGE_INFO
+  cow:Farm/l/cps
+  pig:Farm/laextra/cps
+)
+
+add_library(Cow INTERFACE)
+add_library(Pig INTERFACE)
+
+install(TARGETS Cow EXPORT cow)
+install(TARGETS Pig EXPORT pig)
+install(EXPORT cow FILE farm-targets.cmake DESTINATION .)
+install(EXPORT pig FILE farm-targets-extra.cmake DESTINATION .)
diff --git a/Tests/RunCMake/PrecompileHeaders/PchReuseFromCycle-result.txt b/Tests/RunCMake/InstallExportsAsPackageInfo/MissingAppendixName-result.txt
similarity index 100%
copy from Tests/RunCMake/PrecompileHeaders/PchReuseFromCycle-result.txt
copy to Tests/RunCMake/InstallExportsAsPackageInfo/MissingAppendixName-result.txt
diff --git a/Tests/RunCMake/InstallExportsAsPackageInfo/MissingAppendixName-stderr.txt b/Tests/RunCMake/InstallExportsAsPackageInfo/MissingAppendixName-stderr.txt
new file mode 100644
index 0000000..f63cc68
--- /dev/null
+++ b/Tests/RunCMake/InstallExportsAsPackageInfo/MissingAppendixName-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at MissingAppendixName.cmake:2 \(install\):
+  install CMAKE_INSTALL_EXPORTS_AS_PACKAGE_INFO given APPENDIX directive for
+  export "foo", but no appendix name was provided\.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:3 \(include\)
diff --git a/Tests/RunCMake/InstallExportsAsPackageInfo/MissingAppendixName.cmake b/Tests/RunCMake/InstallExportsAsPackageInfo/MissingAppendixName.cmake
new file mode 100644
index 0000000..08147e3
--- /dev/null
+++ b/Tests/RunCMake/InstallExportsAsPackageInfo/MissingAppendixName.cmake
@@ -0,0 +1,2 @@
+set(CMAKE_INSTALL_EXPORTS_AS_PACKAGE_INFO foo:foo/a)
+install(EXPORT foo FILE foo-targets.cmake DESTINATION .)
diff --git a/Tests/RunCMake/CXXModules/examples/circular-build-result.txt b/Tests/RunCMake/InstallExportsAsPackageInfo/MissingExport-result.txt
similarity index 100%
copy from Tests/RunCMake/CXXModules/examples/circular-build-result.txt
copy to Tests/RunCMake/InstallExportsAsPackageInfo/MissingExport-result.txt
diff --git a/Tests/RunCMake/InstallExportsAsPackageInfo/MissingExport-stderr.txt b/Tests/RunCMake/InstallExportsAsPackageInfo/MissingExport-stderr.txt
new file mode 100644
index 0000000..67e290b
--- /dev/null
+++ b/Tests/RunCMake/InstallExportsAsPackageInfo/MissingExport-stderr.txt
@@ -0,0 +1,3 @@
+CMake Error: INSTALL\(PACKAGE_INFO\) given unknown export "foo"
+CMake Error: INSTALL\(EXPORT\) given unknown export "foo"
+CMake Generate step failed\.  Build files cannot be regenerated correctly\.
diff --git a/Tests/RunCMake/InstallExportsAsPackageInfo/MissingExport.cmake b/Tests/RunCMake/InstallExportsAsPackageInfo/MissingExport.cmake
new file mode 100644
index 0000000..517af22
--- /dev/null
+++ b/Tests/RunCMake/InstallExportsAsPackageInfo/MissingExport.cmake
@@ -0,0 +1,2 @@
+set(CMAKE_INSTALL_EXPORTS_AS_PACKAGE_INFO foo:foo)
+install(EXPORT foo FILE foo-targets.cmake DESTINATION .)
diff --git a/Tests/RunCMake/PrecompileHeaders/PchReuseFromCycle-result.txt b/Tests/RunCMake/InstallExportsAsPackageInfo/MissingPackageName-result.txt
similarity index 100%
copy from Tests/RunCMake/PrecompileHeaders/PchReuseFromCycle-result.txt
copy to Tests/RunCMake/InstallExportsAsPackageInfo/MissingPackageName-result.txt
diff --git a/Tests/RunCMake/InstallExportsAsPackageInfo/MissingPackageName-stderr.txt b/Tests/RunCMake/InstallExportsAsPackageInfo/MissingPackageName-stderr.txt
new file mode 100644
index 0000000..99d4240
--- /dev/null
+++ b/Tests/RunCMake/InstallExportsAsPackageInfo/MissingPackageName-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at MissingPackageName.cmake:2 \(install\):
+  install CMAKE_INSTALL_EXPORTS_AS_PACKAGE_INFO missing package name for
+  export "foo"\.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:3 \(include\)
diff --git a/Tests/RunCMake/InstallExportsAsPackageInfo/MissingPackageName.cmake b/Tests/RunCMake/InstallExportsAsPackageInfo/MissingPackageName.cmake
new file mode 100644
index 0000000..8489637
--- /dev/null
+++ b/Tests/RunCMake/InstallExportsAsPackageInfo/MissingPackageName.cmake
@@ -0,0 +1,2 @@
+set(CMAKE_INSTALL_EXPORTS_AS_PACKAGE_INFO foo:)
+install(EXPORT foo FILE foo-targets.cmake DESTINATION .)
diff --git a/Tests/RunCMake/InstallExportsAsPackageInfo/RunCMakeTest.cmake b/Tests/RunCMake/InstallExportsAsPackageInfo/RunCMakeTest.cmake
new file mode 100644
index 0000000..7f35c13
--- /dev/null
+++ b/Tests/RunCMake/InstallExportsAsPackageInfo/RunCMakeTest.cmake
@@ -0,0 +1,22 @@
+include(RunCMake)
+
+# Test experimental gate
+run_cmake(ExperimentalGate)
+run_cmake(ExperimentalWarning)
+
+# Enable experimental feature and suppress warnings
+set(RunCMake_TEST_OPTIONS
+  -Wno-dev
+  "-DCMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO:STRING=b80be207-778e-46ba-8080-b23bba22639e"
+  "-DCMAKE_EXPERIMENTAL_MAPPED_PACKAGE_INFO:STRING=ababa1b5-7099-495f-a9cd-e22d38f274f2"
+  )
+
+# Test incorrect usage
+run_cmake(MissingPackageName)
+run_cmake(MissingAppendixName)
+run_cmake(MissingExport)
+run_cmake(BadDirective)
+
+# Test functionality
+run_cmake(SampleExport)
+run_cmake(LowerCase)
diff --git a/Tests/RunCMake/InstallExportsAsPackageInfo/SampleExport-check.cmake b/Tests/RunCMake/InstallExportsAsPackageInfo/SampleExport-check.cmake
new file mode 100644
index 0000000..fdeeefa
--- /dev/null
+++ b/Tests/RunCMake/InstallExportsAsPackageInfo/SampleExport-check.cmake
@@ -0,0 +1,19 @@
+include(${CMAKE_CURRENT_LIST_DIR}/Assertions.cmake)
+
+set(out_dir "${RunCMake_BINARY_DIR}/SampleExport-build/CMakeFiles/Export/510c5684a4a8a792eadfb55bc9744983")
+
+file(READ "${out_dir}/farm.cps" content)
+expect_value("${content}" "farm" "name")
+expect_value("${content}" "interface" "components" "cow" "type")
+expect_value("${content}" "1.2.3" "version")
+expect_value("${content}" "1.1.0" "compat_version")
+expect_value("${content}" "simple" "version_schema")
+expect_value("${content}" "Apache-2.0" "license")
+expect_value("${content}" "BSD-3-Clause" "default_license")
+expect_array("${content}" 2 "configurations")
+expect_value("${content}" "Small" "configurations" 0)
+expect_value("${content}" "Large" "configurations" 1)
+
+file(READ "${out_dir}/farm-extra.cps" content)
+expect_value("${content}" "farm" "name")
+expect_value("${content}" "interface" "components" "pig" "type")
diff --git a/Tests/RunCMake/InstallExportsAsPackageInfo/SampleExport.cmake b/Tests/RunCMake/InstallExportsAsPackageInfo/SampleExport.cmake
new file mode 100644
index 0000000..fedcec0
--- /dev/null
+++ b/Tests/RunCMake/InstallExportsAsPackageInfo/SampleExport.cmake
@@ -0,0 +1,22 @@
+cmake_minimum_required(VERSION 4.2)
+
+project(farm VERSION 1.2.3 COMPAT_VERSION 1.1.0)
+
+set(CMAKE_INSTALL_EXPORTS_AS_PACKAGE_INFO
+  cow:farm//cps
+  pig:farm/aextra/cps
+)
+set(cow_EXPORT_PACKAGE_INFO_VERSION @farm_VERSION@)
+set(cow_EXPORT_PACKAGE_INFO_COMPAT_VERSION @farm_COMPAT_VERSION@)
+set(cow_EXPORT_PACKAGE_INFO_VERSION_SCHEMA "simple")
+set(cow_EXPORT_PACKAGE_INFO_LICENSE "Apache-2.0")
+set(cow_EXPORT_PACKAGE_INFO_DEFAULT_LICENSE "BSD-3-Clause")
+set(cow_EXPORT_PACKAGE_INFO_DEFAULT_CONFIGURATIONS "Small;Large")
+
+add_library(cow INTERFACE)
+add_library(pig INTERFACE)
+
+install(TARGETS cow EXPORT cow)
+install(TARGETS pig EXPORT pig)
+install(EXPORT cow FILE farm-targets.cmake DESTINATION .)
+install(EXPORT pig FILE farm-targets-extra.cmake DESTINATION .)
diff --git a/Tests/RunCMake/PrecompileHeaders-Reuse/CMakeLists.txt b/Tests/RunCMake/PrecompileHeaders-Reuse/CMakeLists.txt
new file mode 100644
index 0000000..7dbf32e
--- /dev/null
+++ b/Tests/RunCMake/PrecompileHeaders-Reuse/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.15.0)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/PrecompileHeaders/PchReuseAppend-build-stderr.txt b/Tests/RunCMake/PrecompileHeaders-Reuse/PchReuseAppend-build-stderr.txt
similarity index 100%
rename from Tests/RunCMake/PrecompileHeaders/PchReuseAppend-build-stderr.txt
rename to Tests/RunCMake/PrecompileHeaders-Reuse/PchReuseAppend-build-stderr.txt
diff --git a/Tests/RunCMake/PrecompileHeaders/PchReuseAppend.cmake b/Tests/RunCMake/PrecompileHeaders-Reuse/PchReuseAppend.cmake
similarity index 100%
rename from Tests/RunCMake/PrecompileHeaders/PchReuseAppend.cmake
rename to Tests/RunCMake/PrecompileHeaders-Reuse/PchReuseAppend.cmake
diff --git a/Tests/RunCMake/PrecompileHeaders/PchReuseConsistency-build-stderr.txt b/Tests/RunCMake/PrecompileHeaders-Reuse/PchReuseConsistency-build-stderr.txt
similarity index 100%
rename from Tests/RunCMake/PrecompileHeaders/PchReuseConsistency-build-stderr.txt
rename to Tests/RunCMake/PrecompileHeaders-Reuse/PchReuseConsistency-build-stderr.txt
diff --git a/Tests/RunCMake/PrecompileHeaders/PchReuseConsistency.cmake b/Tests/RunCMake/PrecompileHeaders-Reuse/PchReuseConsistency.cmake
similarity index 100%
rename from Tests/RunCMake/PrecompileHeaders/PchReuseConsistency.cmake
rename to Tests/RunCMake/PrecompileHeaders-Reuse/PchReuseConsistency.cmake
diff --git a/Tests/RunCMake/PrecompileHeaders/PchReuseDeclarationOrder-build-stderr.txt b/Tests/RunCMake/PrecompileHeaders-Reuse/PchReuseDeclarationOrder-build-stderr.txt
similarity index 100%
rename from Tests/RunCMake/PrecompileHeaders/PchReuseDeclarationOrder-build-stderr.txt
rename to Tests/RunCMake/PrecompileHeaders-Reuse/PchReuseDeclarationOrder-build-stderr.txt
diff --git a/Tests/RunCMake/PrecompileHeaders/PchReuseDeclarationOrder.cmake b/Tests/RunCMake/PrecompileHeaders-Reuse/PchReuseDeclarationOrder.cmake
similarity index 100%
rename from Tests/RunCMake/PrecompileHeaders/PchReuseDeclarationOrder.cmake
rename to Tests/RunCMake/PrecompileHeaders-Reuse/PchReuseDeclarationOrder.cmake
diff --git a/Tests/RunCMake/PrecompileHeaders/PchReuseFrom-CMP0141-NEW-empty.cmake b/Tests/RunCMake/PrecompileHeaders-Reuse/PchReuseFrom-CMP0141-NEW-empty.cmake
similarity index 100%
rename from Tests/RunCMake/PrecompileHeaders/PchReuseFrom-CMP0141-NEW-empty.cmake
rename to Tests/RunCMake/PrecompileHeaders-Reuse/PchReuseFrom-CMP0141-NEW-empty.cmake
diff --git a/Tests/RunCMake/PrecompileHeaders/PchReuseFrom-CMP0141-NEW.cmake b/Tests/RunCMake/PrecompileHeaders-Reuse/PchReuseFrom-CMP0141-NEW.cmake
similarity index 100%
rename from Tests/RunCMake/PrecompileHeaders/PchReuseFrom-CMP0141-NEW.cmake
rename to Tests/RunCMake/PrecompileHeaders-Reuse/PchReuseFrom-CMP0141-NEW.cmake
diff --git a/Tests/RunCMake/PrecompileHeaders/PchReuseFrom-CMP0141-OLD-stderr.txt b/Tests/RunCMake/PrecompileHeaders-Reuse/PchReuseFrom-CMP0141-OLD-stderr.txt
similarity index 100%
rename from Tests/RunCMake/PrecompileHeaders/PchReuseFrom-CMP0141-OLD-stderr.txt
rename to Tests/RunCMake/PrecompileHeaders-Reuse/PchReuseFrom-CMP0141-OLD-stderr.txt
diff --git a/Tests/RunCMake/PrecompileHeaders/PchReuseFrom-CMP0141-OLD.cmake b/Tests/RunCMake/PrecompileHeaders-Reuse/PchReuseFrom-CMP0141-OLD.cmake
similarity index 100%
rename from Tests/RunCMake/PrecompileHeaders/PchReuseFrom-CMP0141-OLD.cmake
rename to Tests/RunCMake/PrecompileHeaders-Reuse/PchReuseFrom-CMP0141-OLD.cmake
diff --git a/Tests/RunCMake/PrecompileHeaders/PchReuseFrom-CMP0141-common.cmake b/Tests/RunCMake/PrecompileHeaders-Reuse/PchReuseFrom-CMP0141-common.cmake
similarity index 100%
rename from Tests/RunCMake/PrecompileHeaders/PchReuseFrom-CMP0141-common.cmake
rename to Tests/RunCMake/PrecompileHeaders-Reuse/PchReuseFrom-CMP0141-common.cmake
diff --git a/Tests/RunCMake/PrecompileHeaders/PchReuseFromCycle-result.txt b/Tests/RunCMake/PrecompileHeaders-Reuse/PchReuseFromCycle-result.txt
similarity index 100%
rename from Tests/RunCMake/PrecompileHeaders/PchReuseFromCycle-result.txt
rename to Tests/RunCMake/PrecompileHeaders-Reuse/PchReuseFromCycle-result.txt
diff --git a/Tests/RunCMake/PrecompileHeaders/PchReuseFromCycle-stderr.txt b/Tests/RunCMake/PrecompileHeaders-Reuse/PchReuseFromCycle-stderr.txt
similarity index 100%
rename from Tests/RunCMake/PrecompileHeaders/PchReuseFromCycle-stderr.txt
rename to Tests/RunCMake/PrecompileHeaders-Reuse/PchReuseFromCycle-stderr.txt
diff --git a/Tests/RunCMake/PrecompileHeaders/PchReuseFromCycle.cmake b/Tests/RunCMake/PrecompileHeaders-Reuse/PchReuseFromCycle.cmake
similarity index 100%
rename from Tests/RunCMake/PrecompileHeaders/PchReuseFromCycle.cmake
rename to Tests/RunCMake/PrecompileHeaders-Reuse/PchReuseFromCycle.cmake
diff --git a/Tests/RunCMake/PrecompileHeaders/PchReuseFromIgnoreOwnProps-build-check.cmake b/Tests/RunCMake/PrecompileHeaders-Reuse/PchReuseFromIgnoreOwnProps-build-check.cmake
similarity index 100%
rename from Tests/RunCMake/PrecompileHeaders/PchReuseFromIgnoreOwnProps-build-check.cmake
rename to Tests/RunCMake/PrecompileHeaders-Reuse/PchReuseFromIgnoreOwnProps-build-check.cmake
diff --git a/Tests/RunCMake/PrecompileHeaders/PchReuseFromIgnoreOwnProps-build-stderr.txt b/Tests/RunCMake/PrecompileHeaders-Reuse/PchReuseFromIgnoreOwnProps-build-stderr.txt
similarity index 100%
rename from Tests/RunCMake/PrecompileHeaders/PchReuseFromIgnoreOwnProps-build-stderr.txt
rename to Tests/RunCMake/PrecompileHeaders-Reuse/PchReuseFromIgnoreOwnProps-build-stderr.txt
diff --git a/Tests/RunCMake/PrecompileHeaders/PchReuseFromIgnoreOwnProps.cmake b/Tests/RunCMake/PrecompileHeaders-Reuse/PchReuseFromIgnoreOwnProps.cmake
similarity index 100%
rename from Tests/RunCMake/PrecompileHeaders/PchReuseFromIgnoreOwnProps.cmake
rename to Tests/RunCMake/PrecompileHeaders-Reuse/PchReuseFromIgnoreOwnProps.cmake
diff --git a/Tests/RunCMake/PrecompileHeaders/PchReuseFromObjLib.cmake b/Tests/RunCMake/PrecompileHeaders-Reuse/PchReuseFromObjLib.cmake
similarity index 100%
rename from Tests/RunCMake/PrecompileHeaders/PchReuseFromObjLib.cmake
rename to Tests/RunCMake/PrecompileHeaders-Reuse/PchReuseFromObjLib.cmake
diff --git a/Tests/RunCMake/PrecompileHeaders/PchReuseFromPrefixed-build-stderr.txt b/Tests/RunCMake/PrecompileHeaders-Reuse/PchReuseFromPrefixed-build-stderr.txt
similarity index 100%
rename from Tests/RunCMake/PrecompileHeaders/PchReuseFromPrefixed-build-stderr.txt
rename to Tests/RunCMake/PrecompileHeaders-Reuse/PchReuseFromPrefixed-build-stderr.txt
diff --git a/Tests/RunCMake/PrecompileHeaders/PchReuseFromPrefixed.cmake b/Tests/RunCMake/PrecompileHeaders-Reuse/PchReuseFromPrefixed.cmake
similarity index 100%
rename from Tests/RunCMake/PrecompileHeaders/PchReuseFromPrefixed.cmake
rename to Tests/RunCMake/PrecompileHeaders-Reuse/PchReuseFromPrefixed.cmake
diff --git a/Tests/RunCMake/PrecompileHeaders/PchReuseFromSubdir-build-stderr.txt b/Tests/RunCMake/PrecompileHeaders-Reuse/PchReuseFromSubdir-build-stderr.txt
similarity index 100%
rename from Tests/RunCMake/PrecompileHeaders/PchReuseFromSubdir-build-stderr.txt
rename to Tests/RunCMake/PrecompileHeaders-Reuse/PchReuseFromSubdir-build-stderr.txt
diff --git a/Tests/RunCMake/PrecompileHeaders/PchReuseFromSubdir.cmake b/Tests/RunCMake/PrecompileHeaders-Reuse/PchReuseFromSubdir.cmake
similarity index 100%
rename from Tests/RunCMake/PrecompileHeaders/PchReuseFromSubdir.cmake
rename to Tests/RunCMake/PrecompileHeaders-Reuse/PchReuseFromSubdir.cmake
diff --git a/Tests/RunCMake/PrecompileHeaders/PchReuseFromUseUpdatedProps-build-check.cmake b/Tests/RunCMake/PrecompileHeaders-Reuse/PchReuseFromUseUpdatedProps-build-check.cmake
similarity index 100%
rename from Tests/RunCMake/PrecompileHeaders/PchReuseFromUseUpdatedProps-build-check.cmake
rename to Tests/RunCMake/PrecompileHeaders-Reuse/PchReuseFromUseUpdatedProps-build-check.cmake
diff --git a/Tests/RunCMake/PrecompileHeaders/PchReuseFromUseUpdatedProps-build-stderr.txt b/Tests/RunCMake/PrecompileHeaders-Reuse/PchReuseFromUseUpdatedProps-build-stderr.txt
similarity index 100%
rename from Tests/RunCMake/PrecompileHeaders/PchReuseFromUseUpdatedProps-build-stderr.txt
rename to Tests/RunCMake/PrecompileHeaders-Reuse/PchReuseFromUseUpdatedProps-build-stderr.txt
diff --git a/Tests/RunCMake/PrecompileHeaders/PchReuseFromUseUpdatedProps.cmake b/Tests/RunCMake/PrecompileHeaders-Reuse/PchReuseFromUseUpdatedProps.cmake
similarity index 100%
rename from Tests/RunCMake/PrecompileHeaders/PchReuseFromUseUpdatedProps.cmake
rename to Tests/RunCMake/PrecompileHeaders-Reuse/PchReuseFromUseUpdatedProps.cmake
diff --git a/Tests/RunCMake/PrecompileHeaders/PchReuseWithoutPch-stderr.txt b/Tests/RunCMake/PrecompileHeaders-Reuse/PchReuseWithoutPch-stderr.txt
similarity index 100%
rename from Tests/RunCMake/PrecompileHeaders/PchReuseWithoutPch-stderr.txt
rename to Tests/RunCMake/PrecompileHeaders-Reuse/PchReuseWithoutPch-stderr.txt
diff --git a/Tests/RunCMake/PrecompileHeaders/PchReuseWithoutPch.cmake b/Tests/RunCMake/PrecompileHeaders-Reuse/PchReuseWithoutPch.cmake
similarity index 100%
rename from Tests/RunCMake/PrecompileHeaders/PchReuseWithoutPch.cmake
rename to Tests/RunCMake/PrecompileHeaders-Reuse/PchReuseWithoutPch.cmake
diff --git a/Tests/RunCMake/PrecompileHeaders-Reuse/RunCMakeTest.cmake b/Tests/RunCMake/PrecompileHeaders-Reuse/RunCMakeTest.cmake
new file mode 100644
index 0000000..2c38783
--- /dev/null
+++ b/Tests/RunCMake/PrecompileHeaders-Reuse/RunCMakeTest.cmake
@@ -0,0 +1,32 @@
+include(RunCMake)
+
+function(run_test name)
+  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${name}-build)
+  run_cmake(${name})
+  set(RunCMake_TEST_NO_CLEAN 1)
+  run_cmake_command(${name}-build ${CMAKE_COMMAND} --build . --config Debug)
+  run_cmake_command(${name}-test ${CMAKE_CTEST_COMMAND} -C Debug)
+endfunction()
+
+function(run_build_verbose name)
+  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${name}-build)
+  run_cmake(${name})
+  set(RunCMake_TEST_NO_CLEAN 1)
+  run_cmake_command(${name}-build ${CMAKE_COMMAND} --build . --verbose --config Debug)
+endfunction()
+
+run_test(PchReuseFrom-CMP0141-OLD)
+run_test(PchReuseFrom-CMP0141-NEW)
+if(CMAKE_C_COMPILER_ID STREQUAL "MSVC")
+  run_test(PchReuseFrom-CMP0141-NEW-empty)
+endif()
+run_test(PchReuseFromPrefixed)
+run_test(PchReuseFromSubdir)
+run_build_verbose(PchReuseFromIgnoreOwnProps)
+run_build_verbose(PchReuseFromUseUpdatedProps)
+run_build_verbose(PchReuseConsistency)
+run_cmake(PchReuseFromCycle)
+run_cmake(PchReuseWithoutPch)
+run_build_verbose(PchReuseAppend)
+run_build_verbose(PchReuseDeclarationOrder)
+run_test(PchReuseFromObjLib)
diff --git a/Tests/RunCMake/PrecompileHeaders-Reuse/empty.c b/Tests/RunCMake/PrecompileHeaders-Reuse/empty.c
new file mode 100644
index 0000000..2a51ebc
--- /dev/null
+++ b/Tests/RunCMake/PrecompileHeaders-Reuse/empty.c
@@ -0,0 +1,3 @@
+void nothing(void)
+{
+}
diff --git a/Tests/RunCMake/PrecompileHeaders-Reuse/foo.c b/Tests/RunCMake/PrecompileHeaders-Reuse/foo.c
new file mode 100644
index 0000000..a4710fd
--- /dev/null
+++ b/Tests/RunCMake/PrecompileHeaders-Reuse/foo.c
@@ -0,0 +1,13 @@
+#include "foo.h"
+
+#include "foo2.h"
+
+int foo(void)
+{
+  return 0;
+}
+
+int foo2(void)
+{
+  return 0;
+}
diff --git a/Tests/RunCMake/PrecompileHeaders-Reuse/foobar.c b/Tests/RunCMake/PrecompileHeaders-Reuse/foobar.c
new file mode 100644
index 0000000..71ebe37
--- /dev/null
+++ b/Tests/RunCMake/PrecompileHeaders-Reuse/foobar.c
@@ -0,0 +1,14 @@
+#include "bar.h"
+#include "foo.h"
+#include "foo2.h"
+
+int main(void)
+{
+  int zeroSize = 0;
+
+#ifdef HAVE_PCH_SUPPORT
+  zeroSize = (int)strlen("");
+#endif
+
+  return foo() + foo2() + bar() + zeroSize;
+}
diff --git a/Tests/RunCMake/PrecompileHeaders-Reuse/include/bar.h b/Tests/RunCMake/PrecompileHeaders-Reuse/include/bar.h
new file mode 100644
index 0000000..89a156c
--- /dev/null
+++ b/Tests/RunCMake/PrecompileHeaders-Reuse/include/bar.h
@@ -0,0 +1,9 @@
+#ifndef bar_h
+#define bar_h
+
+static int bar(void)
+{
+  return 0;
+}
+
+#endif
diff --git a/Tests/RunCMake/PrecompileHeaders-Reuse/include/foo.h b/Tests/RunCMake/PrecompileHeaders-Reuse/include/foo.h
new file mode 100644
index 0000000..fc0ae14
--- /dev/null
+++ b/Tests/RunCMake/PrecompileHeaders-Reuse/include/foo.h
@@ -0,0 +1,6 @@
+#ifndef foo_h
+#define foo_h
+
+int foo(void);
+
+#endif
diff --git a/Tests/RunCMake/PrecompileHeaders-Reuse/include/foo2.h b/Tests/RunCMake/PrecompileHeaders-Reuse/include/foo2.h
new file mode 100644
index 0000000..4bf9c81
--- /dev/null
+++ b/Tests/RunCMake/PrecompileHeaders-Reuse/include/foo2.h
@@ -0,0 +1,6 @@
+#ifndef foo2_h
+#define foo2_h
+
+int foo2(void);
+
+#endif
diff --git a/Tests/RunCMake/PrecompileHeaders/subdir/CMakeLists.txt b/Tests/RunCMake/PrecompileHeaders-Reuse/subdir/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/PrecompileHeaders/subdir/CMakeLists.txt
rename to Tests/RunCMake/PrecompileHeaders-Reuse/subdir/CMakeLists.txt
diff --git a/Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake b/Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake
index 35b2fe3..58c45f5 100644
--- a/Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake
+++ b/Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake
@@ -8,13 +8,6 @@
   run_cmake_command(${name}-test ${CMAKE_CTEST_COMMAND} -C Debug)
 endfunction()
 
-function(run_build_verbose name)
-  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${name}-build)
-  run_cmake(${name})
-  set(RunCMake_TEST_NO_CLEAN 1)
-  run_cmake_command(${name}-build ${CMAKE_COMMAND} --build . --verbose --config Debug)
-endfunction()
-
 run_cmake(DisabledPch)
 run_cmake(PchDebugGenex)
 if (RunCMake_GENERATOR MATCHES "(Ninja|Makefiles|Visual Studio)")
@@ -28,21 +21,7 @@
 run_cmake(PchPrologueEpilogue)
 run_test(SkipPrecompileHeaders)
 run_test(CXXnotC)
-run_test(PchReuseFrom-CMP0141-OLD)
-run_test(PchReuseFrom-CMP0141-NEW)
-if(CMAKE_C_COMPILER_ID STREQUAL "MSVC")
-  run_test(PchReuseFrom-CMP0141-NEW-empty)
-endif()
-run_test(PchReuseFromPrefixed)
-run_test(PchReuseFromSubdir)
-run_build_verbose(PchReuseFromIgnoreOwnProps)
-run_build_verbose(PchReuseFromUseUpdatedProps)
-run_build_verbose(PchReuseConsistency)
-run_cmake(PchReuseFromCycle)
-run_cmake(PchReuseWithoutPch)
-run_build_verbose(PchReuseAppend)
 run_cmake(PchMultilanguage)
-run_build_verbose(PchReuseDeclarationOrder)
 if(RunCMake_GENERATOR MATCHES "Make|Ninja")
   run_cmake(PchWarnInvalid)
 
@@ -52,7 +31,6 @@
     run_cmake(PchInstantiateTemplates)
   endif()
 endif()
-run_test(PchReuseFromObjLib)
 run_test(PchIncludedAllLanguages)
 run_test(PchIncludedOneLanguage)
 run_test(PchLibObjLibExe)
diff --git a/Tests/RunCMake/file-CREATE_LINK/CMP0205-HardLink-NEW.cmake b/Tests/RunCMake/file-CREATE_LINK/CMP0205-HardLink-NEW.cmake
new file mode 100644
index 0000000..4cc82ae
--- /dev/null
+++ b/Tests/RunCMake/file-CREATE_LINK/CMP0205-HardLink-NEW.cmake
@@ -0,0 +1,3 @@
+set(link_name HardLink)
+set(maybe_SYMBOLIC)
+include("${CMAKE_CURRENT_LIST_DIR}/CMP0205-common-NEW.cmake")
diff --git a/Tests/RunCMake/file-CREATE_LINK/CMP0205-HardLink-OLD.cmake b/Tests/RunCMake/file-CREATE_LINK/CMP0205-HardLink-OLD.cmake
new file mode 100644
index 0000000..e68cb7f
--- /dev/null
+++ b/Tests/RunCMake/file-CREATE_LINK/CMP0205-HardLink-OLD.cmake
@@ -0,0 +1,3 @@
+set(link_name HardLink)
+set(maybe_SYMBOLIC)
+include("${CMAKE_CURRENT_LIST_DIR}/CMP0205-common-OLD.cmake")
diff --git a/Tests/RunCMake/file-CREATE_LINK/CMP0205-HardLink-WARN-stderr.txt b/Tests/RunCMake/file-CREATE_LINK/CMP0205-HardLink-WARN-stderr.txt
new file mode 100644
index 0000000..52873f3
--- /dev/null
+++ b/Tests/RunCMake/file-CREATE_LINK/CMP0205-HardLink-WARN-stderr.txt
@@ -0,0 +1,38 @@
+^CMake Warning \(dev\) at [^
+]*/CMP0205-common\.cmake:[0-9]+ \(file\):
+  Path
+
+    [^
+]*[\\|/]file-CREATE_LINK[\\|/]CMP0205
+
+  is directory.  Hardlinks creation is not supported for directories.
+
+  Policy CMP0205 is not set: file\(CREATE_LINK\) with COPY_ON_ERROR copies
+  directory content\.  Run "cmake --help-policy CMP0205" for policy details\.
+  Use the cmake_policy command to set the policy and suppress this warning\.
+Call Stack \(most recent call first\):
+  [^
+]*/CMP0205-common-WARN\.cmake:[0-9]+ \(include\)
+  [^
+]*/CMP0205-HardLink-WARN\.cmake:[0-9]+ \(include\)
+This warning is for project developers\.  Use -Wno-dev to suppress it\.
+
+CMake Warning \(dev\) at [^
+]*/CMP0205-common\.cmake:[0-9]+ \(file\):
+  Path
+
+    [^
+]*[\\|/]file-CREATE_LINK[\\|/]CMP0205
+
+  is directory.  It will be copied recursively when NEW policy behavior
+  applies for CMP0205\.
+
+  Policy CMP0205 is not set: file\(CREATE_LINK\) with COPY_ON_ERROR copies
+  directory content\.  Run "cmake --help-policy CMP0205" for policy details\.
+  Use the cmake_policy command to set the policy and suppress this warning\.
+Call Stack \(most recent call first\):
+  [^
+]*/CMP0205-common-WARN\.cmake:[0-9]+ \(include\)
+  [^
+]*/CMP0205-HardLink-WARN\.cmake:[0-9]+ \(include\)
+This warning is for project developers\.  Use -Wno-dev to suppress it\.$
diff --git a/Tests/RunCMake/file-CREATE_LINK/CMP0205-HardLink-WARN.cmake b/Tests/RunCMake/file-CREATE_LINK/CMP0205-HardLink-WARN.cmake
new file mode 100644
index 0000000..c8ebc71
--- /dev/null
+++ b/Tests/RunCMake/file-CREATE_LINK/CMP0205-HardLink-WARN.cmake
@@ -0,0 +1,3 @@
+set(link_name HardLink)
+set(maybe_SYMBOLIC)
+include("${CMAKE_CURRENT_LIST_DIR}/CMP0205-common-WARN.cmake")
diff --git a/Tests/RunCMake/file-CREATE_LINK/CMP0205-SymLink-NEW.cmake b/Tests/RunCMake/file-CREATE_LINK/CMP0205-SymLink-NEW.cmake
new file mode 100644
index 0000000..4831ab2
--- /dev/null
+++ b/Tests/RunCMake/file-CREATE_LINK/CMP0205-SymLink-NEW.cmake
@@ -0,0 +1,3 @@
+set(link_name SymLink)
+set(maybe_SYMBOLIC SYMBOLIC)
+include("${CMAKE_CURRENT_LIST_DIR}/CMP0205-common-NEW.cmake")
diff --git a/Tests/RunCMake/file-CREATE_LINK/CMP0205-SymLink-OLD.cmake b/Tests/RunCMake/file-CREATE_LINK/CMP0205-SymLink-OLD.cmake
new file mode 100644
index 0000000..7fb1f6a
--- /dev/null
+++ b/Tests/RunCMake/file-CREATE_LINK/CMP0205-SymLink-OLD.cmake
@@ -0,0 +1,3 @@
+set(link_name SymLink)
+set(maybe_SYMBOLIC SYMBOLIC)
+include("${CMAKE_CURRENT_LIST_DIR}/CMP0205-common-OLD.cmake")
diff --git a/Tests/RunCMake/file-CREATE_LINK/CMP0205-SymLink-WARN-stderr.txt b/Tests/RunCMake/file-CREATE_LINK/CMP0205-SymLink-WARN-stderr.txt
new file mode 100644
index 0000000..0399f1f
--- /dev/null
+++ b/Tests/RunCMake/file-CREATE_LINK/CMP0205-SymLink-WARN-stderr.txt
@@ -0,0 +1,19 @@
+^CMake Warning \(dev\) at [^
+]*/CMP0205-common\.cmake:[0-9]+ \(file\):
+  Path
+
+    [^
+]*[\\|/]file-CREATE_LINK[\\|/]CMP0205
+
+  is directory.  It will be copied recursively when NEW policy behavior
+  applies for CMP0205\.
+
+  Policy CMP0205 is not set: file\(CREATE_LINK\) with COPY_ON_ERROR copies
+  directory content\.  Run "cmake --help-policy CMP0205" for policy details\.
+  Use the cmake_policy command to set the policy and suppress this warning\.
+Call Stack \(most recent call first\):
+  [^
+]*/CMP0205-common-WARN\.cmake:[0-9]+ \(include\)
+  [^
+]*/CMP0205-SymLink-WARN\.cmake:[0-9]+ \(include\)
+This warning is for project developers\.  Use -Wno-dev to suppress it\.$
diff --git a/Tests/RunCMake/file-CREATE_LINK/CMP0205-SymLink-WARN.cmake b/Tests/RunCMake/file-CREATE_LINK/CMP0205-SymLink-WARN.cmake
new file mode 100644
index 0000000..b14ec15
--- /dev/null
+++ b/Tests/RunCMake/file-CREATE_LINK/CMP0205-SymLink-WARN.cmake
@@ -0,0 +1,3 @@
+set(link_name SymLink)
+set(maybe_SYMBOLIC SYMBOLIC)
+include("${CMAKE_CURRENT_LIST_DIR}/CMP0205-common-WARN.cmake")
diff --git a/Tests/RunCMake/file-CREATE_LINK/CMP0205-common-NEW.cmake b/Tests/RunCMake/file-CREATE_LINK/CMP0205-common-NEW.cmake
new file mode 100644
index 0000000..15e6a36
--- /dev/null
+++ b/Tests/RunCMake/file-CREATE_LINK/CMP0205-common-NEW.cmake
@@ -0,0 +1,12 @@
+cmake_policy(SET CMP0205 NEW)
+include("${CMAKE_CURRENT_LIST_DIR}/CMP0205-common.cmake")
+
+if(NOT allFilesDst)
+  message(SEND_ERROR "Destination directory is empty: '${allFilesDst}'")
+endif()
+
+if(NOT "${allFilesSrc}" STREQUAL "${allFilesDst}")
+  message(SEND_ERROR "Source and destination directories are not equal")
+  message(SEND_ERROR "Source files: '${allFilesSrc}'")
+  message(SEND_ERROR "Destination files: '${allFilesDst}'")
+endif()
diff --git a/Tests/RunCMake/file-CREATE_LINK/CMP0205-common-OLD.cmake b/Tests/RunCMake/file-CREATE_LINK/CMP0205-common-OLD.cmake
new file mode 100644
index 0000000..76add41
--- /dev/null
+++ b/Tests/RunCMake/file-CREATE_LINK/CMP0205-common-OLD.cmake
@@ -0,0 +1,6 @@
+cmake_policy(SET CMP0205 OLD)
+include("${CMAKE_CURRENT_LIST_DIR}/CMP0205-common.cmake")
+
+if(allFilesDst)
+  message(SEND_ERROR "Directory is not empty: '${allFilesDst}'")
+endif()
diff --git a/Tests/RunCMake/file-CREATE_LINK/CMP0205-common-WARN.cmake b/Tests/RunCMake/file-CREATE_LINK/CMP0205-common-WARN.cmake
new file mode 100644
index 0000000..ee94046
--- /dev/null
+++ b/Tests/RunCMake/file-CREATE_LINK/CMP0205-common-WARN.cmake
@@ -0,0 +1,6 @@
+# CMP0205 is unset
+include("${CMAKE_CURRENT_LIST_DIR}/CMP0205-common.cmake")
+
+if(allFilesDst)
+  message(SEND_ERROR "Directory is not empty: '${allFilesDst}'")
+endif()
diff --git a/Tests/RunCMake/file-CREATE_LINK/CMP0205-common.cmake b/Tests/RunCMake/file-CREATE_LINK/CMP0205-common.cmake
new file mode 100644
index 0000000..deb313f
--- /dev/null
+++ b/Tests/RunCMake/file-CREATE_LINK/CMP0205-common.cmake
@@ -0,0 +1,14 @@
+# Use COPY_ON_ERROR to handle the case where the source and destination
+# directory are on different devices and empty.
+file(CREATE_LINK
+  ${CMAKE_CURRENT_LIST_DIR}/CMP0205 ${CMAKE_CURRENT_BINARY_DIR}/CMP0205-${link_name}
+  ${maybe_SYMBOLIC}
+  RESULT result
+  COPY_ON_ERROR
+  )
+if(NOT result STREQUAL "0")
+  message(SEND_ERROR "COPY_ON_ERROR failed: '${result}'")
+endif()
+
+file(GLOB_RECURSE allFilesSrc LIST_DIRECTORIES true RELATIVE "${CMAKE_CURRENT_LIST_DIR}/CMP0205" "${CMAKE_CURRENT_LIST_DIR}/CMP0205/*")
+file(GLOB_RECURSE allFilesDst LIST_DIRECTORIES true RELATIVE "${CMAKE_CURRENT_BINARY_DIR}/CMP0205-${link_name}" "${CMAKE_CURRENT_BINARY_DIR}/CMP0205-${link_name}/*")
diff --git a/Tests/RunCMake/CXXModules/examples/export-build-database/dep_interface_include/anchor b/Tests/RunCMake/file-CREATE_LINK/CMP0205/test.txt
similarity index 100%
copy from Tests/RunCMake/CXXModules/examples/export-build-database/dep_interface_include/anchor
copy to Tests/RunCMake/file-CREATE_LINK/CMP0205/test.txt
diff --git a/Tests/RunCMake/file-CREATE_LINK/CMakeLists.txt b/Tests/RunCMake/file-CREATE_LINK/CMakeLists.txt
new file mode 100644
index 0000000..39da703
--- /dev/null
+++ b/Tests/RunCMake/file-CREATE_LINK/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 4.1)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/file/CREATE_LINK-COPY_ON_ERROR.cmake b/Tests/RunCMake/file-CREATE_LINK/CREATE_LINK-COPY_ON_ERROR-file.cmake
similarity index 77%
rename from Tests/RunCMake/file/CREATE_LINK-COPY_ON_ERROR.cmake
rename to Tests/RunCMake/file-CREATE_LINK/CREATE_LINK-COPY_ON_ERROR-file.cmake
index 777ef4e..e980ac0 100644
--- a/Tests/RunCMake/file/CREATE_LINK-COPY_ON_ERROR.cmake
+++ b/Tests/RunCMake/file-CREATE_LINK/CREATE_LINK-COPY_ON_ERROR-file.cmake
@@ -1,6 +1,7 @@
 # Use COPY_ON_ERROR to handle the case where the source and destination
-# directory are on different devices. Cross-device links are not permitted
+# file are on different devices. Cross-device links are not permitted
 # and the following command falls back to copying the file if link fails.
+# Check only command result.
 file(CREATE_LINK
   ${CMAKE_CURRENT_LIST_FILE} TestCreateLink.cmake
   RESULT result
diff --git a/Tests/RunCMake/file/CREATE_LINK-SYMBOLIC-noexist.cmake b/Tests/RunCMake/file-CREATE_LINK/CREATE_LINK-SYMBOLIC-noexist.cmake
similarity index 100%
rename from Tests/RunCMake/file/CREATE_LINK-SYMBOLIC-noexist.cmake
rename to Tests/RunCMake/file-CREATE_LINK/CREATE_LINK-SYMBOLIC-noexist.cmake
diff --git a/Tests/RunCMake/file/CREATE_LINK-SYMBOLIC.cmake b/Tests/RunCMake/file-CREATE_LINK/CREATE_LINK-SYMBOLIC.cmake
similarity index 100%
rename from Tests/RunCMake/file/CREATE_LINK-SYMBOLIC.cmake
rename to Tests/RunCMake/file-CREATE_LINK/CREATE_LINK-SYMBOLIC.cmake
diff --git a/Tests/RunCMake/file/CREATE_LINK-noarg-result.txt b/Tests/RunCMake/file-CREATE_LINK/CREATE_LINK-noarg-result.txt
similarity index 100%
rename from Tests/RunCMake/file/CREATE_LINK-noarg-result.txt
rename to Tests/RunCMake/file-CREATE_LINK/CREATE_LINK-noarg-result.txt
diff --git a/Tests/RunCMake/file/CREATE_LINK-noarg-stderr.txt b/Tests/RunCMake/file-CREATE_LINK/CREATE_LINK-noarg-stderr.txt
similarity index 100%
rename from Tests/RunCMake/file/CREATE_LINK-noarg-stderr.txt
rename to Tests/RunCMake/file-CREATE_LINK/CREATE_LINK-noarg-stderr.txt
diff --git a/Tests/RunCMake/file/CREATE_LINK-noarg.cmake b/Tests/RunCMake/file-CREATE_LINK/CREATE_LINK-noarg.cmake
similarity index 100%
rename from Tests/RunCMake/file/CREATE_LINK-noarg.cmake
rename to Tests/RunCMake/file-CREATE_LINK/CREATE_LINK-noarg.cmake
diff --git a/Tests/RunCMake/file/CREATE_LINK-noexist-stderr.txt b/Tests/RunCMake/file-CREATE_LINK/CREATE_LINK-noexist-stderr.txt
similarity index 100%
rename from Tests/RunCMake/file/CREATE_LINK-noexist-stderr.txt
rename to Tests/RunCMake/file-CREATE_LINK/CREATE_LINK-noexist-stderr.txt
diff --git a/Tests/RunCMake/file/CREATE_LINK-noexist.cmake b/Tests/RunCMake/file-CREATE_LINK/CREATE_LINK-noexist.cmake
similarity index 100%
rename from Tests/RunCMake/file/CREATE_LINK-noexist.cmake
rename to Tests/RunCMake/file-CREATE_LINK/CREATE_LINK-noexist.cmake
diff --git a/Tests/RunCMake/file/CREATE_LINK.cmake b/Tests/RunCMake/file-CREATE_LINK/CREATE_LINK.cmake
similarity index 100%
rename from Tests/RunCMake/file/CREATE_LINK.cmake
rename to Tests/RunCMake/file-CREATE_LINK/CREATE_LINK.cmake
diff --git a/Tests/RunCMake/file-CREATE_LINK/RunCMakeTest.cmake b/Tests/RunCMake/file-CREATE_LINK/RunCMakeTest.cmake
new file mode 100644
index 0000000..ed83312
--- /dev/null
+++ b/Tests/RunCMake/file-CREATE_LINK/RunCMakeTest.cmake
@@ -0,0 +1,44 @@
+include(RunCMake)
+
+run_cmake(CREATE_LINK)
+run_cmake(CREATE_LINK-COPY_ON_ERROR-file)
+run_cmake(CREATE_LINK-noarg)
+run_cmake(CREATE_LINK-noexist)
+
+if(NOT WIN32
+    AND NOT MSYS # FIXME: This works on CYGWIN but not on MSYS
+    )
+  run_cmake(CREATE_LINK-SYMBOLIC)
+  run_cmake(CREATE_LINK-SYMBOLIC-noexist)
+endif()
+
+file(MAKE_DIRECTORY ${RunCMake_BINARY_DIR}/CMP0205-Inspect/Dest)
+
+file(REMOVE_RECURSE ${RunCMake_BINARY_DIR}/CMP0205-Inspect-SymLink)
+file(CREATE_LINK
+  ${RunCMake_BINARY_DIR}/CMP0205-Inspect/Dest ${RunCMake_BINARY_DIR}/CMP0205-Inspect-SymLink
+  SYMBOLIC
+  RESULT SymLink_RESULT
+)
+if(SymLink_RESULT STREQUAL "0")
+  message(STATUS "CMP0205-SymLink-* skipped: directory symbolic link creation works")
+  file(REMOVE ${RunCMake_BINARY_DIR}/CMP0205-Inspect-SymLink)
+else()
+  run_cmake_script(CMP0205-SymLink-WARN)
+  run_cmake_script(CMP0205-SymLink-OLD)
+  run_cmake_script(CMP0205-SymLink-NEW)
+endif()
+
+file(REMOVE_RECURSE ${RunCMake_BINARY_DIR}/CMP0205-Inspect-HardLink)
+file(CREATE_LINK
+  ${RunCMake_BINARY_DIR}/CMP0205-Inspect/Dest ${RunCMake_BINARY_DIR}/CMP0205-Inspect-HardLink
+  RESULT HardLink_RESULT
+)
+if(HardLink_RESULT STREQUAL "0")
+  message(STATUS "CMP0205-HardLink-* skipped: directory hard link creation works")
+  file(REMOVE_RECURSE ${RunCMake_BINARY_DIR}/CMP0205-Inspect-HardLink)
+else()
+  run_cmake_script(CMP0205-HardLink-WARN)
+  run_cmake_script(CMP0205-HardLink-OLD)
+  run_cmake_script(CMP0205-HardLink-NEW)
+endif()
diff --git a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/CMP0207-NEW.cmake b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/CMP0207-NEW.cmake
new file mode 100644
index 0000000..53bb192
--- /dev/null
+++ b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/CMP0207-NEW.cmake
@@ -0,0 +1,13 @@
+cmake_policy(SET CMP0207 NEW)
+
+include("${CMAKE_CURRENT_LIST_DIR}/CMP0207-common.cmake")
+
+install(CODE [[
+  if(results_old)
+    message(SEND_ERROR "Old dependencies are not empty: `${results_old}`")
+  endif()
+
+  if(NOT results_new)
+    message(SEND_ERROR "New dependencies are empty: `${results_new}`")
+  endif()
+  ]])
diff --git a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/CMP0207-OLD.cmake b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/CMP0207-OLD.cmake
new file mode 100644
index 0000000..c7e497d
--- /dev/null
+++ b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/CMP0207-OLD.cmake
@@ -0,0 +1,13 @@
+cmake_policy(SET CMP0207 OLD)
+
+include("${CMAKE_CURRENT_LIST_DIR}/CMP0207-common.cmake")
+
+install(CODE [[
+  if(NOT results_old)
+    message(SEND_ERROR "Old dependencies are empty: `${results_old}`")
+  endif()
+
+  if(results_new)
+    message(SEND_ERROR "New dependencies are not empty: `${results_new}`")
+  endif()
+  ]])
diff --git a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/CMP0207-WARN-all-stderr.txt b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/CMP0207-WARN-all-stderr.txt
new file mode 100644
index 0000000..1d8f189
--- /dev/null
+++ b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/CMP0207-WARN-all-stderr.txt
@@ -0,0 +1,44 @@
+^CMake Warning \(dev\) at cmake_install\.cmake:[0-9]+ \(file\):
+  Policy CMP0207 is not set: file\(GET_RUNTIME_DEPENDENCIES\) normalizes paths
+  before matching\.  Run "cmake --help-policy CMP0207" for policy details\.
+  Use the cmake_policy command to set the policy and suppress this warning\.
+
+  Path
+
+    "[^"]*test\.dll"
+
+  would be converted to
+
+    "[^"]*test\.dll"
+
+This warning is for project developers\.  Use -Wno-dev to suppress it\.
++
+CMake Warning \(dev\) at cmake_install\.cmake:[0-9]+ \(file\):
+  Policy CMP0207 is not set: file\(GET_RUNTIME_DEPENDENCIES\) normalizes paths
+  before matching\.  Run "cmake --help-policy CMP0207" for policy details\.
+  Use the cmake_policy command to set the policy and suppress this warning\.
+
+  Path
+
+    "[^"]*test\.dll"
+
+  would be converted to
+
+    "[^"]*test\.dll"
+
+This warning is for project developers\.  Use -Wno-dev to suppress it\.
++
+CMake Warning \(dev\) at cmake_install\.cmake:[0-9]+ \(file\):
+  Policy CMP0207 is not set: file\(GET_RUNTIME_DEPENDENCIES\) normalizes paths
+  before matching\.  Run "cmake --help-policy CMP0207" for policy details\.
+  Use the cmake_policy command to set the policy and suppress this warning\.
+
+  Path
+
+    "[^"]*test\.dll"
+
+  would be converted to
+
+    "[^"]*test\.dll"
+
+This warning is for project developers\.  Use -Wno-dev to suppress it\.$
diff --git a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/CMP0207-WARN.cmake b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/CMP0207-WARN.cmake
new file mode 100644
index 0000000..a5a5cc0
--- /dev/null
+++ b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/CMP0207-WARN.cmake
@@ -0,0 +1,12 @@
+# CMP0207 is unset
+include("${CMAKE_CURRENT_LIST_DIR}/CMP0207-common.cmake")
+
+install(CODE [[
+  if(NOT results_old)
+    message(SEND_ERROR "Old dependencies are empty: `${results_old}`")
+  endif()
+
+  if(results_new)
+    message(SEND_ERROR "New dependencies are not empty: `${results_new}`")
+  endif()
+  ]])
diff --git a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/CMP0207-common.cmake b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/CMP0207-common.cmake
new file mode 100644
index 0000000..4d916a5
--- /dev/null
+++ b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/CMP0207-common.cmake
@@ -0,0 +1,93 @@
+enable_language(C)
+
+file(WRITE "${CMAKE_BINARY_DIR}/test.c" "__declspec(dllexport) void test(void) {}\n")
+file(WRITE "${CMAKE_BINARY_DIR}/main.c" [[__declspec(dllimport) extern void test(void);
+
+int main(void)
+{
+  test();
+  return 0;
+}
+]])
+
+add_subdirectory(CMP0207-subdir)
+
+add_executable(exe "${CMAKE_BINARY_DIR}/main.c")
+target_link_libraries(exe PRIVATE test)
+
+install(TARGETS test DESTINATION bin/lib1)
+
+install(
+  TARGETS exe
+  DESTINATION results_old
+  RUNTIME_DEPENDENCIES
+    DIRECTORIES "${CMAKE_BINARY_DIR}/root-all\\bin\\lib1"
+    PRE_INCLUDE_REGEXES "^(lib)?test\\.dll$"
+    PRE_EXCLUDE_REGEXES ".*"
+    POST_INCLUDE_REGEXES "\\\\lib1/(lib)?test\\.dll$"
+    POST_EXCLUDE_REGEXES ".*"
+)
+
+install(
+  TARGETS exe
+  DESTINATION results_new
+  RUNTIME_DEPENDENCIES
+    DIRECTORIES "${CMAKE_BINARY_DIR}/root-all\\bin\\lib1"
+    PRE_INCLUDE_REGEXES "^(lib)?test\\.dll$"
+    PRE_EXCLUDE_REGEXES ".*"
+    POST_INCLUDE_REGEXES "/lib1/(lib)?test\\.dll$"
+    POST_EXCLUDE_REGEXES ".*"
+)
+
+install(
+  TARGETS exe
+  DESTINATION results_any
+  RUNTIME_DEPENDENCIES
+    DIRECTORIES "${CMAKE_BINARY_DIR}/root-all\\bin\\lib1"
+    PRE_INCLUDE_REGEXES "^(lib)?test\\.dll$"
+    PRE_EXCLUDE_REGEXES ".*"
+    POST_INCLUDE_REGEXES "(\\\\|/)lib1/(lib)?test\\.dll$"
+    POST_EXCLUDE_REGEXES ".*"
+)
+
+install(
+  TARGETS exe
+  DESTINATION results_any_forward
+  RUNTIME_DEPENDENCIES
+    DIRECTORIES "${CMAKE_BINARY_DIR}/root-all/bin/lib1"
+    PRE_INCLUDE_REGEXES "^(lib)?test\\.dll$"
+    PRE_EXCLUDE_REGEXES ".*"
+    POST_INCLUDE_REGEXES "(\\\\|/)lib1/(lib)?test\\.dll$"
+    POST_EXCLUDE_REGEXES ".*"
+)
+
+install(
+  CODE [[
+    function(check_installed_lib directory out_var)
+      file(GLOB_RECURSE actual
+        LIST_DIRECTORIES FALSE
+        RELATIVE ${CMAKE_INSTALL_PREFIX}/${directory}
+        ${CMAKE_INSTALL_PREFIX}/${directory}/*.dll
+      )
+
+      if(actual)
+        list(SORT actual)
+      endif()
+
+      set(${out_var} "${actual}" PARENT_SCOPE)
+    endfunction()
+
+    check_installed_lib("results_old" results_old)
+    check_installed_lib("results_new" results_new)
+    check_installed_lib("results_any" results_any)
+    check_installed_lib("results_any_forward" results_any_forward)
+
+    if(NOT results_any)
+      message(SEND_ERROR "Any dependencies are empty: `${results_any}`")
+    endif()
+
+    if(NOT results_any_forward)
+      message(SEND_ERROR "Any forward dependencies are empty: `${results_any_forward}`")
+    endif()
+  ]]
+)
diff --git a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/CMP0207-subdir/CMakeLists.txt b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/CMP0207-subdir/CMakeLists.txt
new file mode 100644
index 0000000..8a1946c
--- /dev/null
+++ b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/CMP0207-subdir/CMakeLists.txt
@@ -0,0 +1 @@
+add_library(test SHARED "${CMAKE_BINARY_DIR}/test.c")
diff --git a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/RunCMakeTest.cmake b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/RunCMakeTest.cmake
index 5583407..88ed1bb 100644
--- a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/RunCMakeTest.cmake
+++ b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/RunCMakeTest.cmake
@@ -49,6 +49,9 @@
   run_cmake(badargs1)
   run_cmake(badargs2)
 elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
+  run_install_test(CMP0207-OLD)
+  run_install_test(CMP0207-WARN)
+  run_install_test(CMP0207-NEW)
   run_install_test(windows)
   run_install_test(windows-unresolved)
   run_install_test(windows-conflict)
diff --git a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/windows.cmake b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/windows.cmake
index aad9077..c45955f 100644
--- a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/windows.cmake
+++ b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/windows.cmake
@@ -50,6 +50,7 @@
 
 install(CODE [[
   function(exec_get_runtime_dependencies depsfile udepsfile cdepsfile)
+    cmake_policy(SET CMP0207 NEW)
     file(GET_RUNTIME_DEPENDENCIES
       RESOLVED_DEPENDENCIES_VAR deps
       UNRESOLVED_DEPENDENCIES_VAR udeps
diff --git a/Tests/RunCMake/file/RunCMakeTest.cmake b/Tests/RunCMake/file/RunCMakeTest.cmake
index 38ec2ac..57c191b 100644
--- a/Tests/RunCMake/file/RunCMakeTest.cmake
+++ b/Tests/RunCMake/file/RunCMakeTest.cmake
@@ -1,9 +1,5 @@
 include(RunCMake)
 
-run_cmake(CREATE_LINK)
-run_cmake(CREATE_LINK-COPY_ON_ERROR)
-run_cmake(CREATE_LINK-noarg)
-run_cmake(CREATE_LINK-noexist)
 run_cmake(TOUCH)
 run_cmake(TOUCH-error-in-source-directory)
 run_cmake(TOUCH-error-missing-directory)
@@ -87,8 +83,6 @@
 if(NOT WIN32
     AND NOT MSYS # FIXME: This works on CYGWIN but not on MSYS
     )
-  run_cmake(CREATE_LINK-SYMBOLIC)
-  run_cmake(CREATE_LINK-SYMBOLIC-noexist)
   run_cmake(GLOB_RECURSE-cyclic-recursion)
   run_cmake(INSTALL-SYMLINK)
   run_cmake(READ_SYMLINK)
diff --git a/Tests/RunCMake/install/EXPORT-SystemInclude-check.cmake b/Tests/RunCMake/install/EXPORT-SystemInclude-check.cmake
new file mode 100644
index 0000000..32a1401
--- /dev/null
+++ b/Tests/RunCMake/install/EXPORT-SystemInclude-check.cmake
@@ -0,0 +1,4 @@
+RunCMake_check_file(export "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/Export/22ecfa717ccadd33cf3e4bcbabcbde6b/foo.cmake" [[
+ *INTERFACE_INCLUDE_DIRECTORIES "\${_IMPORT_PREFIX}/include"
+ *INTERFACE_SYSTEM_INCLUDE_DIRECTORIES "\${_IMPORT_PREFIX}/include"
+]])
diff --git a/Tests/RunCMake/install/EXPORT-SystemInclude.cmake b/Tests/RunCMake/install/EXPORT-SystemInclude.cmake
new file mode 100644
index 0000000..a68ef8d
--- /dev/null
+++ b/Tests/RunCMake/install/EXPORT-SystemInclude.cmake
@@ -0,0 +1,4 @@
+add_library(iface INTERFACE)
+target_include_directories(iface SYSTEM INTERFACE "$<INSTALL_INTERFACE:include>")
+install(TARGETS iface EXPORT foo)
+install(EXPORT foo DESTINATION lib/cmake/foo)
diff --git a/Tests/RunCMake/install/RunCMakeTest.cmake b/Tests/RunCMake/install/RunCMakeTest.cmake
index 9309f9a..818b898 100644
--- a/Tests/RunCMake/install/RunCMakeTest.cmake
+++ b/Tests/RunCMake/install/RunCMakeTest.cmake
@@ -1,3 +1,4 @@
+cmake_minimum_required(VERSION 4.0)
 include(RunCMake)
 
 # Function to build and install a project.  The latter step *-check.cmake
@@ -87,6 +88,7 @@
 run_cmake(EXPORT-UnknownExport)
 run_cmake(EXPORT-NamelinkOnly)
 run_cmake(EXPORT-SeparateNamelink)
+run_cmake(EXPORT-SystemInclude)
 run_cmake(EXPORT-TargetTwice)
 run_cmake(EXPORT-InterfaceLinkNoexist)
 run_cmake(CMP0062-NEW)
diff --git a/Tests/RunCMake/property_init/CompileSources.cmake b/Tests/RunCMake/property_init/CompileSources.cmake
index ca3871d..fe2b0fb 100644
--- a/Tests/RunCMake/property_init/CompileSources.cmake
+++ b/Tests/RunCMake/property_init/CompileSources.cmake
@@ -102,7 +102,6 @@
   "C_LINKER_LAUNCHER"                       "ccache"            "<SAME>"
   ### C++
   "CXX_LINKER_LAUNCHER"                     "ccache"            "<SAME>"
-  "CXX_MODULE_STD"                          "ON"                "<SAME>"
   ### CUDA
   "CUDA_RESOLVE_DEVICE_SYMBOLS"             "ON"                "<SAME>"
   "CUDA_RUNTIME_LIBRARY"                    "Static"            "<SAME>"
@@ -229,6 +228,15 @@
     )
 endmacro ()
 
+set(_cmake_supported_import_std_experimental "")
+cmake_language(GET_EXPERIMENTAL_FEATURE_ENABLED "CxxImportStd" _cmake_supported_import_std_experimental)
+if(_cmake_supported_import_std_experimental)
+  list(APPEND properties
+    # property                      expected  alias
+    "CXX_MODULE_STD"                "ON"      "<SAME>"
+  )
+endif()
+
 # Mock up knowing the standard flag. This doesn't actually build, so nothing
 # should care at this point.
 set(CMAKE_Cc_std_11_STANDARD_COMPILE_OPTION "-std=c11")
diff --git a/Utilities/CMakeLists.txt b/Utilities/CMakeLists.txt
index e73827a..9b434f0 100644
--- a/Utilities/CMakeLists.txt
+++ b/Utilities/CMakeLists.txt
@@ -7,7 +7,7 @@
   # Undocumented option for CI usage to reuse already
   # built documentation.
   install(DIRECTORY ${CMake_DOC_ARTIFACT_PREFIX}/
-          DESTINATION . USE_SOURCE_PERMISSIONS)
+          DESTINATION ${CMake_INSTALL_APP_DIR} USE_SOURCE_PERMISSIONS)
 else()
   # Normal documentation build.
   add_subdirectory(Sphinx)
diff --git a/Utilities/Doxygen/CMakeLists.txt b/Utilities/Doxygen/CMakeLists.txt
index 22712b7..be15f9c 100644
--- a/Utilities/Doxygen/CMakeLists.txt
+++ b/Utilities/Doxygen/CMakeLists.txt
@@ -82,14 +82,14 @@
   if(CMake_BUILD_DEVELOPER_REFERENCE_HTML)
     CMake_OPTIONAL_COMPONENT(cmake-developer-reference-html)
     install(DIRECTORY "${CMakeDeveloperReference_BINARY_DIR}/developer-reference/html"
-      DESTINATION ${CMAKE_DOC_DIR}/developer-reference
+      DESTINATION ${CMake_INSTALL_DOC_DIR}/developer-reference
       ${COMPONENT})
   endif()
 
   if(CMake_BUILD_DEVELOPER_REFERENCE_QTHELP)
     CMake_OPTIONAL_COMPONENT(cmake-developer-reference-qthelp)
     install(FILES "${CMakeDeveloperReference_BINARY_DIR}/developer-reference/CMakeDeveloperReference-${CMake_VERSION_MAJOR}${CMake_VERSION_MINOR}${CMake_VERSION_PATCH}.qch"
-      DESTINATION ${CMAKE_DOC_DIR}/developer-reference
+      DESTINATION ${CMake_INSTALL_DOC_DIR}/developer-reference
       ${COMPONENT})
   endif()
 
diff --git a/Utilities/Release/macos/qt-5.15.2-macosx10.13-x86_64-arm64.bash b/Utilities/Release/macos/qt-5.15.2-macosx10.13-x86_64-arm64.bash
deleted file mode 100755
index bf92e62..0000000
--- a/Utilities/Release/macos/qt-5.15.2-macosx10.13-x86_64-arm64.bash
+++ /dev/null
@@ -1,125 +0,0 @@
-#!/usr/bin/env bash
-
-# Run this script on a macOS x86_64 host to generate Qt universal binaries.
-#
-# This script requires the 'makeuniversal' tool from:
-#
-#   https://github.com/fizzyade/makeuniversal
-#
-# Build it with an existing local Qt installation first.
-#
-# Set the PATH environment variable to contain the location of 'makeuniversal'.
-
-set -e
-set -x
-
-umask 022
-
-# Verify that 'makeuniversal' is available in the PATH.
-type -p makeuniversal >/dev/null
-
-# Download, verify, and extract sources.
-curl -OL https://download.qt.io/archive/qt/5.15/5.15.2/single/qt-everywhere-src-5.15.2.tar.xz
-shasum -a 256 qt-everywhere-src-5.15.2.tar.xz | grep -q 3a530d1b243b5dec00bc54937455471aaa3e56849d2593edb8ded07228202240
-tar xjf qt-everywhere-src-5.15.2.tar.xz
-
-# Build the x86_64 variant.
-mkdir qt-5.15.2-x86_64
-cd qt-5.15.2-x86_64
-../qt-everywhere-src-5.15.2/configure \
-  --prefix=/ \
-  -platform macx-clang \
-  -device-option QMAKE_APPLE_DEVICE_ARCHS=x86_64 \
-  -device-option QMAKE_MACOSX_DEPLOYMENT_TARGET=10.13 \
-  -release \
-  -opensource -confirm-license \
-  -gui \
-  -widgets \
-  -no-gif \
-  -no-icu \
-  -no-pch \
-  -no-angle \
-  -no-opengl \
-  -no-dbus \
-  -no-harfbuzz \
-  -skip declarative \
-  -skip multimedia \
-  -skip qtcanvas3d \
-  -skip qtcharts \
-  -skip qtconnectivity \
-  -skip qtdeclarative \
-  -skip qtgamepad \
-  -skip qtlocation \
-  -skip qtmultimedia \
-  -skip qtnetworkauth \
-  -skip qtpurchasing \
-  -skip qtremoteobjects \
-  -skip qtscript \
-  -skip qtsensors \
-  -skip qtserialbus \
-  -skip qtserialport \
-  -skip qtsvg \
-  -skip qtwebchannel \
-  -skip qtwebengine \
-  -skip qtwebsockets \
-  -skip qtxmlpatterns \
-  -nomake examples \
-  -nomake tests \
-  -nomake tools
-make -j 8
-cd ..
-
-# Build the arm64 variant.
-mkdir qt-5.15.2-arm64
-cd qt-5.15.2-arm64
-../qt-everywhere-src-5.15.2/configure \
-  --prefix=/ \
-  -platform macx-clang \
-  -device-option QMAKE_APPLE_DEVICE_ARCHS=arm64 \
-  -device-option QMAKE_MACOSX_DEPLOYMENT_TARGET=10.13 \
-  -release \
-  -opensource -confirm-license \
-  -gui \
-  -widgets \
-  -no-gif \
-  -no-icu \
-  -no-pch \
-  -no-angle \
-  -no-opengl \
-  -no-dbus \
-  -no-harfbuzz \
-  -skip declarative \
-  -skip multimedia \
-  -skip qtcanvas3d \
-  -skip qtcharts \
-  -skip qtconnectivity \
-  -skip qtdeclarative \
-  -skip qtgamepad \
-  -skip qtlocation \
-  -skip qtmultimedia \
-  -skip qtnetworkauth \
-  -skip qtpurchasing \
-  -skip qtremoteobjects \
-  -skip qtscript \
-  -skip qtsensors \
-  -skip qtserialbus \
-  -skip qtserialport \
-  -skip qtsvg \
-  -skip qtwebchannel \
-  -skip qtwebengine \
-  -skip qtwebsockets \
-  -skip qtxmlpatterns \
-  -nomake examples \
-  -nomake tests \
-  -nomake tools
-make -j 8 -k
-cd ..
-
-# Combine the two builds into universal binaries.
-makeuniversal qt-5.15.2-univ qt-5.15.2-x86_64 qt-5.15.2-arm64
-cd qt-5.15.2-univ
-make install -j 8 INSTALL_ROOT=/tmp/qt-5.15.2-macosx10.13-x86_64-arm64
-cd ..
-
-# Create the final tarball containing universal binaries.
-tar cjf qt-5.15.2-macosx10.13-x86_64-arm64.tar.xz -C /tmp qt-5.15.2-macosx10.13-x86_64-arm64
diff --git a/Utilities/Release/macos/sign-notarize.bash b/Utilities/Release/macos/sign-notarize.bash
index 55ed591..89ed702 100755
--- a/Utilities/Release/macos/sign-notarize.bash
+++ b/Utilities/Release/macos/sign-notarize.bash
@@ -91,14 +91,16 @@
 readonly vol_path="/Volumes/$vol_name"
 hdiutil attach "${udrw_dmg}"
 
-codesign --verify --timestamp --options=runtime --verbose --deep \
+codesign --verify --timestamp --options=runtime --verbose --force --deep \
   -s "$id" \
   --entitlements "$entitlements_xml" \
-  "$vol_path/CMake.app/Contents/bin/cmake" \
-  "$vol_path/CMake.app/Contents/bin/ccmake" \
-  "$vol_path/CMake.app/Contents/bin/ctest" \
-  "$vol_path/CMake.app/Contents/bin/cpack" \
-  "$vol_path/CMake.app"
+  "$vol_path"/CMake.app/Contents/bin/cmake \
+  "$vol_path"/CMake.app/Contents/bin/ccmake \
+  "$vol_path"/CMake.app/Contents/bin/ctest \
+  "$vol_path"/CMake.app/Contents/bin/cpack \
+  "$vol_path"/CMake.app/Contents/Frameworks/*.framework/Versions/[A56]/Qt* \
+  "$vol_path"/CMake.app/Contents/PlugIns/*/lib*.dylib \
+  "$vol_path"/CMake.app
 
 ditto -c -k --keepParent "$vol_path/CMake.app" "$tmpdir/CMake.app.zip"
 xcrun notarytool submit "$tmpdir/CMake.app.zip" --keychain-profile "$keychain_profile" --wait
diff --git a/Utilities/Scripts/update-bzip2.bash b/Utilities/Scripts/update-bzip2.bash
index 83439d1..cda9ca7 100755
--- a/Utilities/Scripts/update-bzip2.bash
+++ b/Utilities/Scripts/update-bzip2.bash
@@ -10,6 +10,7 @@
 readonly repo="https://sourceware.org/git/bzip2.git"
 readonly tag="bzip2-1.0.8"
 readonly shortlog=false
+readonly exact_tree_match=false
 readonly paths="
   LICENSE
   README
@@ -21,6 +22,7 @@
     git_archive
     pushd "${extractdir}/${name}-reduced"
     echo "* -whitespace" > .gitattributes
+    fromdos dlltest.c
     popd
 }
 
diff --git a/Utilities/Scripts/update-cppdap.bash b/Utilities/Scripts/update-cppdap.bash
index ffe10d9..0f5e091 100755
--- a/Utilities/Scripts/update-cppdap.bash
+++ b/Utilities/Scripts/update-cppdap.bash
@@ -10,6 +10,7 @@
 readonly repo="https://github.com/google/cppdap.git"
 readonly tag="c69444ed76f7468b232ac4f989cb8f2bdc100185" # 2024-08-02
 readonly shortlog=false
+readonly exact_tree_match=false
 readonly paths="
   LICENSE
   include
diff --git a/Utilities/Scripts/update-curl.bash b/Utilities/Scripts/update-curl.bash
index e0c3c6d..0ce3edc 100755
--- a/Utilities/Scripts/update-curl.bash
+++ b/Utilities/Scripts/update-curl.bash
@@ -10,6 +10,7 @@
 readonly repo="https://github.com/curl/curl.git"
 readonly tag="curl-8_17_0"
 readonly shortlog=false
+readonly exact_tree_match=false
 readonly paths="
   CMake/*
   CMakeLists.txt
diff --git a/Utilities/Scripts/update-elf.bash b/Utilities/Scripts/update-elf.bash
index 1a065ba..ac9d8b9 100755
--- a/Utilities/Scripts/update-elf.bash
+++ b/Utilities/Scripts/update-elf.bash
@@ -10,6 +10,7 @@
 readonly repo="https://github.com/freebsd/freebsd-src.git"
 readonly tag="main"
 readonly shortlog=false
+readonly exact_tree_match=false
 readonly paths="
   sys/sys/elf32.h
   sys/sys/elf64.h
diff --git a/Utilities/Scripts/update-expat.bash b/Utilities/Scripts/update-expat.bash
index e34b230..35f82c2 100755
--- a/Utilities/Scripts/update-expat.bash
+++ b/Utilities/Scripts/update-expat.bash
@@ -10,6 +10,7 @@
 readonly repo="https://github.com/libexpat/libexpat.git"
 readonly tag="R_2_6_2"
 readonly shortlog=false
+readonly exact_tree_match=false
 readonly paths="
   expat/lib/asciitab.h
   expat/lib/expat.h
diff --git a/Utilities/Scripts/update-gitsetup.bash b/Utilities/Scripts/update-gitsetup.bash
index 70fb165..04da57d 100755
--- a/Utilities/Scripts/update-gitsetup.bash
+++ b/Utilities/Scripts/update-gitsetup.bash
@@ -10,6 +10,7 @@
 readonly repo="https://gitlab.kitware.com/utils/gitsetup.git"
 readonly tag="setup"
 readonly shortlog=false
+readonly exact_tree_match=false
 readonly paths="
   .gitattributes
   LICENSE
diff --git a/Utilities/Scripts/update-jsoncpp.bash b/Utilities/Scripts/update-jsoncpp.bash
index 5e97f9e..f71d7f0 100755
--- a/Utilities/Scripts/update-jsoncpp.bash
+++ b/Utilities/Scripts/update-jsoncpp.bash
@@ -10,6 +10,7 @@
 readonly repo="https://github.com/open-source-parsers/jsoncpp.git"
 readonly tag="1.9.6"
 readonly shortlog=false
+readonly exact_tree_match=false
 readonly paths="
   LICENSE
   include/json
diff --git a/Utilities/Scripts/update-kwiml.bash b/Utilities/Scripts/update-kwiml.bash
index 4497c92..86109a1 100755
--- a/Utilities/Scripts/update-kwiml.bash
+++ b/Utilities/Scripts/update-kwiml.bash
@@ -10,6 +10,7 @@
 readonly repo="https://gitlab.kitware.com/utils/kwiml.git"
 readonly tag="master"
 readonly shortlog=true
+readonly exact_tree_match=false
 readonly paths="
 "
 
diff --git a/Utilities/Scripts/update-kwsys.bash b/Utilities/Scripts/update-kwsys.bash
index dfbd366..9f00b52 100755
--- a/Utilities/Scripts/update-kwsys.bash
+++ b/Utilities/Scripts/update-kwsys.bash
@@ -10,6 +10,7 @@
 readonly repo="https://gitlab.kitware.com/utils/kwsys.git"
 readonly tag="master"
 readonly shortlog=true
+readonly exact_tree_match=false
 readonly paths="
 "
 
diff --git a/Utilities/Scripts/update-libarchive.bash b/Utilities/Scripts/update-libarchive.bash
index e1be638..c313561 100755
--- a/Utilities/Scripts/update-libarchive.bash
+++ b/Utilities/Scripts/update-libarchive.bash
@@ -8,8 +8,9 @@
 readonly ownership="LibArchive Upstream <libarchive-discuss@googlegroups.com>"
 readonly subtree="Utilities/cmlibarchive"
 readonly repo="https://github.com/libarchive/libarchive.git"
-readonly tag="v3.8.1"
+readonly tag="v3.8.2"
 readonly shortlog=false
+readonly exact_tree_match=false
 readonly paths="
   CMakeLists.txt
   COPYING
diff --git a/Utilities/Scripts/update-liblzma.bash b/Utilities/Scripts/update-liblzma.bash
index 8bfde77..e4be024 100755
--- a/Utilities/Scripts/update-liblzma.bash
+++ b/Utilities/Scripts/update-liblzma.bash
@@ -10,6 +10,7 @@
 readonly repo="https://git.tukaani.org/xz.git"
 readonly tag="v5.6.3"
 readonly shortlog=false
+readonly exact_tree_match=false
 readonly paths="
   COPYING
   src/common/common_w32res.rc
diff --git a/Utilities/Scripts/update-librhash.bash b/Utilities/Scripts/update-librhash.bash
index b3d078b..871eb80 100755
--- a/Utilities/Scripts/update-librhash.bash
+++ b/Utilities/Scripts/update-librhash.bash
@@ -10,6 +10,7 @@
 readonly repo="https://github.com/rhash/rhash.git"
 readonly tag="v1.4.4"
 readonly shortlog=false
+readonly exact_tree_match=false
 readonly paths="
   COPYING
   librhash/algorithms.c
diff --git a/Utilities/Scripts/update-libuv.bash b/Utilities/Scripts/update-libuv.bash
index 1027436..b9f664e 100755
--- a/Utilities/Scripts/update-libuv.bash
+++ b/Utilities/Scripts/update-libuv.bash
@@ -14,6 +14,7 @@
 # - It requires Windows 8, we support Windows 7.
 readonly tag="v1.44.2"
 readonly shortlog=false
+readonly exact_tree_match=false
 readonly paths="
   LICENSE
   include
diff --git a/Utilities/Scripts/update-llpkgc.bash b/Utilities/Scripts/update-llpkgc.bash
index b1dd017..0e7830d 100755
--- a/Utilities/Scripts/update-llpkgc.bash
+++ b/Utilities/Scripts/update-llpkgc.bash
@@ -12,6 +12,7 @@
 readonly repo="https://gitlab.kitware.com/utils/llpkgc.git"
 readonly tag="7958a1de42b9eec04676d547f6fcf5daa425fbcc"
 readonly shortlog=false
+readonly exact_tree_match=false
 readonly paths="
   bin
   src
diff --git a/Utilities/Scripts/update-nghttp2.bash b/Utilities/Scripts/update-nghttp2.bash
index c638efe..ad7e79b 100755
--- a/Utilities/Scripts/update-nghttp2.bash
+++ b/Utilities/Scripts/update-nghttp2.bash
@@ -10,6 +10,7 @@
 readonly repo="https://github.com/nghttp2/nghttp2.git"
 readonly tag="v1.52.0" # When updating, sync PACKAGE_VERSION below!
 readonly shortlog=false
+readonly exact_tree_match=false
 readonly paths="
   COPYING
   lib/*.c
diff --git a/Utilities/Scripts/update-pdcurses.bash b/Utilities/Scripts/update-pdcurses.bash
index b1a2815..19dc574 100755
--- a/Utilities/Scripts/update-pdcurses.bash
+++ b/Utilities/Scripts/update-pdcurses.bash
@@ -10,6 +10,7 @@
 readonly repo="https://github.com/wmcbrine/PDCurses.git"
 readonly tag="f1cd4f4569451a5028ddf3d3c202f0ad6b1ae446"
 readonly shortlog=false
+readonly exact_tree_match=false
 readonly paths="
   README.md
   *.h
diff --git a/Utilities/Scripts/update-third-party.bash b/Utilities/Scripts/update-third-party.bash
index 98fc5a5..9f744b9 100644
--- a/Utilities/Scripts/update-third-party.bash
+++ b/Utilities/Scripts/update-third-party.bash
@@ -5,7 +5,7 @@
 # you may not use this file except in compliance with the License.
 # You may obtain a copy of the License at
 #
-#     http://www.apache.org/licenses/LICENSE-2.0
+#     https://www.apache.org/licenses/LICENSE-2.0
 #
 # Unless required by applicable law or agreed to in writing, software
 # distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,12 @@
 # limitations under the License.
 #=============================================================================
 
+set -e
+
+# Disable noise from `pre-commit` when no configuration is present on the
+# imported tree.
+export PRE_COMMIT_ALLOW_NO_CONFIG=1
+
 ########################################################################
 # Script for updating third party packages.
 #
@@ -33,6 +39,10 @@
 #       The tag, branch or commit hash to use for upstream.
 #   shortlog
 #       Optional.  Set to 'true' to get a shortlog in the commit message.
+#   exact_tree_match
+#       Optional. Set to 'false' to disable tree-object based matching for
+#       previous import commit (required for projects that allow modifying
+#       imported trees). In such cases, log-based searching is performed.
 #
 # Additionally, an "extract_source" function must be defined. It will be
 # run within the checkout of the project on the requested tag. It should
@@ -85,7 +95,8 @@
     pushd "${extractdir}/${name}-reduced"
     # Git does not allow custom attributes in a subdirectory where we
     # are about to merge the `.gitattributes` file, so disable them.
-    sed -i '/^\[attr\]/ {s/^/#/;}' .gitattributes
+    sed -i.bak -e '/^\[attr\]/ {s/^/#/;}' .gitattributes
+    rm .gitattributes.bak
     popd
 }
 
@@ -95,12 +106,13 @@
 }
 
 warn () {
-    echo >&2 "warning: $@"
+    echo >&2 "warning:" "$@"
 }
 
 readonly regex_date='20[0-9][0-9]-[0-9][0-9]-[0-9][0-9]'
 readonly basehash_regex="$name $regex_date ([0-9a-f]*)"
-readonly toplevel_dir="$( git rev-parse --show-toplevel )"
+toplevel_dir="$( git rev-parse --show-toplevel )"
+readonly toplevel_dir
 
 cd "$toplevel_dir"
 
@@ -117,17 +129,39 @@
     die "'repo' is empty"
 [ -n "$tag" ] || \
     die "'tag' is empty"
+[ -n "$exact_tree_match" ] || \
+    exact_tree_match=true
 
 # Check for an empty destination directory on disk.  By checking on disk and
 # not in the repo it allows a library to be freshly re-initialized in a single
 # commit rather than first deleting the old copy in one commit and adding the
 # new copy in a separate commit.
-if [ ! -d "$(git rev-parse --show-toplevel)/$subtree" ]; then
-    readonly basehash=""
+if [ ! -d "$( git rev-parse --show-toplevel )/$subtree" ]; then
+    basehash=""
+elif $exact_tree_match; then
+    # Find the tree object for the current subtree.
+    current_tree="$( git rev-parse "HEAD:$subtree" )"
+    # Search history for a commit whose subtree matches this tree object.
+    basehash=""
+    # Limit candidate commits to those with expected import commit messages for efficiency.
+    for commit in $( git rev-list --author="$ownership" --grep="$basehash_regex" HEAD ); do
+        imported_tree="$( git rev-parse "$commit^{tree}" )"
+        # Verify the imported tree is what is currently imported. If so, we
+        # have found the desired import commit.
+        if [ "$imported_tree" = "$current_tree" ] && [ -n "$imported_tree" ]; then
+            basehash="$commit"
+            break
+        fi
+    done
+    if [ -z "$basehash" ]; then
+        die "No previous import commit found with matching tree object for $subtree. (exact_tree_match enabled)"
+    fi
 else
-    readonly basehash="$( git rev-list --author="$ownership" --grep="$basehash_regex" -n 1 HEAD )"
+    basehash="$( git rev-list --author="$ownership" --grep="$basehash_regex" -n 1 HEAD )"
 fi
-readonly upstream_old_short="$( git cat-file commit "$basehash" | sed -n '/'"$basehash_regex"'/ {s/.*(//;s/)//;p;}' | egrep '^[0-9a-f]+$' )"
+readonly basehash
+upstream_old_short="$( git cat-file commit "$basehash" | sed -n '/'"$basehash_regex"'/ {s/.*(//;s/)//;p;}' | grep -E '^[0-9a-f]+$' )"
+readonly upstream_old_short
 
 [ -n "$basehash" ] || \
     warn "'basehash' is empty; performing initial import"
@@ -142,6 +176,9 @@
 
 trap "rm -rf '$workdir'" EXIT
 
+# Skip LFS downloading; imports should not need LFS data.
+export GIT_LFS_SKIP_SMUDGE=1
+
 # Get upstream
 git clone --recursive "$repo" "$upstreamdir"
 
@@ -166,20 +203,25 @@
 git checkout "$tag"
 git submodule sync --recursive
 git submodule update --recursive --init
-readonly upstream_hash="$( git rev-parse HEAD )"
-readonly upstream_hash_short="$( git rev-parse --short=8 "$upstream_hash" )"
-readonly upstream_datetime="$( git rev-list "$upstream_hash" --format='%ci' -n 1 | grep -e "^$regex_date" )"
-readonly upstream_date="$( echo "$upstream_datetime" | grep -o -e "$regex_date" )"
+upstream_hash="$( git rev-parse HEAD )"
+readonly upstream_hash
+upstream_hash_short="$( git rev-parse --short=8 "$upstream_hash" )"
+readonly upstream_hash_short
+upstream_datetime="$( git rev-list "$upstream_hash" --format='%ci' -n 1 | grep -e "^$regex_date" )"
+readonly upstream_datetime
+upstream_date="$( echo "$upstream_datetime" | grep -o -e "$regex_date" )"
+readonly upstream_date
 if $do_shortlog && [ -n "$basehash" ]; then
-    readonly commit_shortlog="
+    commit_shortlog="
 
 Upstream Shortlog
 -----------------
 
 $( git shortlog --no-merges --abbrev=8 --format='%h %s' "$upstream_old_short".."$upstream_hash" )"
 else
-    readonly commit_shortlog=""
+    commit_shortlog=""
 fi
+readonly commit_shortlog
 extract_source || \
     die "failed to extract source"
 popd
@@ -193,7 +235,7 @@
 mv -v "$name-reduced/"* .
 rmdir "$name-reduced/"
 git add -A .
-git commit -n --author="$ownership" --date="$upstream_datetime" -F - <<-EOF
+git commit --no-verify --no-post-rewrite --author="$ownership" --date="$upstream_datetime" -F - <<-EOF
 $commit_summary
 
 Code extracted from:
@@ -213,9 +255,9 @@
     # will fail, so use the flag by default.
     unrelated_histories_flag=""
     if git --version | grep -q windows; then
-        unrelated_histories_flag="--allow-unrelated-histories "
+        unrelated_histories_flag="--allow-unrelated-histories"
     elif git merge --help | grep -q -e allow-unrelated-histories; then
-        unrelated_histories_flag="--allow-unrelated-histories "
+        unrelated_histories_flag="--allow-unrelated-histories"
     fi
     readonly unrelated_histories_flag
 
diff --git a/Utilities/Scripts/update-vim-syntax.bash b/Utilities/Scripts/update-vim-syntax.bash
index bb14683..047807a 100755
--- a/Utilities/Scripts/update-vim-syntax.bash
+++ b/Utilities/Scripts/update-vim-syntax.bash
@@ -10,6 +10,7 @@
 readonly repo="https://github.com/pboettch/vim-cmake-syntax.git"
 readonly tag="master"
 readonly shortlog=true
+readonly exact_tree_match=false
 readonly paths="
   indent
   syntax
diff --git a/Utilities/Scripts/update-zlib.bash b/Utilities/Scripts/update-zlib.bash
index aad18bf..66802f5 100755
--- a/Utilities/Scripts/update-zlib.bash
+++ b/Utilities/Scripts/update-zlib.bash
@@ -10,6 +10,7 @@
 readonly repo="https://github.com/madler/zlib.git"
 readonly tag="v1.3.1" # When updating, sync Copyright.txt below!
 readonly shortlog=false
+readonly exact_tree_match=false
 readonly paths="
   README
 
diff --git a/Utilities/Scripts/update-zstd.bash b/Utilities/Scripts/update-zstd.bash
index 7bfb3dc..193671b 100755
--- a/Utilities/Scripts/update-zstd.bash
+++ b/Utilities/Scripts/update-zstd.bash
@@ -10,6 +10,7 @@
 readonly repo="https://github.com/facebook/zstd.git"
 readonly tag="v1.5.5"
 readonly shortlog=false
+readonly exact_tree_match=false
 readonly paths="
   LICENSE
   README.md
diff --git a/Utilities/Sphinx/CMakeLists.txt b/Utilities/Sphinx/CMakeLists.txt
index 8f1634e..ecc6176 100644
--- a/Utilities/Sphinx/CMakeLists.txt
+++ b/Utilities/Sphinx/CMakeLists.txt
@@ -283,7 +283,7 @@
 if(SPHINX_INFO)
   CMake_OPTIONAL_COMPONENT(sphinx-info)
   install(FILES ${CMAKE_CURRENT_BINARY_DIR}/texinfo/cmake.info
-          DESTINATION ${CMAKE_INFO_DIR}
+          DESTINATION ${CMake_INSTALL_INFO_DIR}
           ${COMPONENT}
           )
 endif()
@@ -306,7 +306,7 @@
       if(NOT skip)
         CMake_OPTIONAL_COMPONENT(sphinx-man)
         install(FILES ${CMAKE_CURRENT_BINARY_DIR}/man/${name}.${sec}
-                DESTINATION ${CMAKE_MAN_DIR}/man${sec}
+                DESTINATION ${CMake_INSTALL_MAN_DIR}/man${sec}
                 ${COMPONENT})
       endif()
       unset(skip)
@@ -317,7 +317,7 @@
 if(SPHINX_HTML)
   CMake_OPTIONAL_COMPONENT(sphinx-html)
   install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html
-          DESTINATION ${CMAKE_DOC_DIR}
+          DESTINATION ${CMake_INSTALL_DOC_DIR}
           ${COMPONENT}
           PATTERN .buildinfo EXCLUDE
           )
@@ -326,7 +326,7 @@
 if(SPHINX_SINGLEHTML)
   CMake_OPTIONAL_COMPONENT(sphinx-singlehtml)
   install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/singlehtml
-          DESTINATION ${CMAKE_DOC_DIR}
+          DESTINATION ${CMake_INSTALL_DOC_DIR}
           ${COMPONENT}
           PATTERN .buildinfo EXCLUDE
           )
@@ -335,13 +335,13 @@
 if(SPHINX_QTHELP)
   CMake_OPTIONAL_COMPONENT(sphinx-qthelp)
   install(FILES ${CMAKE_CURRENT_BINARY_DIR}/qthelp/CMake.qch
-          DESTINATION ${CMAKE_DOC_DIR} ${COMPONENT}
+          DESTINATION ${CMake_INSTALL_DOC_DIR} ${COMPONENT}
           )
 endif()
 
 if(SPHINX_LATEXPDF)
   CMake_OPTIONAL_COMPONENT(sphinx-latexpdf)
   install(FILES ${CMAKE_CURRENT_BINARY_DIR}/latexpdf/latex/CMake.pdf
-          DESTINATION ${CMAKE_DOC_DIR} ${COMPONENT}
+          DESTINATION ${CMake_INSTALL_DOC_DIR} ${COMPONENT}
           )
 endif()
diff --git a/Utilities/ast-grep/rule-tests/__snapshots__/cmhasliteralprefix-char-snapshot.yml b/Utilities/ast-grep/rule-tests/__snapshots__/cmhasliteralprefix-char-snapshot.yml
new file mode 100644
index 0000000..4739ca5
--- /dev/null
+++ b/Utilities/ast-grep/rule-tests/__snapshots__/cmhasliteralprefix-char-snapshot.yml
@@ -0,0 +1,23 @@
+id: cmhasliteralprefix-char
+snapshots:
+  cmHasLiteralPrefix(haystack, "'"):
+    fixed: cmHasPrefix(haystack, '\'')
+    labels:
+    - source: cmHasLiteralPrefix(haystack, "'")
+      style: primary
+      start: 0
+      end: 33
+  cmHasLiteralPrefix(haystack, "\n"):
+    fixed: cmHasPrefix(haystack, '\n')
+    labels:
+    - source: cmHasLiteralPrefix(haystack, "\n")
+      style: primary
+      start: 0
+      end: 34
+  cmHasLiteralPrefix(haystack, "a"):
+    fixed: cmHasPrefix(haystack, 'a')
+    labels:
+    - source: cmHasLiteralPrefix(haystack, "a")
+      style: primary
+      start: 0
+      end: 33
diff --git a/Utilities/ast-grep/rule-tests/__snapshots__/cmhasliteralsuffix-char-snapshot.yml b/Utilities/ast-grep/rule-tests/__snapshots__/cmhasliteralsuffix-char-snapshot.yml
new file mode 100644
index 0000000..d77881d
--- /dev/null
+++ b/Utilities/ast-grep/rule-tests/__snapshots__/cmhasliteralsuffix-char-snapshot.yml
@@ -0,0 +1,23 @@
+id: cmhasliteralsuffix-char
+snapshots:
+  cmHasLiteralSuffix(haystack, "'"):
+    fixed: cmHasSuffix(haystack, '\'')
+    labels:
+    - source: cmHasLiteralSuffix(haystack, "'")
+      style: primary
+      start: 0
+      end: 33
+  cmHasLiteralSuffix(haystack, "\n"):
+    fixed: cmHasSuffix(haystack, '\n')
+    labels:
+    - source: cmHasLiteralSuffix(haystack, "\n")
+      style: primary
+      start: 0
+      end: 34
+  cmHasLiteralSuffix(haystack, "a"):
+    fixed: cmHasSuffix(haystack, 'a')
+    labels:
+    - source: cmHasLiteralSuffix(haystack, "a")
+      style: primary
+      start: 0
+      end: 33
diff --git a/Utilities/ast-grep/rule-tests/__snapshots__/cmhasprefix-char-snapshot.yml b/Utilities/ast-grep/rule-tests/__snapshots__/cmhasprefix-char-snapshot.yml
new file mode 100644
index 0000000..0b75c5e
--- /dev/null
+++ b/Utilities/ast-grep/rule-tests/__snapshots__/cmhasprefix-char-snapshot.yml
@@ -0,0 +1,47 @@
+id: cmhasprefix-char
+snapshots:
+  cmHasPrefix(haystack, "'"):
+    fixed: cmHasPrefix(haystack, '\'')
+    labels:
+    - source: '"''"'
+      style: primary
+      start: 22
+      end: 25
+    - source: cmHasPrefix(haystack, "'")
+      style: secondary
+      start: 0
+      end: 26
+    - source: ','
+      style: secondary
+      start: 20
+      end: 21
+  cmHasPrefix(haystack, "\n"):
+    fixed: cmHasPrefix(haystack, '\n')
+    labels:
+    - source: '"\n"'
+      style: primary
+      start: 22
+      end: 26
+    - source: cmHasPrefix(haystack, "\n")
+      style: secondary
+      start: 0
+      end: 27
+    - source: ','
+      style: secondary
+      start: 20
+      end: 21
+  cmHasPrefix(haystack, "a"):
+    fixed: cmHasPrefix(haystack, 'a')
+    labels:
+    - source: '"a"'
+      style: primary
+      start: 22
+      end: 25
+    - source: cmHasPrefix(haystack, "a")
+      style: secondary
+      start: 0
+      end: 26
+    - source: ','
+      style: secondary
+      start: 20
+      end: 21
diff --git a/Utilities/ast-grep/rule-tests/__snapshots__/cmhassuffix-char-snapshot.yml b/Utilities/ast-grep/rule-tests/__snapshots__/cmhassuffix-char-snapshot.yml
new file mode 100644
index 0000000..d376a53
--- /dev/null
+++ b/Utilities/ast-grep/rule-tests/__snapshots__/cmhassuffix-char-snapshot.yml
@@ -0,0 +1,47 @@
+id: cmhassuffix-char
+snapshots:
+  cmHasSuffix(haystack, "'"):
+    fixed: cmHasSuffix(haystack, '\'')
+    labels:
+    - source: '"''"'
+      style: primary
+      start: 22
+      end: 25
+    - source: cmHasSuffix(haystack, "'")
+      style: secondary
+      start: 0
+      end: 26
+    - source: ','
+      style: secondary
+      start: 20
+      end: 21
+  cmHasSuffix(haystack, "\n"):
+    fixed: cmHasSuffix(haystack, '\n')
+    labels:
+    - source: '"\n"'
+      style: primary
+      start: 22
+      end: 26
+    - source: cmHasSuffix(haystack, "\n")
+      style: secondary
+      start: 0
+      end: 27
+    - source: ','
+      style: secondary
+      start: 20
+      end: 21
+  cmHasSuffix(haystack, "a"):
+    fixed: cmHasSuffix(haystack, 'a')
+    labels:
+    - source: '"a"'
+      style: primary
+      start: 22
+      end: 25
+    - source: cmHasSuffix(haystack, "a")
+      style: secondary
+      start: 0
+      end: 26
+    - source: ','
+      style: secondary
+      start: 20
+      end: 21
diff --git a/Utilities/ast-grep/rule-tests/cmhasliteralprefix-char.yml b/Utilities/ast-grep/rule-tests/cmhasliteralprefix-char.yml
new file mode 100644
index 0000000..4254481
--- /dev/null
+++ b/Utilities/ast-grep/rule-tests/cmhasliteralprefix-char.yml
@@ -0,0 +1,8 @@
+---
+id: cmhasliteralprefix-char
+valid:
+  - 'cmHasLiteralPrefix(haystack, "foo")'
+invalid:
+  - 'cmHasLiteralPrefix(haystack, "a")'
+  - 'cmHasLiteralPrefix(haystack, "\n")'
+  - "cmHasLiteralPrefix(haystack, \"'\")"
diff --git a/Utilities/ast-grep/rule-tests/cmhasliteralsuffix-char.yml b/Utilities/ast-grep/rule-tests/cmhasliteralsuffix-char.yml
new file mode 100644
index 0000000..03f0650
--- /dev/null
+++ b/Utilities/ast-grep/rule-tests/cmhasliteralsuffix-char.yml
@@ -0,0 +1,8 @@
+---
+id: cmhasliteralsuffix-char
+valid:
+  - 'cmHasLiteralSuffix(haystack, "foo")'
+invalid:
+  - 'cmHasLiteralSuffix(haystack, "a")'
+  - 'cmHasLiteralSuffix(haystack, "\n")'
+  - "cmHasLiteralSuffix(haystack, \"'\")"
diff --git a/Utilities/ast-grep/rule-tests/cmhasprefix-char.yml b/Utilities/ast-grep/rule-tests/cmhasprefix-char.yml
new file mode 100644
index 0000000..37e51ca
--- /dev/null
+++ b/Utilities/ast-grep/rule-tests/cmhasprefix-char.yml
@@ -0,0 +1,9 @@
+---
+id: cmhasprefix-char
+valid:
+  - "cmHasPrefix(haystack, 'a')"
+  - 'cmHasPrefix(haystack, "foo")'
+invalid:
+  - 'cmHasPrefix(haystack, "a")'
+  - 'cmHasPrefix(haystack, "\n")'
+  - "cmHasPrefix(haystack, \"'\")"
diff --git a/Utilities/ast-grep/rule-tests/cmhassuffix-char.yml b/Utilities/ast-grep/rule-tests/cmhassuffix-char.yml
new file mode 100644
index 0000000..17a146b
--- /dev/null
+++ b/Utilities/ast-grep/rule-tests/cmhassuffix-char.yml
@@ -0,0 +1,9 @@
+---
+id: cmhassuffix-char
+valid:
+  - "cmHasSuffix(haystack, 'a')"
+  - 'cmHasSuffix(haystack, "foo")'
+invalid:
+  - 'cmHasSuffix(haystack, "a")'
+  - 'cmHasSuffix(haystack, "\n")'
+  - "cmHasSuffix(haystack, \"'\")"
diff --git a/Utilities/ast-grep/rules/cmhasliteralprefix-char.yml b/Utilities/ast-grep/rules/cmhasliteralprefix-char.yml
new file mode 100644
index 0000000..99f178f
--- /dev/null
+++ b/Utilities/ast-grep/rules/cmhasliteralprefix-char.yml
@@ -0,0 +1,27 @@
+---
+id: cmhasliteralprefix-char
+language: Cpp
+severity: warning
+message: "`cmHasLiteralPrefix` with a one-char prefix search should use `cmHasPrefix`"
+rule:
+  pattern: cmHasLiteralPrefix($HAYSTACK, $NEEDLE)
+constraints:
+  NEEDLE:
+    regex: '^"(.|\\.)"$'
+transform:
+  NEEDLE_CHANGE_QUOTE:
+    replace:
+      source: $NEEDLE
+      replace: '(^"|"$)'
+      by: "'"
+  NEEDLE_ESCAPE_SINGLE_QUOTE:
+    replace:
+      source: $NEEDLE_CHANGE_QUOTE
+      replace: "'''"
+      by: "'\\''"
+  NEEDLE_OUT:
+    replace:
+      source: $NEEDLE_ESCAPE_SINGLE_QUOTE
+      replace: '\\"'
+      by: '"'
+fix: cmHasPrefix($HAYSTACK, $NEEDLE_OUT)
diff --git a/Utilities/ast-grep/rules/cmhasliteralsuffix-char.yml b/Utilities/ast-grep/rules/cmhasliteralsuffix-char.yml
new file mode 100644
index 0000000..ee3f035
--- /dev/null
+++ b/Utilities/ast-grep/rules/cmhasliteralsuffix-char.yml
@@ -0,0 +1,27 @@
+---
+id: cmhasliteralsuffix-char
+language: Cpp
+severity: warning
+message: "`cmHasLiteralSuffix` with a one-char suffix search should use `cmHasSuffix`"
+rule:
+  pattern: cmHasLiteralSuffix($HAYSTACK, $NEEDLE)
+constraints:
+  NEEDLE:
+    regex: '^"(.|\\.)"$'
+transform:
+  NEEDLE_CHANGE_QUOTE:
+    replace:
+      source: $NEEDLE
+      replace: '(^"|"$)'
+      by: "'"
+  NEEDLE_ESCAPE_SINGLE_QUOTE:
+    replace:
+      source: $NEEDLE_CHANGE_QUOTE
+      replace: "'''"
+      by: "'\\''"
+  NEEDLE_OUT:
+    replace:
+      source: $NEEDLE_ESCAPE_SINGLE_QUOTE
+      replace: '\\"'
+      by: '"'
+fix: cmHasSuffix($HAYSTACK, $NEEDLE_OUT)
diff --git a/Utilities/ast-grep/rules/cmhasprefix-char.yml b/Utilities/ast-grep/rules/cmhasprefix-char.yml
new file mode 100644
index 0000000..06027a7
--- /dev/null
+++ b/Utilities/ast-grep/rules/cmhasprefix-char.yml
@@ -0,0 +1,34 @@
+---
+id: cmhasprefix-char
+language: Cpp
+severity: warning
+message: "`cmHasPrefix` with a one-char prefix search should use `cmHasPrefix`"
+rule:
+  kind: string_literal
+  pattern: $ARG
+  follows:
+    regex: '(,|[(])'
+  inside:
+    matches: cmhasprefix-call
+    stopBy:
+      kind: call_expression
+constraints:
+  ARG:
+    regex: '^"(.|\\.)"$'
+transform:
+  ARG_CHANGE_QUOTE:
+    replace:
+      source: $ARG
+      replace: '(^"|"$)'
+      by: "'"
+  ARG_ESCAPE_SINGLE_QUOTE:
+    replace:
+      source: $ARG_CHANGE_QUOTE
+      replace: "'''"
+      by: "'\\''"
+  ARG_OUT:
+    replace:
+      source: $ARG_ESCAPE_SINGLE_QUOTE
+      replace: '\\"'
+      by: '"'
+fix: $ARG_OUT
diff --git a/Utilities/ast-grep/rules/cmhassuffix-char.yml b/Utilities/ast-grep/rules/cmhassuffix-char.yml
new file mode 100644
index 0000000..1d45b83
--- /dev/null
+++ b/Utilities/ast-grep/rules/cmhassuffix-char.yml
@@ -0,0 +1,34 @@
+---
+id: cmhassuffix-char
+language: Cpp
+severity: warning
+message: "`cmHasSuffix` with a one-char suffix search should use `cmHasSuffix`"
+rule:
+  kind: string_literal
+  pattern: $ARG
+  follows:
+    regex: '(,|[(])'
+  inside:
+    matches: cmhassuffix-call
+    stopBy:
+      kind: call_expression
+constraints:
+  ARG:
+    regex: '^"(.|\\.)"$'
+transform:
+  ARG_CHANGE_QUOTE:
+    replace:
+      source: $ARG
+      replace: '(^"|"$)'
+      by: "'"
+  ARG_ESCAPE_SINGLE_QUOTE:
+    replace:
+      source: $ARG_CHANGE_QUOTE
+      replace: "'''"
+      by: "'\\''"
+  ARG_OUT:
+    replace:
+      source: $ARG_ESCAPE_SINGLE_QUOTE
+      replace: '\\"'
+      by: '"'
+fix: $ARG_OUT
diff --git a/Utilities/ast-grep/utils/cmhasprefix-call.yml b/Utilities/ast-grep/utils/cmhasprefix-call.yml
new file mode 100644
index 0000000..eb57a79
--- /dev/null
+++ b/Utilities/ast-grep/utils/cmhasprefix-call.yml
@@ -0,0 +1,5 @@
+---
+id: cmhasprefix-call
+language: Cpp
+rule:
+  pattern: cmHasPrefix($$$)
diff --git a/Utilities/ast-grep/utils/cmhassuffix-call.yml b/Utilities/ast-grep/utils/cmhassuffix-call.yml
new file mode 100644
index 0000000..d0fca6e
--- /dev/null
+++ b/Utilities/ast-grep/utils/cmhassuffix-call.yml
@@ -0,0 +1,5 @@
+---
+id: cmhassuffix-call
+language: Cpp
+rule:
+  pattern: cmHasSuffix($$$)
diff --git a/Utilities/cmThirdPartyChecks.cmake b/Utilities/cmThirdPartyChecks.cmake
index a316b6b..aa7e8d6 100644
--- a/Utilities/cmThirdPartyChecks.cmake
+++ b/Utilities/cmThirdPartyChecks.cmake
@@ -41,6 +41,8 @@
   set(HAVE_CHFLAGS 0)
   set(HAVE_CHOWN 0)
   set(HAVE_CHROOT 0)
+  set(HAVE_CLOSEFROM 0)
+  set(HAVE_CLOSE_RANGE 0)
   set(HAVE_COPYFILE_H 0)
   set(HAVE_CRYPTO_H 0)
   set(HAVE_CTIME_R 0)
@@ -81,6 +83,7 @@
   set(HAVE_FUTIMES 0)
   set(HAVE_FUTIMESAT 0)
   set(HAVE_GETADDRINFO 1)
+  set(HAVE_GETEGID 0)
   set(HAVE_GETEUID 0)
   set(HAVE_GETGRGID_R 0)
   set(HAVE_GETGRNAM_R 0)
@@ -94,6 +97,8 @@
   set(HAVE_GETPWNAM_R 0)
   set(HAVE_GETPWUID_R 0)
   set(HAVE_GETRANDOM 0)
+  set(HAVE_GETRESGID 0)
+  set(HAVE_GETRESUID 0)
   set(HAVE_GETRLIMIT 0)
   set(HAVE_GETSOCKNAME 1)
   set(HAVE_GETVFSBYNAME 0)
@@ -114,6 +119,7 @@
   set(HAVE_IOCTLSOCKET_CAMEL_FIONBIO 1)
   set(HAVE_IOCTLSOCKET_FIONBIO 1)
   set(HAVE_IO_H 1)
+  set(HAVE_ISSETUGID 0)
   set(HAVE_KRB_H 0)
   set(HAVE_LANGINFO_H 0)
   set(HAVE_LCHFLAGS 0)
diff --git a/Utilities/cmbzip2/dlltest.c b/Utilities/cmbzip2/dlltest.c
index 03fa146..4e27da2 100644
--- a/Utilities/cmbzip2/dlltest.c
+++ b/Utilities/cmbzip2/dlltest.c
@@ -1,175 +1,175 @@
-/*

-   minibz2

-      libbz2.dll test program.

-      by Yoshioka Tsuneo (tsuneo@rr.iij4u.or.jp)

-      This file is Public Domain.  Welcome any email to me.

-

-   usage: minibz2 [-d] [-{1,2,..9}] [[srcfilename] destfilename]

-*/

-

-#define BZ_IMPORT

-#include <stdio.h>

-#include <stdlib.h>

-#include "bzlib.h"

-#ifdef _WIN32

-#include <io.h>

-#endif

-

-

-#ifdef _WIN32

-

-#define BZ2_LIBNAME "libbz2-1.0.2.DLL" 

-

-#include <windows.h>

-static int BZ2DLLLoaded = 0;

-static HINSTANCE BZ2DLLhLib;

-int BZ2DLLLoadLibrary(void)

-{

-   HINSTANCE hLib;

-

-   if(BZ2DLLLoaded==1){return 0;}

-   hLib=LoadLibrary(BZ2_LIBNAME);

-   if(hLib == NULL){

-      fprintf(stderr,"Can't load %s\n",BZ2_LIBNAME);

-      return -1;

-   }

-   BZ2_bzlibVersion=GetProcAddress(hLib,"BZ2_bzlibVersion");

-   BZ2_bzopen=GetProcAddress(hLib,"BZ2_bzopen");

-   BZ2_bzdopen=GetProcAddress(hLib,"BZ2_bzdopen");

-   BZ2_bzread=GetProcAddress(hLib,"BZ2_bzread");

-   BZ2_bzwrite=GetProcAddress(hLib,"BZ2_bzwrite");

-   BZ2_bzflush=GetProcAddress(hLib,"BZ2_bzflush");

-   BZ2_bzclose=GetProcAddress(hLib,"BZ2_bzclose");

-   BZ2_bzerror=GetProcAddress(hLib,"BZ2_bzerror");

-

-   if (!BZ2_bzlibVersion || !BZ2_bzopen || !BZ2_bzdopen

-       || !BZ2_bzread || !BZ2_bzwrite || !BZ2_bzflush

-       || !BZ2_bzclose || !BZ2_bzerror) {

-      fprintf(stderr,"GetProcAddress failed.\n");

-      return -1;

-   }

-   BZ2DLLLoaded=1;

-   BZ2DLLhLib=hLib;

-   return 0;

-

-}

-int BZ2DLLFreeLibrary(void)

-{

-   if(BZ2DLLLoaded==0){return 0;}

-   FreeLibrary(BZ2DLLhLib);

-   BZ2DLLLoaded=0;

-}

-#endif /* WIN32 */

-

-void usage(void)

-{

-   puts("usage: minibz2 [-d] [-{1,2,..9}] [[srcfilename] destfilename]");

-}

-

-int main(int argc,char *argv[])

-{

-   int decompress = 0;

-   int level = 9;

-   char *fn_r = NULL;

-   char *fn_w = NULL;

-

-#ifdef _WIN32

-   if(BZ2DLLLoadLibrary()<0){

-      fprintf(stderr,"Loading of %s failed.  Giving up.\n", BZ2_LIBNAME);

-      exit(1);

-   }

-   printf("Loading of %s succeeded.  Library version is %s.\n",

-          BZ2_LIBNAME, BZ2_bzlibVersion() );

-#endif

-   while(++argv,--argc){

-      if(**argv =='-' || **argv=='/'){

-         char *p;

-

-         for(p=*argv+1;*p;p++){

-            if(*p=='d'){

-               decompress = 1;

-            }else if('1'<=*p && *p<='9'){

-               level = *p - '0';

-            }else{

-               usage();

-               exit(1);

-            }

-         }

-      }else{

-         break;

-      }

-   }

-   if(argc>=1){

-      fn_r = *argv;

-      argc--;argv++;

-   }else{

-      fn_r = NULL;

-   }

-   if(argc>=1){

-      fn_w = *argv;

-      argc--;argv++;

-   }else{

-      fn_w = NULL;

-   }

-   {

-      int len;

-      char buff[0x1000];

-      char mode[10];

-

-      if(decompress){

-         BZFILE *BZ2fp_r = NULL;

-         FILE *fp_w = NULL;

-

-         if(fn_w){

-            if((fp_w = fopen(fn_w,"wb"))==NULL){

-               printf("can't open [%s]\n",fn_w);

-               perror("reason:");

-               exit(1);

-            }

-         }else{

-            fp_w = stdout;

-         }

-         if((fn_r == NULL && (BZ2fp_r = BZ2_bzdopen(fileno(stdin),"rb"))==NULL)

-            || (fn_r != NULL && (BZ2fp_r = BZ2_bzopen(fn_r,"rb"))==NULL)){

-            printf("can't bz2openstream\n");

-            exit(1);

-         }

-         while((len=BZ2_bzread(BZ2fp_r,buff,0x1000))>0){

-            fwrite(buff,1,len,fp_w);

-         }

-         BZ2_bzclose(BZ2fp_r);

-         if(fp_w != stdout) fclose(fp_w);

-      }else{

-         BZFILE *BZ2fp_w = NULL;

-         FILE *fp_r = NULL;

-

-         if(fn_r){

-            if((fp_r = fopen(fn_r,"rb"))==NULL){

-               printf("can't open [%s]\n",fn_r);

-               perror("reason:");

-               exit(1);

-            }

-         }else{

-            fp_r = stdin;

-         }

-         mode[0]='w';

-         mode[1] = '0' + level;

-         mode[2] = '\0';

-

-         if((fn_w == NULL && (BZ2fp_w = BZ2_bzdopen(fileno(stdout),mode))==NULL)

-            || (fn_w !=NULL && (BZ2fp_w = BZ2_bzopen(fn_w,mode))==NULL)){

-            printf("can't bz2openstream\n");

-            exit(1);

-         }

-         while((len=fread(buff,1,0x1000,fp_r))>0){

-            BZ2_bzwrite(BZ2fp_w,buff,len);

-         }

-         BZ2_bzclose(BZ2fp_w);

-         if(fp_r!=stdin)fclose(fp_r);

-      }

-   }

-#ifdef _WIN32

-   BZ2DLLFreeLibrary();

-#endif

-   return 0;

-}

+/*
+   minibz2
+      libbz2.dll test program.
+      by Yoshioka Tsuneo (tsuneo@rr.iij4u.or.jp)
+      This file is Public Domain.  Welcome any email to me.
+
+   usage: minibz2 [-d] [-{1,2,..9}] [[srcfilename] destfilename]
+*/
+
+#define BZ_IMPORT
+#include <stdio.h>
+#include <stdlib.h>
+#include "bzlib.h"
+#ifdef _WIN32
+#include <io.h>
+#endif
+
+
+#ifdef _WIN32
+
+#define BZ2_LIBNAME "libbz2-1.0.2.DLL" 
+
+#include <windows.h>
+static int BZ2DLLLoaded = 0;
+static HINSTANCE BZ2DLLhLib;
+int BZ2DLLLoadLibrary(void)
+{
+   HINSTANCE hLib;
+
+   if(BZ2DLLLoaded==1){return 0;}
+   hLib=LoadLibrary(BZ2_LIBNAME);
+   if(hLib == NULL){
+      fprintf(stderr,"Can't load %s\n",BZ2_LIBNAME);
+      return -1;
+   }
+   BZ2_bzlibVersion=GetProcAddress(hLib,"BZ2_bzlibVersion");
+   BZ2_bzopen=GetProcAddress(hLib,"BZ2_bzopen");
+   BZ2_bzdopen=GetProcAddress(hLib,"BZ2_bzdopen");
+   BZ2_bzread=GetProcAddress(hLib,"BZ2_bzread");
+   BZ2_bzwrite=GetProcAddress(hLib,"BZ2_bzwrite");
+   BZ2_bzflush=GetProcAddress(hLib,"BZ2_bzflush");
+   BZ2_bzclose=GetProcAddress(hLib,"BZ2_bzclose");
+   BZ2_bzerror=GetProcAddress(hLib,"BZ2_bzerror");
+
+   if (!BZ2_bzlibVersion || !BZ2_bzopen || !BZ2_bzdopen
+       || !BZ2_bzread || !BZ2_bzwrite || !BZ2_bzflush
+       || !BZ2_bzclose || !BZ2_bzerror) {
+      fprintf(stderr,"GetProcAddress failed.\n");
+      return -1;
+   }
+   BZ2DLLLoaded=1;
+   BZ2DLLhLib=hLib;
+   return 0;
+
+}
+int BZ2DLLFreeLibrary(void)
+{
+   if(BZ2DLLLoaded==0){return 0;}
+   FreeLibrary(BZ2DLLhLib);
+   BZ2DLLLoaded=0;
+}
+#endif /* WIN32 */
+
+void usage(void)
+{
+   puts("usage: minibz2 [-d] [-{1,2,..9}] [[srcfilename] destfilename]");
+}
+
+int main(int argc,char *argv[])
+{
+   int decompress = 0;
+   int level = 9;
+   char *fn_r = NULL;
+   char *fn_w = NULL;
+
+#ifdef _WIN32
+   if(BZ2DLLLoadLibrary()<0){
+      fprintf(stderr,"Loading of %s failed.  Giving up.\n", BZ2_LIBNAME);
+      exit(1);
+   }
+   printf("Loading of %s succeeded.  Library version is %s.\n",
+          BZ2_LIBNAME, BZ2_bzlibVersion() );
+#endif
+   while(++argv,--argc){
+      if(**argv =='-' || **argv=='/'){
+         char *p;
+
+         for(p=*argv+1;*p;p++){
+            if(*p=='d'){
+               decompress = 1;
+            }else if('1'<=*p && *p<='9'){
+               level = *p - '0';
+            }else{
+               usage();
+               exit(1);
+            }
+         }
+      }else{
+         break;
+      }
+   }
+   if(argc>=1){
+      fn_r = *argv;
+      argc--;argv++;
+   }else{
+      fn_r = NULL;
+   }
+   if(argc>=1){
+      fn_w = *argv;
+      argc--;argv++;
+   }else{
+      fn_w = NULL;
+   }
+   {
+      int len;
+      char buff[0x1000];
+      char mode[10];
+
+      if(decompress){
+         BZFILE *BZ2fp_r = NULL;
+         FILE *fp_w = NULL;
+
+         if(fn_w){
+            if((fp_w = fopen(fn_w,"wb"))==NULL){
+               printf("can't open [%s]\n",fn_w);
+               perror("reason:");
+               exit(1);
+            }
+         }else{
+            fp_w = stdout;
+         }
+         if((fn_r == NULL && (BZ2fp_r = BZ2_bzdopen(fileno(stdin),"rb"))==NULL)
+            || (fn_r != NULL && (BZ2fp_r = BZ2_bzopen(fn_r,"rb"))==NULL)){
+            printf("can't bz2openstream\n");
+            exit(1);
+         }
+         while((len=BZ2_bzread(BZ2fp_r,buff,0x1000))>0){
+            fwrite(buff,1,len,fp_w);
+         }
+         BZ2_bzclose(BZ2fp_r);
+         if(fp_w != stdout) fclose(fp_w);
+      }else{
+         BZFILE *BZ2fp_w = NULL;
+         FILE *fp_r = NULL;
+
+         if(fn_r){
+            if((fp_r = fopen(fn_r,"rb"))==NULL){
+               printf("can't open [%s]\n",fn_r);
+               perror("reason:");
+               exit(1);
+            }
+         }else{
+            fp_r = stdin;
+         }
+         mode[0]='w';
+         mode[1] = '0' + level;
+         mode[2] = '\0';
+
+         if((fn_w == NULL && (BZ2fp_w = BZ2_bzdopen(fileno(stdout),mode))==NULL)
+            || (fn_w !=NULL && (BZ2fp_w = BZ2_bzopen(fn_w,mode))==NULL)){
+            printf("can't bz2openstream\n");
+            exit(1);
+         }
+         while((len=fread(buff,1,0x1000,fp_r))>0){
+            BZ2_bzwrite(BZ2fp_w,buff,len);
+         }
+         BZ2_bzclose(BZ2fp_w);
+         if(fp_r!=stdin)fclose(fp_r);
+      }
+   }
+#ifdef _WIN32
+   BZ2DLLFreeLibrary();
+#endif
+   return 0;
+}
diff --git a/Utilities/cmcppdap/CMakeLists.txt b/Utilities/cmcppdap/CMakeLists.txt
index fe48132..2fd4379 100644
--- a/Utilities/cmcppdap/CMakeLists.txt
+++ b/Utilities/cmcppdap/CMakeLists.txt
@@ -41,4 +41,4 @@
   target_precompile_headers(cmcppdap PRIVATE "include/dap/protocol.h")
 endif()
 
-install(FILES NOTICE DESTINATION ${CMAKE_DOC_DIR}/cmcppdap)
+install(FILES NOTICE DESTINATION ${CMake_INSTALL_DOC_DIR}/cmcppdap)
diff --git a/Utilities/cmcurl/CMakeLists.txt b/Utilities/cmcurl/CMakeLists.txt
index 63d3a4f..44b749b 100644
--- a/Utilities/cmcurl/CMakeLists.txt
+++ b/Utilities/cmcurl/CMakeLists.txt
@@ -2261,7 +2261,7 @@
   add_test(curl curltest ${CMAKE_CURL_TEST_URL})
 endif()
 
-install(FILES COPYING DESTINATION ${CMAKE_DOC_DIR}/cmcurl)
+install(FILES COPYING DESTINATION ${CMake_INSTALL_DOC_DIR}/cmcurl)
 
 return() # The rest of this file is not needed for building within CMake.
 # XXX(cmake): end cmake-specific curl code
diff --git a/Utilities/cmlibarchive/CMakeLists.txt b/Utilities/cmlibarchive/CMakeLists.txt
index 9957052..3c99360 100644
--- a/Utilities/cmlibarchive/CMakeLists.txt
+++ b/Utilities/cmlibarchive/CMakeLists.txt
@@ -5,6 +5,11 @@
 
 PROJECT(libarchive C)
 #
+if(0) # XXX(cmake): not needed for build within cmake
+# Include standard installation directories
+include(GNUInstallDirs)
+endif() # XXX(cmake): end
+#
 SET(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/build/cmake")
 if(NOT CMAKE_RUNTIME_OUTPUT_DIRECTORY)
   set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${libarchive_BINARY_DIR}/bin)
@@ -282,6 +287,10 @@
 OPTION(ENABLE_COVERAGE "Enable code coverage (GCC only, automatically sets ENABLE_TEST to ON)" FALSE)
 OPTION(ENABLE_INSTALL "Enable installing of libraries" ON)
 
+IF(WIN32 AND MSVC)
+  OPTION(MSVC_USE_STATIC_CRT "Use static CRT" OFF)
+ENDIF()
+
 SET(POSIX_REGEX_LIB "AUTO" CACHE STRING "Choose what library should provide POSIX regular expression support")
 SET(ENABLE_SAFESEH "AUTO" CACHE STRING "Enable use of /SAFESEH linker flag (MSVC only)")
 SET(WINDOWS_VERSION "WIN10" CACHE STRING "Set Windows version to use (Windows only)")
@@ -1502,6 +1511,8 @@
 CHECK_FUNCTION_EXISTS_GLIBC(chflags HAVE_CHFLAGS)
 CHECK_FUNCTION_EXISTS_GLIBC(chown HAVE_CHOWN)
 CHECK_FUNCTION_EXISTS_GLIBC(chroot HAVE_CHROOT)
+CHECK_FUNCTION_EXISTS_GLIBC(closefrom HAVE_CLOSEFROM)
+CHECK_FUNCTION_EXISTS_GLIBC(close_range HAVE_CLOSE_RANGE)
 CHECK_FUNCTION_EXISTS_GLIBC(ctime_r HAVE_CTIME_R)
 CHECK_FUNCTION_EXISTS_GLIBC(fchdir HAVE_FCHDIR)
 CHECK_FUNCTION_EXISTS_GLIBC(fchflags HAVE_FCHFLAGS)
@@ -1519,15 +1530,19 @@
 CHECK_FUNCTION_EXISTS_GLIBC(futimens HAVE_FUTIMENS)
 CHECK_FUNCTION_EXISTS_GLIBC(futimes HAVE_FUTIMES)
 CHECK_FUNCTION_EXISTS_GLIBC(futimesat HAVE_FUTIMESAT)
+CHECK_FUNCTION_EXISTS_GLIBC(getegid HAVE_GETEGID)
 CHECK_FUNCTION_EXISTS_GLIBC(geteuid HAVE_GETEUID)
 CHECK_FUNCTION_EXISTS_GLIBC(getgrgid_r HAVE_GETGRGID_R)
 CHECK_FUNCTION_EXISTS_GLIBC(getgrnam_r HAVE_GETGRNAM_R)
 CHECK_FUNCTION_EXISTS_GLIBC(getline HAVE_GETLINE)
+CHECK_FUNCTION_EXISTS_GLIBC(getpid HAVE_GETPID)
 CHECK_FUNCTION_EXISTS_GLIBC(getpwnam_r HAVE_GETPWNAM_R)
 CHECK_FUNCTION_EXISTS_GLIBC(getpwuid_r HAVE_GETPWUID_R)
-CHECK_FUNCTION_EXISTS_GLIBC(getpid HAVE_GETPID)
+CHECK_FUNCTION_EXISTS_GLIBC(getresgid HAVE_GETRESGID)
+CHECK_FUNCTION_EXISTS_GLIBC(getresuid HAVE_GETRESUID)
 CHECK_FUNCTION_EXISTS_GLIBC(getvfsbyname HAVE_GETVFSBYNAME)
 CHECK_FUNCTION_EXISTS_GLIBC(gmtime_r HAVE_GMTIME_R)
+CHECK_FUNCTION_EXISTS_GLIBC(issetugid HAVE_ISSETUGID)
 CHECK_FUNCTION_EXISTS_GLIBC(lchflags HAVE_LCHFLAGS)
 if(NOT CMAKE_C_COMPILER_ID STREQUAL "LCC" OR NOT CMAKE_C_COMPILER_VERSION VERSION_LESS_EQUAL "1.23")
   CHECK_FUNCTION_EXISTS_GLIBC(lchmod HAVE_LCHMOD)
@@ -1611,12 +1626,6 @@
   "#include <sys/types.h>\n#include <sys/mount.h>\nint main(void) { struct statfs s; return sizeof(s);}"
   HAVE_STRUCT_STATFS)
 
-# Make sure we have the POSIX version of readdir_r, not the
-# older 2-argument version.
-CHECK_C_SOURCE_COMPILES(
-  "#include <dirent.h>\nint main() {DIR *d = opendir(\".\"); struct dirent e,*r; return readdir_r(d,&e,&r);}"
-  HAVE_READDIR_R)
-
 # dirfd can be either a function or a macro.
 CHECK_C_SOURCE_COMPILES(
   "#include <dirent.h>\nint main() {DIR *d = opendir(\".\"); return dirfd(d);}"
@@ -2218,4 +2227,4 @@
 add_subdirectory(unzip)
 ENDIF()
 
-install(FILES COPYING DESTINATION ${CMAKE_DOC_DIR}/cmlibarchive)
+install(FILES COPYING DESTINATION ${CMake_INSTALL_DOC_DIR}/cmlibarchive)
diff --git a/Utilities/cmlibarchive/build/cmake/config.h.in b/Utilities/cmlibarchive/build/cmake/config.h.in
index 6bc5930..9530dd8 100644
--- a/Utilities/cmlibarchive/build/cmake/config.h.in
+++ b/Utilities/cmlibarchive/build/cmake/config.h.in
@@ -236,6 +236,12 @@
 /* Define to 1 if you have the `chroot' function. */
 #cmakedefine HAVE_CHROOT 1
 
+/* Define to 1 if you have the `closefrom' function. */
+#cmakedefine HAVE_CLOSEFROM 1
+
+/* Define to 1 if you have the `close_range' function. */
+#cmakedefine HAVE_CLOSE_RANGE 1
+
 /* Define to 1 if you have the <copyfile.h> header file. */
 #cmakedefine HAVE_COPYFILE_H 1
 
@@ -754,9 +760,6 @@
 /* Define to 1 if you have the <pwd.h> header file. */
 #cmakedefine HAVE_PWD_H 1
 
-/* Define to 1 if you have the `readdir_r' function. */
-#cmakedefine HAVE_READDIR_R 1
-
 /* Define to 1 if you have the `readlink' function. */
 #cmakedefine HAVE_READLINK 1
 
diff --git a/Utilities/cmlibarchive/build/version b/Utilities/cmlibarchive/build/version
index f08c8c4..4c388c3 100644
--- a/Utilities/cmlibarchive/build/version
+++ b/Utilities/cmlibarchive/build/version
@@ -1 +1 @@
-3008001
+3008002
diff --git a/Utilities/cmlibarchive/libarchive/CMakeLists.txt b/Utilities/cmlibarchive/libarchive/CMakeLists.txt
index 54b16d1..ec6a3f9 100644
--- a/Utilities/cmlibarchive/libarchive/CMakeLists.txt
+++ b/Utilities/cmlibarchive/libarchive/CMakeLists.txt
@@ -52,6 +52,7 @@
   archive_pathmatch.h
   archive_platform.h
   archive_platform_acl.h
+  archive_platform_stat.h
   archive_platform_xattr.h
   archive_ppmd_private.h
   archive_ppmd8.c
@@ -262,6 +263,9 @@
                         SOVERSION ${SOVERSION}
                         MACHO_COMPATIBILITY_VERSION ${MACHO_COMPATIBILITY_VERSION}
                         MACHO_CURRENT_VERSION ${MACHO_CURRENT_VERSION})
+  IF(WIN32 AND MSVC AND MSVC_USE_STATIC_CRT)
+    SET_PROPERTY(TARGET archive PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
+  ENDIF(WIN32 AND MSVC AND MSVC_USE_STATIC_CRT)
 ENDIF(BUILD_SHARED_LIBS)
 
 # archive_static is a static library
@@ -270,15 +274,14 @@
 TARGET_LINK_LIBRARIES(archive_static ${ADDITIONAL_LIBS})
 SET_TARGET_PROPERTIES(archive_static PROPERTIES COMPILE_DEFINITIONS
   LIBARCHIVE_STATIC)
+IF(WIN32 AND MSVC AND MSVC_USE_STATIC_CRT)
+  SET_PROPERTY(TARGET archive_static PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
+ENDIF(WIN32 AND MSVC AND MSVC_USE_STATIC_CRT)
 # On Posix systems, libarchive.so and libarchive.a can co-exist.
 IF(NOT WIN32 OR CYGWIN OR NOT BUILD_SHARED_LIBS)
   SET_TARGET_PROPERTIES(archive_static PROPERTIES OUTPUT_NAME archive)
 ENDIF(NOT WIN32 OR CYGWIN OR NOT BUILD_SHARED_LIBS)
 
-if(NOT DEFINED CMAKE_INSTALL_LIBDIR)
-    set(CMAKE_INSTALL_LIBDIR "lib")
-endif()
-
 IF(ENABLE_INSTALL)
   # How to install the libraries
   IF(BUILD_SHARED_LIBS)
diff --git a/Utilities/cmlibarchive/libarchive/archive.h b/Utilities/cmlibarchive/libarchive/archive.h
index a8b4cff..1a89284 100644
--- a/Utilities/cmlibarchive/libarchive/archive.h
+++ b/Utilities/cmlibarchive/libarchive/archive.h
@@ -34,7 +34,7 @@
  * assert that ARCHIVE_VERSION_NUMBER >= 2012108.
  */
 /* Note: Compiler will complain if this does not match archive_entry.h! */
-#define	ARCHIVE_VERSION_NUMBER 3008001
+#define	ARCHIVE_VERSION_NUMBER 3008002
 
 #include <sys/stat.h>
 #include <stddef.h>  /* for wchar_t */
@@ -174,7 +174,7 @@
 /*
  * Textual name/version of the library, useful for version displays.
  */
-#define	ARCHIVE_VERSION_ONLY_STRING "3.8.1"
+#define	ARCHIVE_VERSION_ONLY_STRING "3.8.2"
 #define	ARCHIVE_VERSION_STRING "libarchive " ARCHIVE_VERSION_ONLY_STRING
 __LA_DECL const char *	archive_version_string(void);
 
diff --git a/Utilities/cmlibarchive/libarchive/archive_acl.c b/Utilities/cmlibarchive/libarchive/archive_acl.c
index 3124688..4ee8055 100644
--- a/Utilities/cmlibarchive/libarchive/archive_acl.c
+++ b/Utilities/cmlibarchive/libarchive/archive_acl.c
@@ -274,6 +274,19 @@
 {
 	struct archive_acl_entry *ap, *aq;
 
+	/* Reject an invalid type */
+	switch (type) {
+	case ARCHIVE_ENTRY_ACL_TYPE_ACCESS:
+	case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT:
+	case ARCHIVE_ENTRY_ACL_TYPE_ALLOW:
+	case ARCHIVE_ENTRY_ACL_TYPE_DENY:
+	case ARCHIVE_ENTRY_ACL_TYPE_AUDIT:
+	case ARCHIVE_ENTRY_ACL_TYPE_ALARM:
+		break;
+	default:
+		return (NULL);
+	}
+
 	/* Type argument must be a valid NFS4 or POSIX.1e type.
 	 * The type must agree with anything already set and
 	 * the permset must be compatible. */
@@ -826,6 +839,9 @@
 		wname = NULL;
 		id = -1;
 		break;
+	default:
+		**wp = '\0';
+		break;
 	}
 	*wp += wcslen(*wp);
 	*(*wp)++ = L':';
@@ -882,6 +898,7 @@
 			wcscpy(*wp, L"alarm");
 			break;
 		default:
+			*(*wp) = L'\0';
 			break;
 		}
 		*wp += wcslen(*wp);
@@ -1061,6 +1078,9 @@
 		name = NULL;
 		id = -1;
 		break;
+	default:
+		**p = '\0';
+		break;
 	}
 	*p += strlen(*p);
 	*(*p)++ = ':';
@@ -1116,6 +1136,9 @@
 		case ARCHIVE_ENTRY_ACL_TYPE_ALARM:
 			strcpy(*p, "alarm");
 			break;
+		default:
+			*(*p) = '\0';
+			break;
 		}
 		*p += strlen(*p);
 	}
diff --git a/Utilities/cmlibarchive/libarchive/archive_check_magic.c b/Utilities/cmlibarchive/libarchive/archive_check_magic.c
index d12f0c4..6b8e0c5 100644
--- a/Utilities/cmlibarchive/libarchive/archive_check_magic.c
+++ b/Utilities/cmlibarchive/libarchive/archive_check_magic.c
@@ -30,6 +30,7 @@
 #endif
 
 #include <stdio.h>
+#include <errno.h>
 #ifdef HAVE_STDLIB_H
 #include <stdlib.h>
 #endif
@@ -54,8 +55,14 @@
 
 	while (s > 0) {
 		written = write(2, m, s);
-		if (written <= 0)
+		if (written == 0)
 			return;
+		if (written < 0)
+		{
+			if (errno == EINTR)
+				continue;
+			return;
+		}
 		m += written;
 		s -= written;
 	}
diff --git a/Utilities/cmlibarchive/libarchive/archive_cryptor.c b/Utilities/cmlibarchive/libarchive/archive_cryptor.c
index 1825af4..9f03f9c 100644
--- a/Utilities/cmlibarchive/libarchive/archive_cryptor.c
+++ b/Utilities/cmlibarchive/libarchive/archive_cryptor.c
@@ -151,7 +151,7 @@
 	(void)rounds; /* UNUSED */
 	(void)derived_key; /* UNUSED */
 	(void)derived_key_len; /* UNUSED */
-	return -1; /* UNSUPPORTED */
+	return CRYPTOR_STUB_FUNCTION; /* UNSUPPORTED */
 }
 
 #endif
@@ -439,14 +439,14 @@
 	(void)ctx; /* UNUSED */
 	(void)key; /* UNUSED */
 	(void)key_len; /* UNUSED */
-	return -1;
+	return CRYPTOR_STUB_FUNCTION;
 }
 
 static int
 aes_ctr_encrypt_counter(archive_crypto_ctx *ctx)
 {
 	(void)ctx; /* UNUSED */
-	return -1;
+	return CRYPTOR_STUB_FUNCTION;
 }
 
 static int
@@ -469,7 +469,7 @@
 	(void)out; /* UNUSED */
 	(void)out_len; /* UNUSED */
 	aes_ctr_encrypt_counter(ctx); /* UNUSED */ /* Fix unused function warning */
-	return -1;
+	return CRYPTOR_STUB_FUNCTION;
 }
 
 #else
diff --git a/Utilities/cmlibarchive/libarchive/archive_cryptor_private.h b/Utilities/cmlibarchive/libarchive/archive_cryptor_private.h
index 4b3c6c1..1dbc5c1 100644
--- a/Utilities/cmlibarchive/libarchive/archive_cryptor_private.h
+++ b/Utilities/cmlibarchive/libarchive/archive_cryptor_private.h
@@ -43,7 +43,7 @@
 #ifdef __APPLE__
 # include <AvailabilityMacros.h>
 # if MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
-#  define ARCHIVE_CRYPTOR_USE_Apple_CommonCrypto
+#  define ARCHIVE_CRYPTOR_USE_Apple_CommonCrypto 1
 # endif
 #endif
 
@@ -144,9 +144,15 @@
 
 #else
 
+#if defined(ARCHIVE_CRYPTO_MD5_WIN)    ||\
+	defined(ARCHIVE_CRYPTO_SHA1_WIN)   ||\
+	defined(ARCHIVE_CRYPTO_SHA256_WIN) ||\
+	defined(ARCHIVE_CRYPTO_SHA384_WIN) ||\
+	defined(ARCHIVE_CRYPTO_SHA512_WIN)
 #if defined(_WIN32) && !defined(__CYGWIN__) && !(defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA)
 #define ARCHIVE_CRYPTOR_USE_WINCRYPT 1
 #endif
+#endif
 
 #define AES_BLOCK_SIZE	16
 #define AES_MAX_KEY_SIZE 32
@@ -172,6 +178,9 @@
 #define archive_encrypto_aes_ctr_release(ctx) \
   __archive_cryptor.encrypto_aes_ctr_release(ctx)
 
+/* Stub return value if no encryption support exists. */
+#define CRYPTOR_STUB_FUNCTION	-2
+
 /* Minimal interface to cryptographic functionality for internal use in
  * libarchive */
 struct archive_cryptor
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry.h b/Utilities/cmlibarchive/libarchive/archive_entry.h
index f71a66a..d58f540 100644
--- a/Utilities/cmlibarchive/libarchive/archive_entry.h
+++ b/Utilities/cmlibarchive/libarchive/archive_entry.h
@@ -28,7 +28,7 @@
 #define	ARCHIVE_ENTRY_H_INCLUDED
 
 /* Note: Compiler will complain if this does not match archive.h! */
-#define	ARCHIVE_VERSION_NUMBER 3008001
+#define	ARCHIVE_VERSION_NUMBER 3008002
 
 /*
  * Note: archive_entry.h is for use outside of libarchive; the
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry_paths.3 b/Utilities/cmlibarchive/libarchive/archive_entry_paths.3
index 0f849c9..f739b17 100644
--- a/Utilities/cmlibarchive/libarchive/archive_entry_paths.3
+++ b/Utilities/cmlibarchive/libarchive/archive_entry_paths.3
@@ -64,7 +64,7 @@
 .Ft void
 .Fn archive_entry_copy_hardlink "struct archive_entry *a" "const char *path"
 .Ft void
-.Fn archive_entry_copy_hardlink_w "struct archive_entry *a "const wchar_t *path"
+.Fn archive_entry_copy_hardlink_w "struct archive_entry *a" "const wchar_t *path"
 .Ft int
 .Fn archive_entry_update_hardlink_utf8 "struct archive_entry *a" "const char *path"
 .Ft void
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry_stat.c b/Utilities/cmlibarchive/libarchive/archive_entry_stat.c
index c490683..345d3d2 100644
--- a/Utilities/cmlibarchive/libarchive/archive_entry_stat.c
+++ b/Utilities/cmlibarchive/libarchive/archive_entry_stat.c
@@ -38,6 +38,7 @@
 const struct stat *
 archive_entry_stat(struct archive_entry *entry)
 {
+	int64_t size;
 	struct stat *st;
 	if (entry->stat == NULL) {
 		entry->stat = calloc(1, sizeof(*st));
@@ -74,7 +75,10 @@
 	st->st_ino = (ino_t)archive_entry_ino64(entry);
 	st->st_nlink = archive_entry_nlink(entry);
 	st->st_rdev = archive_entry_rdev(entry);
-	st->st_size = (off_t)archive_entry_size(entry);
+	size = archive_entry_size(entry);
+	st->st_size = (off_t)size;
+	if (st->st_size < 0 || (int64_t)st->st_size != size)
+		st->st_size = 0;
 	st->st_mode = archive_entry_mode(entry);
 
 	/*
diff --git a/Utilities/cmlibarchive/libarchive/archive_platform.h b/Utilities/cmlibarchive/libarchive/archive_platform.h
index 625d2e7..711671f 100644
--- a/Utilities/cmlibarchive/libarchive/archive_platform.h
+++ b/Utilities/cmlibarchive/libarchive/archive_platform.h
@@ -176,16 +176,6 @@
 #define	CAN_RESTORE_METADATA_FD
 #endif
 
-/*
- * glibc 2.24 deprecates readdir_r
- * bionic c deprecates readdir_r too
- */
-#if defined(HAVE_READDIR_R) && (!defined(__GLIBC__) || !defined(__GLIBC_MINOR__) || __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 24)) && (!defined(__ANDROID__))
-#define	USE_READDIR_R	1
-#else
-#undef	USE_READDIR_R
-#endif
-
 /* Set up defaults for internal error codes. */
 #ifndef ARCHIVE_ERRNO_FILE_FORMAT
 #if HAVE_EFTYPE
diff --git a/Utilities/cmlibarchive/libarchive/archive_platform_stat.h b/Utilities/cmlibarchive/libarchive/archive_platform_stat.h
new file mode 100644
index 0000000..5432b2f
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_platform_stat.h
@@ -0,0 +1,45 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2025 Tobias Stoeckmann
+ * All rights reserved.
+ */
+
+/* !!ONLY FOR USE INTERNALLY TO LIBARCHIVE!! */
+
+#ifndef ARCHIVE_PLATFORM_STAT_H_INCLUDED
+#define ARCHIVE_PLATFORM_STAT_H_INCLUDED
+
+#ifndef __LIBARCHIVE_BUILD
+#error This header is only to be used internally to libarchive.
+#endif
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+/* We use _lseeki64() on Windows. */
+typedef int64_t la_seek_t;
+
+struct la_seek_stat {
+	int64_t		st_mtime;
+	ino_t		st_ino;
+	unsigned short	st_mode;
+	uint32_t	st_nlink;
+	gid_t		st_gid;
+	la_seek_t	st_size;
+	uid_t		st_uid;
+	dev_t		st_dev;
+	dev_t		st_rdev;
+};
+typedef struct la_seek_stat la_seek_stat_t;
+
+#define la_seek_fstat(fd, st)	__la_seek_fstat((fd), (st))
+#define la_seek_stat(fd, st)	__la_seek_stat((fd), (st))
+
+#else
+typedef off_t la_seek_t;
+typedef struct stat la_seek_stat_t;
+
+#define la_seek_fstat(fd, st)	fstat((fd), (st))
+#define la_seek_stat(fd, st)	stat((fd), (st))
+#endif
+
+#endif	/* !ARCHIVE_PLATFORM_STAT_H_INCLUDED */
diff --git a/Utilities/cmlibarchive/libarchive/archive_private.h b/Utilities/cmlibarchive/libarchive/archive_private.h
index 050fc63..3a926c6 100644
--- a/Utilities/cmlibarchive/libarchive/archive_private.h
+++ b/Utilities/cmlibarchive/libarchive/archive_private.h
@@ -158,6 +158,7 @@
 __LA_NORETURN void	__archive_errx(int retvalue, const char *msg);
 
 void	__archive_ensure_cloexec_flag(int fd);
+int	__archive_get_tempdir(struct archive_string *);
 int	__archive_mktemp(const char *tmpdir);
 #if defined(_WIN32) && !defined(__CYGWIN__)
 int	__archive_mkstemp(wchar_t *templates);
diff --git a/Utilities/cmlibarchive/libarchive/archive_read.c b/Utilities/cmlibarchive/libarchive/archive_read.c
index 50db870..c9b9d59 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read.c
@@ -575,8 +575,7 @@
 			return (ARCHIVE_OK);
 		}
 
-		filter
-		    = calloc(1, sizeof(*filter));
+		filter = calloc(1, sizeof(*filter));
 		if (filter == NULL)
 			return (ARCHIVE_FATAL);
 		filter->bidder = best_bidder;
@@ -834,7 +833,9 @@
 			r = archive_read_data_block(a, &read_buf,
 			    &a->read_data_remaining, &a->read_data_offset);
 			a->read_data_block = read_buf;
-			if (r == ARCHIVE_EOF)
+			if (r == ARCHIVE_EOF &&
+			    a->read_data_offset == a->read_data_output_offset &&
+			    a->read_data_remaining == 0)
 				return (bytes_read);
 			/*
 			 * Error codes are all negative, so the status
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_disk_entry_from_file.c b/Utilities/cmlibarchive/libarchive/archive_read_disk_entry_from_file.c
index 19d0497..42af403 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_disk_entry_from_file.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_disk_entry_from_file.c
@@ -338,7 +338,7 @@
 	int ret = ARCHIVE_OK;
 	void *buff = NULL;
 	int have_attrs;
-	const char *name, *tempdir;
+	const char *name;
 	struct archive_string tempfile;
 
 	(void)fd; /* UNUSED */
@@ -357,13 +357,11 @@
 	if (have_attrs == 0)
 		return (ARCHIVE_OK);
 
-	tempdir = NULL;
-	if (issetugid() == 0)
-		tempdir = getenv("TMPDIR");
-	if (tempdir == NULL)
-		tempdir = _PATH_TMP;
 	archive_string_init(&tempfile);
-	archive_strcpy(&tempfile, tempdir);
+	if (__archive_get_tempdir(&tempfile) != ARCHIVE_OK) {
+		ret = ARCHIVE_WARN;
+		goto cleanup;
+	}
 	archive_strcat(&tempfile, "tar.md.XXXXXX");
 	tempfd = mkstemp(tempfile.s);
 	if (tempfd < 0) {
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_disk_posix.c b/Utilities/cmlibarchive/libarchive/archive_read_disk_posix.c
index f8e234c..12c8225 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_disk_posix.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_disk_posix.c
@@ -172,9 +172,6 @@
 	int		synthetic;
 	int		remote;
 	int		noatime;
-#if defined(USE_READDIR_R)
-	size_t		name_max;
-#endif
 	long		incr_xfer_size;
 	long		max_xfer_size;
 	long		min_xfer_size;
@@ -207,10 +204,6 @@
 	DIR			*d;
 #define	INVALID_DIR_HANDLE NULL
 	struct dirent		*de;
-#if defined(USE_READDIR_R)
-	struct dirent		*dirent;
-	size_t			 dirent_allocated;
-#endif
 	int			 flags;
 	int			 visit_type;
 	/* Error code from last failed operation. */
@@ -877,7 +870,7 @@
 			tree_enter_initial_dir(t);
 			return (ARCHIVE_FATAL);
 		case TREE_ERROR_DIR:
-			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+			archive_set_error(&a->archive, t->tree_errno,
 			    "%s: Couldn't visit directory",
 			    tree_current_path(t));
 			tree_enter_initial_dir(t);
@@ -1586,9 +1579,6 @@
 #  endif
 #endif
 	int r, xr = 0;
-#if !defined(HAVE_STRUCT_STATFS_F_NAMEMAX)
-	long nm;
-#endif
 
 	t->current_filesystem->synthetic = -1;
 	t->current_filesystem->remote = -1;
@@ -1655,35 +1645,6 @@
 #endif
 		t->current_filesystem->noatime = 0;
 
-#if defined(USE_READDIR_R)
-	/* Set maximum filename length. */
-#if defined(HAVE_STRUCT_STATFS_F_NAMEMAX)
-	t->current_filesystem->name_max = sfs.f_namemax;
-#else
-# if defined(_PC_NAME_MAX)
-	/* Mac OS X does not have f_namemax in struct statfs. */
-	if (tree_current_is_symblic_link_target(t)) {
-		if (tree_enter_working_dir(t) != 0) {
-			archive_set_error(&a->archive, errno, "fchdir failed");
-			return (ARCHIVE_FAILED);
-		}
-		nm = pathconf(tree_current_access_path(t), _PC_NAME_MAX);
-	} else
-		nm = fpathconf(tree_current_dir_fd(t), _PC_NAME_MAX);
-# else
-	nm = -1;
-# endif
-	if (nm == -1)
-		t->current_filesystem->name_max = NAME_MAX;
-	else
-		t->current_filesystem->name_max = nm;
-#endif
-	if (t->current_filesystem->name_max == 0) {
-		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
-		    "Cannot determine name_max");
-		return (ARCHIVE_FAILED);
-	}
-#endif /* USE_READDIR_R */
 	return (ARCHIVE_OK);
 }
 
@@ -1871,19 +1832,6 @@
 #endif
 		t->current_filesystem->noatime = 0;
 
-#if defined(USE_READDIR_R)
-	/* Set maximum filename length. */
-#if defined(HAVE_STATVFS)
-	t->current_filesystem->name_max = svfs.f_namemax;
-#else
-	t->current_filesystem->name_max = sfs.f_namelen;
-#endif
-	if (t->current_filesystem->name_max == 0) {
-		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
-		    "Cannot determine name_max");
-		return (ARCHIVE_FAILED);
-	}
-#endif
 	return (ARCHIVE_OK);
 }
 
@@ -1961,15 +1909,6 @@
 #endif
 		t->current_filesystem->noatime = 0;
 
-#if defined(USE_READDIR_R)
-	/* Set maximum filename length. */
-	t->current_filesystem->name_max = svfs.f_namemax;
-	if (t->current_filesystem->name_max == 0) {
-		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
-		    "Cannot determine name_max");
-		return (ARCHIVE_FAILED);
-	}
-#endif
 	return (ARCHIVE_OK);
 }
 
@@ -1983,9 +1922,6 @@
 setup_current_filesystem(struct archive_read_disk *a)
 {
 	struct tree *t = a->tree;
-#if defined(_PC_NAME_MAX) && defined(USE_READDIR_R)
-	long nm;
-#endif
 	t->current_filesystem->synthetic = -1;/* Not supported */
 	t->current_filesystem->remote = -1;/* Not supported */
 	t->current_filesystem->noatime = 0;
@@ -1995,40 +1931,6 @@
 	t->current_filesystem->min_xfer_size = -1;
 	t->current_filesystem->incr_xfer_size = -1;
 
-#if defined(USE_READDIR_R)
-	/* Set maximum filename length. */
-#  if defined(_PC_NAME_MAX)
-	if (tree_current_is_symblic_link_target(t)) {
-		if (tree_enter_working_dir(t) != 0) {
-			archive_set_error(&a->archive, errno, "fchdir failed");
-			return (ARCHIVE_FAILED);
-		}
-		nm = pathconf(tree_current_access_path(t), _PC_NAME_MAX);
-	} else
-		nm = fpathconf(tree_current_dir_fd(t), _PC_NAME_MAX);
-	if (nm == -1)
-#  endif /* _PC_NAME_MAX */
-		/*
-		 * Some systems (HP-UX or others?) incorrectly defined
-		 * NAME_MAX macro to be a smaller value.
-		 */
-#  if defined(NAME_MAX) && NAME_MAX >= 255
-		t->current_filesystem->name_max = NAME_MAX;
-#  else
-		/* No way to get a trusted value of maximum filename
-		 * length. */
-		t->current_filesystem->name_max = PATH_MAX;
-#  endif /* NAME_MAX */
-#  if defined(_PC_NAME_MAX)
-	else
-		t->current_filesystem->name_max = nm;
-#  endif /* _PC_NAME_MAX */
-	if (t->current_filesystem->name_max == 0) {
-		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
-		    "Cannot determine name_max");
-		return (ARCHIVE_FAILED);
-	}
-#endif /* USE_READDIR_R */
 	return (ARCHIVE_OK);
 }
 
@@ -2120,8 +2022,11 @@
 	}
 #endif /* F_DUPFD_CLOEXEC */
 	new_fd = dup(fd);
-	__archive_ensure_cloexec_flag(new_fd);
-	return (new_fd);
+	if (new_fd != -1) {
+		__archive_ensure_cloexec_flag(new_fd);
+		return (new_fd);
+	}
+	return (-1);
 }
 
 /*
@@ -2243,11 +2148,16 @@
 	 * so try again for execute. The consequences of not opening this are
 	 * unhelpful and unnecessary errors later.
 	 */
-	if (t->initial_dir_fd < 0)
+	if (t->initial_dir_fd < 0) {
 		t->initial_dir_fd = open(".", o_flag | O_CLOEXEC);
+		if (t->initial_dir_fd < 0)
+			return NULL;
+	}
 #endif
 	__archive_ensure_cloexec_flag(t->initial_dir_fd);
 	t->working_dir_fd = tree_dup(t->initial_dir_fd);
+	if (t->working_dir_fd < 0)
+		return NULL;
 	return (t);
 }
 
@@ -2460,12 +2370,11 @@
 	size_t namelen;
 
 	if (t->d == NULL) {
-#if defined(USE_READDIR_R)
-		size_t dirent_size;
-#endif
 
 #if defined(HAVE_FDOPENDIR)
-		t->d = fdopendir(tree_dup(t->working_dir_fd));
+		int fd = tree_dup(t->working_dir_fd);
+		if (fd != -1)
+			t->d = fdopendir(fd);
 #else /* HAVE_FDOPENDIR */
 		if (tree_enter_working_dir(t) == 0) {
 			t->d = opendir(".");
@@ -2481,45 +2390,12 @@
 			t->visit_type = r != 0 ? r : TREE_ERROR_DIR;
 			return (t->visit_type);
 		}
-#if defined(USE_READDIR_R)
-		dirent_size = offsetof(struct dirent, d_name) +
-		  t->filesystem_table[t->current->filesystem_id].name_max + 1;
-		if (t->dirent == NULL || t->dirent_allocated < dirent_size) {
-			free(t->dirent);
-			t->dirent = malloc(dirent_size);
-			if (t->dirent == NULL) {
-				closedir(t->d);
-				t->d = INVALID_DIR_HANDLE;
-				(void)tree_ascend(t);
-				tree_pop(t);
-				t->tree_errno = ENOMEM;
-				t->visit_type = TREE_ERROR_DIR;
-				return (t->visit_type);
-			}
-			t->dirent_allocated = dirent_size;
-		}
-#endif /* USE_READDIR_R */
 	}
 	for (;;) {
 		errno = 0;
-#if defined(USE_READDIR_R)
-		r = readdir_r(t->d, t->dirent, &t->de);
-#ifdef _AIX
-		/* Note: According to the man page, return value 9 indicates
-		 * that the readdir_r was not successful and the error code
-		 * is set to the global errno variable. And then if the end
-		 * of directory entries was reached, the return value is 9
-		 * and the third parameter is set to NULL and errno is
-		 * unchanged. */
-		if (r == 9)
-			r = errno;
-#endif /* _AIX */
-		if (r != 0 || t->de == NULL) {
-#else
 		t->de = readdir(t->d);
 		if (t->de == NULL) {
 			r = errno;
-#endif
 			closedir(t->d);
 			t->d = INVALID_DIR_HANDLE;
 			if (r != 0) {
@@ -2758,9 +2634,6 @@
 	if (t == NULL)
 		return;
 	archive_string_free(&t->path);
-#if defined(USE_READDIR_R)
-	free(t->dirent);
-#endif
 	free(t->sparse_list);
 	for (i = 0; i < t->max_filesystem_id; i++)
 		free(t->filesystem_table[i].allocation_ptr);
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_open_fd.c b/Utilities/cmlibarchive/libarchive/archive_read_open_fd.c
index dc7c9e5..c85a62a 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_open_fd.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_open_fd.c
@@ -48,6 +48,7 @@
 #endif
 
 #include "archive.h"
+#include "archive_platform_stat.h"
 
 struct read_fd_data {
 	int	 fd;
@@ -65,12 +66,12 @@
 int
 archive_read_open_fd(struct archive *a, int fd, size_t block_size)
 {
-	struct stat st;
+	la_seek_stat_t st;
 	struct read_fd_data *mine;
 	void *b;
 
 	archive_clear_error(a);
-	if (fstat(fd, &st) != 0) {
+	if (la_seek_fstat(fd, &st) != 0) {
 		archive_set_error(a, errno, "Can't stat fd %d", fd);
 		return (ARCHIVE_FATAL);
 	}
@@ -133,7 +134,7 @@
 file_skip(struct archive *a, void *client_data, int64_t request)
 {
 	struct read_fd_data *mine = (struct read_fd_data *)client_data;
-	off_t skip = (off_t)request;
+	la_seek_t skip = (la_seek_t)request;
 	int64_t old_offset, new_offset;
 	int skip_bits = sizeof(skip) * 8 - 1;  /* off_t is a signed type. */
 
@@ -149,7 +150,8 @@
 	}
 
 	/* Reduce 'skip' to the next smallest multiple of block_size */
-	skip = (off_t)(((int64_t)skip / mine->block_size) * mine->block_size);
+	skip = (la_seek_t)(((int64_t)skip / mine->block_size) * mine->block_size);
+
 	if (skip == 0)
 		return (0);
 
@@ -185,27 +187,28 @@
 file_seek(struct archive *a, void *client_data, int64_t request, int whence)
 {
 	struct read_fd_data *mine = (struct read_fd_data *)client_data;
-	off_t seek = (off_t)request;
+	la_seek_t seek = (la_seek_t)request;
 	int64_t r;
 	int seek_bits = sizeof(seek) * 8 - 1;  /* off_t is a signed type. */
 
 	/* We use off_t here because lseek() is declared that way. */
 
-	/* Reduce a request that would overflow the 'seek' variable. */
+	/* Do not perform a seek which cannot be fulfilled. */
 	if (sizeof(request) > sizeof(seek)) {
 		const int64_t max_seek =
 		    (((int64_t)1 << (seek_bits - 1)) - 1) * 2 + 1;
 		const int64_t min_seek = ~max_seek;
-		if (request > max_seek)
-			seek = (off_t)max_seek;
-		else if (request < min_seek)
-			seek = (off_t)min_seek;
+		if (request < min_seek || request > max_seek) {
+			errno = EOVERFLOW;
+			goto err;
+		}
 	}
 
 	r = lseek(mine->fd, seek, whence);
 	if (r >= 0)
 		return r;
 
+err:
 	if (errno == ESPIPE) {
 		archive_set_error(a, errno,
 		    "A file descriptor(%d) is not seekable(PIPE)", mine->fd);
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_open_file.c b/Utilities/cmlibarchive/libarchive/archive_read_open_file.c
index ede2b4b..ba63969 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_open_file.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_open_file.c
@@ -48,6 +48,7 @@
 #endif
 
 #include "archive.h"
+#include "archive_platform_stat.h"
 
 struct read_FILE_data {
 	FILE    *f;
@@ -65,7 +66,7 @@
 int
 archive_read_open_FILE(struct archive *a, FILE *f)
 {
-	struct stat st;
+	la_seek_stat_t st;
 	struct read_FILE_data *mine;
 	size_t block_size = 128 * 1024;
 	void *b;
@@ -88,7 +89,7 @@
 	 * streams that don't support fileno()).  As a result, fileno()
 	 * should be used cautiously.)
 	 */
-	if (fstat(fileno(mine->f), &st) == 0 && S_ISREG(st.st_mode)) {
+	if (la_seek_fstat(fileno(mine->f), &st) == 0 && S_ISREG(st.st_mode)) {
 		archive_read_extract_set_skip_file(a, st.st_dev, st.st_ino);
 		/* Enable the seek optimization only for regular files. */
 		mine->can_skip = 1;
@@ -205,15 +206,15 @@
 	int seek_bits = sizeof(seek) * 8 - 1;
 	(void)a; /* UNUSED */
 
-	/* Reduce a request that would overflow the 'seek' variable. */
+	/* Do not perform a seek which cannot be fulfilled. */
 	if (sizeof(request) > sizeof(seek)) {
 		const int64_t max_seek =
 		    (((int64_t)1 << (seek_bits - 1)) - 1) * 2 + 1;
 		const int64_t min_seek = ~max_seek;
-		if (request > max_seek)
-			seek = max_seek;
-		else if (request < min_seek)
-			seek = min_seek;
+		if (request < min_seek || request > max_seek) {
+			errno = EOVERFLOW;
+			goto err;
+		}
 	}
 
 #ifdef __ANDROID__
@@ -236,6 +237,7 @@
 	}
 #endif
 	/* If we arrive here, the input is corrupted or truncated so fail. */
+err:
 	archive_set_error(a, errno, "Error seeking in FILE* pointer");
 	return (ARCHIVE_FATAL);
 }
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_open_filename.c b/Utilities/cmlibarchive/libarchive/archive_read_open_filename.c
index 5f5b3f1..a910eef 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_open_filename.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_open_filename.c
@@ -59,6 +59,7 @@
 #endif
 
 #include "archive.h"
+#include "archive_platform_stat.h"
 #include "archive_private.h"
 #include "archive_string.h"
 
@@ -136,8 +137,10 @@
 			mine->filename_type = FNT_STDIN;
 		} else
 			mine->filename_type = FNT_MBS;
-		if (archive_read_append_callback_data(a, mine) != (ARCHIVE_OK))
+		if (archive_read_append_callback_data(a, mine) != (ARCHIVE_OK)) {
+			free(mine);
 			return (ARCHIVE_FATAL);
+		}
 		if (filenames == NULL)
 			break;
 		filename = *(filenames++);
@@ -216,8 +219,10 @@
 			archive_string_free(&fn);
 #endif
 		}
-		if (archive_read_append_callback_data(a, mine) != (ARCHIVE_OK))
+		if (archive_read_append_callback_data(a, mine) != (ARCHIVE_OK)) {
+			free(mine);
 			return (ARCHIVE_FATAL);
+		}
 		if (wfilenames == NULL)
 			break;
 		wfilename = *(wfilenames++);
@@ -248,7 +253,7 @@
 static int
 file_open(struct archive *a, void *client_data)
 {
-	struct stat st;
+	la_seek_stat_t st;
 	struct read_file_data *mine = (struct read_file_data *)client_data;
 	void *buffer;
 	const char *filename = NULL;
@@ -313,7 +318,7 @@
 		goto fail;
 #endif
 	}
-	if (fstat(fd, &st) != 0) {
+	if (la_seek_fstat(fd, &st) != 0) {
 #if defined(_WIN32) && !defined(__CYGWIN__)
 		if (mine->filename_type == FNT_WCS)
 			archive_set_error(a, errno, "Can't stat '%ls'",
@@ -482,10 +487,11 @@
 	struct read_file_data *mine = (struct read_file_data *)client_data;
 #if defined(_WIN32) && !defined(__CYGWIN__)
 	/* We use _lseeki64() on Windows. */
-	int64_t old_offset, new_offset, skip = request;
+	int64_t old_offset, new_offset;
 #else
-	off_t old_offset, new_offset, skip = (off_t)request;
+	off_t old_offset, new_offset;
 #endif
+	la_seek_t skip = (la_seek_t)request;
 	int skip_bits = sizeof(skip) * 8 - 1;
 
 	/* We use off_t here because lseek() is declared that way. */
@@ -552,21 +558,21 @@
 file_seek(struct archive *a, void *client_data, int64_t request, int whence)
 {
 	struct read_file_data *mine = (struct read_file_data *)client_data;
-	off_t seek = (off_t)request;
+	la_seek_t seek = (la_seek_t)request;
 	int64_t r;
 	int seek_bits = sizeof(seek) * 8 - 1;
 
 	/* We use off_t here because lseek() is declared that way. */
 
-	/* Reduce a request that would overflow the 'seek' variable. */
+	/* Do not perform a seek which cannot be fulfilled. */
 	if (sizeof(request) > sizeof(seek)) {
 		const int64_t max_seek =
 		    (((int64_t)1 << (seek_bits - 1)) - 1) * 2 + 1;
 		const int64_t min_seek = ~max_seek;
-		if (request > max_seek)
-			seek = (off_t)max_seek;
-		else if (request < min_seek)
-			seek = (off_t)min_seek;
+		if (request < min_seek || request > max_seek) {
+			errno = EOVERFLOW;
+			goto err;
+		}
 	}
 
 	r = lseek(mine->fd, seek, whence);
@@ -574,6 +580,7 @@
 		return r;
 
 	/* If the input is corrupted or truncated, fail. */
+err:
 	if (mine->filename_type == FNT_STDIN)
 		archive_set_error(a, errno, "Error seeking in stdin");
 	else if (mine->filename_type == FNT_MBS)
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_set_format.c b/Utilities/cmlibarchive/libarchive/archive_read_set_format.c
index c74361b..552ab12 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_set_format.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_set_format.c
@@ -37,7 +37,7 @@
 archive_read_set_format(struct archive *_a, int code)
 {
   int r1, r2, slots, i;
-  char str[10];
+  const char *str;
   struct archive_read *a = (struct archive_read *)_a;
 
   if ((r1 = archive_read_support_format_by_code(_a, code)) < (ARCHIVE_OK))
@@ -49,49 +49,49 @@
   switch (code & ARCHIVE_FORMAT_BASE_MASK)
   {
     case ARCHIVE_FORMAT_7ZIP:
-      strcpy(str, "7zip");
+      str = "7zip";
       break;
     case ARCHIVE_FORMAT_AR:
-      strcpy(str, "ar");
+      str = "ar";
       break;
     case ARCHIVE_FORMAT_CAB:
-      strcpy(str, "cab");
+      str = "cab";
       break;
     case ARCHIVE_FORMAT_CPIO:
-      strcpy(str, "cpio");
+      str = "cpio";
       break;
     case ARCHIVE_FORMAT_EMPTY:
-      strcpy(str, "empty");
+      str = "empty";
       break;
     case ARCHIVE_FORMAT_ISO9660:
-      strcpy(str, "iso9660");
+      str = "iso9660";
       break;
     case ARCHIVE_FORMAT_LHA:
-      strcpy(str, "lha");
+      str = "lha";
       break;
     case ARCHIVE_FORMAT_MTREE:
-      strcpy(str, "mtree");
+      str = "mtree";
       break;
     case ARCHIVE_FORMAT_RAR:
-      strcpy(str, "rar");
+      str = "rar";
       break;
     case ARCHIVE_FORMAT_RAR_V5:
-      strcpy(str, "rar5");
+      str = "rar5";
       break;
     case ARCHIVE_FORMAT_RAW:
-      strcpy(str, "raw");
+      str = "raw";
       break;
     case ARCHIVE_FORMAT_TAR:
-      strcpy(str, "tar");
+      str = "tar";
       break;
     case ARCHIVE_FORMAT_WARC:
-      strcpy(str, "warc");
+      str = "warc";
       break;
     case ARCHIVE_FORMAT_XAR:
-      strcpy(str, "xar");
+      str = "xar";
       break;
     case ARCHIVE_FORMAT_ZIP:
-      strcpy(str, "zip");
+      str = "zip";
       break;
     default:
       archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_program.c b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_program.c
index 9e82522..2c8e453 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_program.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_program.c
@@ -110,7 +110,7 @@
 	pid_t		 child;
 #endif
 	int		 exit_status;
-	int		 waitpid_return;
+	pid_t		 waitpid_return;
 	int		 child_stdin, child_stdout;
 
 	char		*out_buf;
@@ -242,16 +242,13 @@
 			state->waitpid_return
 			    = waitpid(state->child, &state->exit_status, 0);
 		} while (state->waitpid_return == -1 && errno == EINTR);
-#if defined(_WIN32) && !defined(__CYGWIN__)
-		CloseHandle(state->child);
-#endif
 		state->child = 0;
 	}
 
 	if (state->waitpid_return < 0) {
 		/* waitpid() failed?  This is ugly. */
 		archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC,
-		    "Child process exited badly");
+		    "Error closing child process");
 		return (ARCHIVE_WARN);
 	}
 
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_7zip.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_7zip.c
index e88e966..19c7333 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_7zip.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_7zip.c
@@ -84,7 +84,7 @@
 /*
  * ELF format
  */
-#define ELF_HDR_MIN_LEN 0x34
+#define ELF_HDR_MIN_LEN 0x3f
 #define ELF_HDR_EI_CLASS_OFFSET 0x04
 #define ELF_HDR_EI_DATA_OFFSET 0x05
 
@@ -815,6 +815,8 @@
 			strtab_size = (*dec32)(
 			    h + e_shstrndx * e_shentsize + 0x14);
 		}
+		if (strtab_size < 6 || strtab_size > SIZE_MAX)
+			break;
 
 		/*
 		 * Read the STRTAB section to find the .data offset
@@ -1398,7 +1400,8 @@
 		 * size to liblzma when using lzma_raw_decoder() liblzma
 		 * could correctly deal with BCJ+LZMA. But unfortunately
 		 * there is no way to do that.
-		 * Discussion about this can be found at XZ Utils forum.
+		 *
+		 * Reference: https://web.archive.org/web/20240405171610/https://www.mail-archive.com/xz-devel@tukaani.org/msg00373.html
 		 */
 		if (coder2 != NULL) {
 			zip->codec2 = coder2->codec;
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_mtree.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_mtree.c
index ba0e49d..ded13be 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_mtree.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_mtree.c
@@ -51,6 +51,7 @@
 #include "archive.h"
 #include "archive_entry.h"
 #include "archive_entry_private.h"
+#include "archive_platform_stat.h"
 #include "archive_private.h"
 #include "archive_rb.h"
 #include "archive_read_private.h"
@@ -1073,6 +1074,8 @@
 		/* Non-printable characters are not allowed */
 		for (s = p;s < p + len - 1; s++) {
 			if (!isprint((unsigned char)*s) && *s != '\t') {
+				archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+					"Non-printable character 0x%02X", (unsigned char)(*s));
 				r = ARCHIVE_FATAL;
 				break;
 			}
@@ -1175,7 +1178,7 @@
     struct mtree *mtree, struct mtree_entry *mentry, int *use_next)
 {
 	const char *path;
-	struct stat st_storage, *st;
+	la_seek_stat_t st_storage, *st;
 	struct mtree_entry *mp;
 	struct archive_entry *sparse_entry;
 	int r = ARCHIVE_OK, r1, parsed_kws;
@@ -1251,7 +1254,7 @@
 				archive_entry_filetype(entry) == AE_IFDIR) {
 			mtree->fd = open(path, O_RDONLY | O_BINARY | O_CLOEXEC);
 			__archive_ensure_cloexec_flag(mtree->fd);
-			if (mtree->fd == -1 && (
+			if (mtree->fd < 0 && (
 #if defined(_WIN32) && !defined(__CYGWIN__)
         /*
          * On Windows, attempting to open a file with an
@@ -1270,7 +1273,7 @@
 
 		st = &st_storage;
 		if (mtree->fd >= 0) {
-			if (fstat(mtree->fd, st) == -1) {
+			if (la_seek_fstat(mtree->fd, st) == -1) {
 				archive_set_error(&a->archive, errno,
 						"Could not fstat %s", path);
 				r = ARCHIVE_WARN;
@@ -1283,7 +1286,7 @@
 #ifdef HAVE_LSTAT
 		else if (lstat(path, st) == -1)
 #else
-		else if (la_stat(path, st) == -1)
+		else if (la_seek_stat(path, st) == -1)
 #endif
 		{
 			st = NULL;
@@ -2130,6 +2133,13 @@
 		for (u = mtree->line.s + find_off; *u; ++u) {
 			if (u[0] == '\n') {
 				/* Ends with unescaped newline. */
+				/* Check if preceded by '\r' for CRLF handling */
+				if (u > mtree->line.s && u[-1] == '\r') {
+					/* CRLF ending - remove the '\r' */
+					u[-1] = '\n';
+					u[0] = '\0';
+					total_size--;
+				}
 				*start = mtree->line.s;
 				return total_size;
 			} else if (u[0] == '#') {
@@ -2144,6 +2154,11 @@
 					total_size -= 2;
 					mtree->line.s[total_size] = '\0';
 					break;
+				} else if (u[1] == '\r' && u[2] == '\n') {
+					/* Trim escaped CRLF. */
+					total_size -= 3;
+					mtree->line.s[total_size] = '\0';
+					break;
 				} else if (u[1] != '\0') {
 					/* Skip the two-char escape sequence */
 					++u;
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_rar.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_rar.c
index 777cfad..c8792b9 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_rar.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_rar.c
@@ -1119,8 +1119,6 @@
   if (rar->entry_eof || rar->offset_seek >= rar->unp_size) {
     *size = 0;
     *offset = rar->offset;
-    if (*offset < rar->unp_size)
-      *offset = rar->unp_size;
     return (ARCHIVE_EOF);
   }
 
@@ -1457,7 +1455,7 @@
     return (ARCHIVE_FATAL);
 #endif
   }
-  /* If no CRC error, Go on parsing File Header. */
+  /* If no CRC error, go on parsing File Header. */
   p = h;
   endp = p + header_size - 7;
   memcpy(&file_header, p, sizeof(file_header));
@@ -2370,8 +2368,8 @@
         return (ARCHIVE_FATAL);
       }
 
-      /* Make sure ppmd7_contest is freed before Ppmd7_Construct
-       * because reading a broken file cause this abnormal sequence. */
+      /* Make sure ppmd7_context is freed before Ppmd7_Construct
+       * because reading a broken file causes this abnormal sequence. */
       __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context);
 
       rar->bytein.a = a;
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_rar5.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_rar5.c
index 595476f..f0e93ae 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_rar5.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_rar5.c
@@ -1619,10 +1619,13 @@
 {
 	uint64_t extra_field_size;
 	uint64_t extra_field_id = 0;
-	int ret = ARCHIVE_FATAL;
 	uint64_t var_size;
 
 	while(extra_data_size > 0) {
+		/* Make sure we won't fail if the file declares only unsupported
+		attributes. */
+		int ret = ARCHIVE_OK;
+
 		if(!read_var(a, &extra_field_size, &var_size))
 			return ARCHIVE_EOF;
 
@@ -1675,12 +1678,53 @@
 				if (ARCHIVE_OK != consume(a, extra_field_size)) {
 					return ARCHIVE_EOF;
 				}
+
+				/* Don't fail on unsupported attribute -- we've handled it
+				   by skipping over it. */
+				ret = ARCHIVE_OK;
+		}
+
+		if (ret != ARCHIVE_OK) {
+			/* Forward any errors signalled by the attribute parsing
+			   functions. */
+			return ret;
 		}
 	}
 
-	if(ret != ARCHIVE_OK) {
-		/* Attribute not implemented. */
-		return ret;
+	if (extra_data_size != 0) {
+		/* We didn't skip everything, or we skipped too much; either way,
+		   there's an error in this parsing function. */
+
+		archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
+				"unsupported structure of file header extra data");
+		return ARCHIVE_FATAL;
+	}
+
+	return ARCHIVE_OK;
+}
+
+static int file_entry_sanity_checks(struct archive_read* a,
+	size_t block_flags, uint8_t is_dir, uint64_t unpacked_size,
+	size_t packed_size)
+{
+	if (is_dir) {
+		const int declares_data_size =
+			(int) (unpacked_size != 0 || packed_size != 0);
+
+		/* FILE entries for directories still declare HFL_DATA in block flags,
+		   even though attaching data to such blocks doesn't make much sense. */
+		if (declares_data_size) {
+			archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+				"directory entries cannot have any data");
+			return ARCHIVE_FATAL;
+		}
+	} else {
+		const int declares_hfl_data = (int) ((block_flags & HFL_DATA) != 0);
+		if (!declares_hfl_data) {
+			archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+					"no data found in file/service block");
+			return ARCHIVE_FATAL;
+		}
 	}
 
 	return ARCHIVE_OK;
@@ -1701,6 +1745,7 @@
 	int c_method = 0, c_version = 0;
 	char name_utf8_buf[MAX_NAME_IN_BYTES];
 	const uint8_t* p;
+	int sanity_ret;
 
 	enum FILE_FLAGS {
 		DIRECTORY = 0x0001, UTIME = 0x0002, CRC32 = 0x0004,
@@ -1744,10 +1789,6 @@
 		rar->file.bytes_remaining = data_size;
 	} else {
 		rar->file.bytes_remaining = 0;
-
-		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
-				"no data found in file/service block");
-		return ARCHIVE_FATAL;
 	}
 
 	if(!read_var_sized(a, &file_flags, NULL))
@@ -1764,6 +1805,13 @@
 
 	rar->file.dir = (uint8_t) ((file_flags & DIRECTORY) > 0);
 
+	sanity_ret = file_entry_sanity_checks(a, block_flags, rar->file.dir,
+		unpacked_size, data_size);
+
+	if (sanity_ret != ARCHIVE_OK) {
+		return sanity_ret;
+	}
+
 	if(!read_var_sized(a, &file_attr, NULL))
 		return ARCHIVE_EOF;
 
@@ -4174,7 +4222,7 @@
 		 * it's impossible to perform any decompression. */
 		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
 		    "Can't decompress an entry marked as a directory");
-		return ARCHIVE_FAILED;
+		return ARCHIVE_FATAL;
 	}
 
 	if(!rar->skip_mode && (rar->cstate.last_write_ptr > rar->file.unpacked_size)) {
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_tar.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_tar.c
index 59d6941..ccaea87 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_tar.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_tar.c
@@ -233,7 +233,7 @@
 		    struct archive_entry *, int64_t *);
 static int	tohex(int c);
 static char	*url_decode(const char *, size_t);
-static void	tar_flush_unconsumed(struct archive_read *, int64_t *);
+static int	tar_flush_unconsumed(struct archive_read *, int64_t *);
 
 /* Sanity limits:  These numbers should be low enough to
  * prevent a maliciously-crafted archive from forcing us to
@@ -477,7 +477,7 @@
  * how much unconsumed data we have floating around, and to consume
  * anything outstanding since we're going to do read_aheads
  */
-static void
+static int
 tar_flush_unconsumed(struct archive_read *a, int64_t *unconsumed)
 {
 	if (*unconsumed) {
@@ -490,9 +490,13 @@
 			memset(data, 0xff, *unconsumed);
 		}
 */
-		__archive_read_consume(a, *unconsumed);
+		int64_t consumed = __archive_read_consume(a, *unconsumed);
+		if (consumed != *unconsumed) {
+			return (ARCHIVE_FATAL);
+		}
 		*unconsumed = 0;
 	}
+	return (ARCHIVE_OK);
 }
 
 /*
@@ -750,7 +754,9 @@
 
 		/* Find the next valid header record. */
 		while (1) {
-			tar_flush_unconsumed(a, unconsumed);
+			if (tar_flush_unconsumed(a, unconsumed) != ARCHIVE_OK) {
+				return (ARCHIVE_FATAL);
+			}
 
 			/* Read 512-byte header record */
 			h = __archive_read_ahead(a, 512, &bytes);
@@ -796,7 +802,9 @@
 
 			/* This is NOT a null block, so it must be a valid header. */
 			if (!checksum(a, h)) {
-				tar_flush_unconsumed(a, unconsumed);
+				if (tar_flush_unconsumed(a, unconsumed) != ARCHIVE_OK) {
+					return (ARCHIVE_FATAL);
+				}
 				archive_set_error(&a->archive, EINVAL,
 						  "Damaged tar archive (bad header checksum)");
 				/* If we've read some critical information (pax headers, etc)
@@ -1236,7 +1244,7 @@
 
 	header = (const struct archive_entry_header_ustar *)h;
 	size = tar_atol(header->size, sizeof(header->size));
-	if (size > (int64_t)pathname_limit) {
+	if (size < 0 || size > (int64_t)pathname_limit) {
 		return (ARCHIVE_FATAL);
 	}
 	to_consume = ((size + 511) & ~511);
@@ -1255,13 +1263,15 @@
 	const void *src;
 
 	/* Fail if we can't make our buffer big enough. */
-	if (archive_string_ensure(as, (size_t)size+1) == NULL) {
+	if (archive_string_ensure(as, size + 1) == NULL) {
 		archive_set_error(&a->archive, ENOMEM,
 		    "No memory");
 		return (ARCHIVE_FATAL);
 	}
 
-	tar_flush_unconsumed(a, unconsumed);
+	if (tar_flush_unconsumed(a, unconsumed) != ARCHIVE_OK) {
+		return (ARCHIVE_FATAL);
+	}
 
 	/* Read the body into the string. */
 	src = __archive_read_ahead(a, size, NULL);
@@ -1272,9 +1282,9 @@
 		*unconsumed = 0;
 		return (ARCHIVE_FATAL);
 	}
-	memcpy(as->s, src, (size_t)size);
+	memcpy(as->s, src, size);
 	as->s[size] = '\0';
-	as->length = (size_t)size;
+	as->length = size;
 	*unconsumed += size;
 	return (ARCHIVE_OK);
 }
@@ -1715,7 +1725,9 @@
 	 * Q: Is the above idea really possible?  Even
 	 * when there are GNU or pax extension entries?
 	 */
-	tar_flush_unconsumed(a, unconsumed);
+	if (tar_flush_unconsumed(a, unconsumed) != ARCHIVE_OK) {
+		return (ARCHIVE_FATAL);
+	}
 	data = __archive_read_ahead(a, msize, NULL);
 	if (data == NULL) {
 		archive_set_error(&a->archive, EINVAL,
@@ -1900,7 +1912,9 @@
 		    (long long)ext_size, (long long)ext_size_limit);
 		return (ARCHIVE_WARN);
 	}
-	tar_flush_unconsumed(a, unconsumed);
+	if (tar_flush_unconsumed(a, unconsumed) != ARCHIVE_OK) {
+		return (ARCHIVE_FATAL);
+	}
 
 	/* Parse the size/name of each pax attribute in the body */
 	archive_string_init(&attr_name);
@@ -1994,7 +2008,9 @@
 
 		/* Consume size, name, and `=` */
 		*unconsumed += p - attr_start;
-		tar_flush_unconsumed(a, unconsumed);
+		if (tar_flush_unconsumed(a, unconsumed) != ARCHIVE_OK) {
+			return (ARCHIVE_FATAL);
+		}
 
 		if (value_length == 0) {
 			archive_set_error(&a->archive, EINVAL,
@@ -2017,7 +2033,9 @@
 		err = err_combine(err, r);
 
 		/* Consume the `\n` that follows the pax attribute value. */
-		tar_flush_unconsumed(a, unconsumed);
+		if (tar_flush_unconsumed(a, unconsumed) != ARCHIVE_OK) {
+			return (ARCHIVE_FATAL);
+		}
 		p = __archive_read_ahead(a, 1, &did_read);
 		if (p == NULL) {
 			archive_set_error(&a->archive, EINVAL,
@@ -2033,7 +2051,9 @@
 		}
 		ext_size -= 1;
 		*unconsumed += 1;
-		tar_flush_unconsumed(a, unconsumed);
+		if (tar_flush_unconsumed(a, unconsumed) != ARCHIVE_OK) {
+			return (ARCHIVE_FATAL);
+		}
 	}
 	archive_string_free(&attr_name);
 	*unconsumed += ext_size + ext_padding;
@@ -2291,7 +2311,9 @@
 
 	archive_string_init(&as);
 	r = read_bytes_to_string(a, &as, value_length, &unconsumed);
-	tar_flush_unconsumed(a, &unconsumed);
+	if (tar_flush_unconsumed(a, &unconsumed) != ARCHIVE_OK) {
+		return (ARCHIVE_FATAL);
+	}
 	if (r < ARCHIVE_OK) {
 		archive_string_free(&as);
 		*result = 0;
@@ -2941,7 +2963,9 @@
 	/* Copy filename over (to ensure null termination). */
 	header = (const struct archive_entry_header_gnutar *)h;
 	const char *existing_pathname = archive_entry_pathname(entry);
-	if (existing_pathname == NULL || existing_pathname[0] == '\0') {
+	const wchar_t *existing_wcs_pathname = archive_entry_pathname_w(entry);
+	if ((existing_pathname == NULL || existing_pathname[0] == '\0')
+	    && (existing_wcs_pathname == NULL || existing_wcs_pathname[0] == L'\0')) {
 		if (archive_entry_copy_pathname_l(entry,
 		    header->name, sizeof(header->name), tar->sconv) != 0) {
 			err = set_conversion_failed_error(a, tar->sconv, "Pathname");
@@ -3094,7 +3118,9 @@
 		return (ARCHIVE_OK);
 
 	do {
-		tar_flush_unconsumed(a, unconsumed);
+		if (tar_flush_unconsumed(a, unconsumed) != ARCHIVE_OK) {
+			return (ARCHIVE_FATAL);
+		}
 		data = __archive_read_ahead(a, 512, &bytes_read);
 		if (data == NULL) {
 			archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
@@ -3284,7 +3310,9 @@
 			return (ARCHIVE_FATAL);
 	}
 	/* Skip rest of block... */
-	tar_flush_unconsumed(a, unconsumed);
+	if (tar_flush_unconsumed(a, unconsumed) != ARCHIVE_OK) {
+		return (ARCHIVE_FATAL);
+	}
 	bytes_read = tar->entry_bytes_remaining - remaining;
 	to_skip = 0x1ff & -bytes_read;
 	/* Fail if tar->entry_bytes_remaing would get negative */
@@ -3510,7 +3538,9 @@
 	const char *s;
 	void *p;
 
-	tar_flush_unconsumed(a, unconsumed);
+	if (tar_flush_unconsumed(a, unconsumed) != ARCHIVE_OK) {
+		return (ARCHIVE_FATAL);
+	}
 
 	t = __archive_read_ahead(a, 1, &bytes_read);
 	if (bytes_read <= 0 || t == NULL)
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_warc.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_warc.c
index 696f959..d8f188c 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_warc.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_warc.c
@@ -405,7 +405,7 @@
 		/* it's our lucky day, no work, we can leave early */
 		*buf = NULL;
 		*bsz = 0U;
-		*off = w->cntoff + 4U/*for \r\n\r\n separator*/;
+		*off = w->cntoff;
 		w->unconsumed = 0U;
 		return (ARCHIVE_EOF);
 	}
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_xar.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_xar.c
index 3bc9ae1..4205d47 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_xar.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_xar.c
@@ -930,7 +930,7 @@
 abort_read_data:
 	*buff = NULL;
 	*size = 0;
-	*offset = xar->total;
+	*offset = (int64_t)xar->entry_total;
 	return (r);
 }
 
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_zip.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_zip.c
index 6e556e9..bbfcd05 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_zip.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_zip.c
@@ -3015,8 +3015,8 @@
 		    p, salt_len, 1000, derived_key, key_len * 2 + 2);
 		if (r != 0) {
 			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
-			    "Decryption is unsupported due to lack of "
-			    "crypto library");
+			    r == CRYPTOR_STUB_FUNCTION ? "Decryption is unsupported due "
+				"to lack of crypto library" : "Failed to process passphrase");
 			return (ARCHIVE_FAILED);
 		}
 
diff --git a/Utilities/cmlibarchive/libarchive/archive_string.c b/Utilities/cmlibarchive/libarchive/archive_string.c
index 7437715..3bb9783 100644
--- a/Utilities/cmlibarchive/libarchive/archive_string.c
+++ b/Utilities/cmlibarchive/libarchive/archive_string.c
@@ -2015,7 +2015,7 @@
 	/* We must allocate memory even if there is no data for conversion
 	 * or copy. This simulates archive_string_append behavior. */
 	if (length == 0) {
-		int tn = 1;
+		size_t tn = 1;
 		if (sc != NULL && (sc->flag & SCONV_TO_UTF16))
 			tn = 2;
 		if (archive_string_ensure(as, as->length + tn) == NULL)
@@ -2752,7 +2752,8 @@
 	char *p, *endp;
 	uint32_t uc;
 	size_t w;
-	int n, ret = 0, ts, tm;
+	size_t ts, tm;
+	int n, ret = 0;
 	int (*parse)(uint32_t *, const char *, size_t);
 	size_t (*unparse)(char *, size_t, uint32_t);
 
diff --git a/Utilities/cmlibarchive/libarchive/archive_string_sprintf.c b/Utilities/cmlibarchive/libarchive/archive_string_sprintf.c
index 1c5910e..69b0cdc 100644
--- a/Utilities/cmlibarchive/libarchive/archive_string_sprintf.c
+++ b/Utilities/cmlibarchive/libarchive/archive_string_sprintf.c
@@ -146,7 +146,7 @@
 			case 'z': s = va_arg(ap, ssize_t); break;
 			default:  s = va_arg(ap, int); break;
 			}
-		        append_int(as, s, 10);
+			append_int(as, s, 10);
 			break;
 		case 's':
 			switch(long_flag) {
diff --git a/Utilities/cmlibarchive/libarchive/archive_util.c b/Utilities/cmlibarchive/libarchive/archive_util.c
index ecb4fe6..f3cbf0e 100644
--- a/Utilities/cmlibarchive/libarchive/archive_util.c
+++ b/Utilities/cmlibarchive/libarchive/archive_util.c
@@ -445,11 +445,39 @@
 #else
 
 static int
-get_tempdir(struct archive_string *temppath)
+__archive_issetugid(void)
 {
-	const char *tmp;
+#ifdef HAVE_ISSETUGID
+	return (issetugid());
+#elif HAVE_GETRESUID
+	uid_t ruid, euid, suid;
+	gid_t rgid, egid, sgid;
+	if (getresuid(&ruid, &euid, &suid) != 0)
+		return (-1);
+	if (ruid != euid || ruid != suid)
+		return (1);
+	if (getresgid(&ruid, &egid, &sgid) != 0)
+		return (-1);
+	if (rgid != egid || rgid != sgid)
+		return (1);
+#elif HAVE_GETEUID
+	if (geteuid() != getuid())
+		return (1);
+#if HAVE_GETEGID
+	if (getegid() != getgid())
+		return (1);
+#endif
+#endif
+	return (0);
+}
 
-	tmp = getenv("TMPDIR");
+int
+__archive_get_tempdir(struct archive_string *temppath)
+{
+	const char *tmp = NULL;
+
+	if (__archive_issetugid() == 0)
+		tmp = getenv("TMPDIR");
 	if (tmp == NULL)
 #ifdef _PATH_TMP
 		tmp = _PATH_TMP;
@@ -476,7 +504,7 @@
 
 	archive_string_init(&temp_name);
 	if (tmpdir == NULL) {
-		if (get_tempdir(&temp_name) != ARCHIVE_OK)
+		if (__archive_get_tempdir(&temp_name) != ARCHIVE_OK)
 			goto exit_tmpfile;
 	} else {
 		archive_strcpy(&temp_name, tmpdir);
@@ -538,7 +566,7 @@
 	if (template == NULL) {
 		archive_string_init(&temp_name);
 		if (tmpdir == NULL) {
-			if (get_tempdir(&temp_name) != ARCHIVE_OK)
+			if (__archive_get_tempdir(&temp_name) != ARCHIVE_OK)
 				goto exit_tmpfile;
 		} else
 			archive_strcpy(&temp_name, tmpdir);
diff --git a/Utilities/cmlibarchive/libarchive/archive_windows.c b/Utilities/cmlibarchive/libarchive/archive_windows.c
index 03c9736..e55f995 100644
--- a/Utilities/cmlibarchive/libarchive/archive_windows.c
+++ b/Utilities/cmlibarchive/libarchive/archive_windows.c
@@ -45,6 +45,7 @@
 #if defined(_WIN32) && !defined(__CYGWIN__)
 
 #include "archive_platform.h"
+#include "archive_platform_stat.h"
 #include "archive_private.h"
 #include "archive_entry.h"
 #include "archive_time_private.h"
@@ -313,6 +314,10 @@
 	pmode = va_arg(ap, int);
 	va_end(ap);
 	ws = NULL;
+
+	/* _(w)sopen_s fails if we provide any other modes */
+	pmode = pmode & (_S_IREAD | _S_IWRITE);
+
 	if ((flags & ~O_BINARY) == O_RDONLY) {
 		/*
 		 * When we open a directory, _open function returns
@@ -374,7 +379,7 @@
 		   TODO: Fix mode of new file.  */
 		r = _open(path, flags);
 #else
-		r = _open(path, flags, pmode);
+		_sopen_s(&r, path, flags, _SH_DENYNO, pmode);
 #endif
 		if (r < 0 && errno == EACCES && (flags & O_CREAT) != 0) {
 			/* Simulate other POSIX system action to pass our test suite. */
@@ -395,7 +400,7 @@
 			return (-1);
 		}
 	}
-	r = _wopen(ws, flags, pmode);
+	_wsopen_s(&r, ws, flags, _SH_DENYNO, pmode);
 	if (r < 0 && errno == EACCES && (flags & O_CREAT) != 0) {
 		/* Simulate other POSIX system action to pass our test suite. */
 		attr = GetFileAttributesW(ws);
@@ -410,6 +415,93 @@
 	return (r);
 }
 
+int
+__la_wopen(const wchar_t *path, int flags, ...)
+{
+	va_list ap;
+	wchar_t *fullpath;
+	int r, pmode;
+	DWORD attr;
+
+	va_start(ap, flags);
+	pmode = va_arg(ap, int);
+	va_end(ap);
+	fullpath = NULL;
+
+	/* _(w)sopen_s fails if we provide any other modes */
+	pmode = pmode & (_S_IREAD | _S_IWRITE);
+
+	if ((flags & ~O_BINARY) == O_RDONLY) {
+		/*
+		 * When we open a directory, _open function returns
+		 * "Permission denied" error.
+		 */
+		attr = GetFileAttributesW(path);
+#if !defined(WINAPI_FAMILY_PARTITION) || WINAPI_FAMILY_PARTITION (WINAPI_PARTITION_DESKTOP)
+		if (attr == (DWORD)-1 && GetLastError() == ERROR_PATH_NOT_FOUND)
+#endif
+		{
+			fullpath = __la_win_permissive_name_w(path);
+			if (fullpath == NULL) {
+				errno = EINVAL;
+				return (-1);
+			}
+			path = fullpath;
+			attr = GetFileAttributesW(fullpath);
+		}
+		if (attr == (DWORD)-1) {
+			la_dosmaperr(GetLastError());
+			free(fullpath);
+			return (-1);
+		}
+		if (attr & FILE_ATTRIBUTE_DIRECTORY) {
+			HANDLE handle;
+#if !defined(WINAPI_FAMILY_PARTITION) || WINAPI_FAMILY_PARTITION (WINAPI_PARTITION_DESKTOP)
+			if (fullpath != NULL)
+				handle = CreateFileW(fullpath, 0, 0, NULL,
+				    OPEN_EXISTING,
+				    FILE_FLAG_BACKUP_SEMANTICS |
+				    FILE_ATTRIBUTE_READONLY,
+					NULL);
+			else
+				handle = CreateFileW(path, 0, 0, NULL,
+				    OPEN_EXISTING,
+				    FILE_FLAG_BACKUP_SEMANTICS |
+				    FILE_ATTRIBUTE_READONLY,
+					NULL);
+#else /* !WINAPI_PARTITION_DESKTOP */
+			CREATEFILE2_EXTENDED_PARAMETERS createExParams;
+			ZeroMemory(&createExParams, sizeof(createExParams));
+			createExParams.dwSize = sizeof(createExParams);
+			createExParams.dwFileAttributes = FILE_ATTRIBUTE_READONLY;
+			createExParams.dwFileFlags = FILE_FLAG_BACKUP_SEMANTICS;
+			handle = CreateFile2(fullpath, 0, 0,
+				OPEN_EXISTING, &createExParams);
+#endif /* !WINAPI_PARTITION_DESKTOP */
+			free(fullpath);
+			if (handle == INVALID_HANDLE_VALUE) {
+				la_dosmaperr(GetLastError());
+				return (-1);
+			}
+			r = _open_osfhandle((intptr_t)handle, _O_RDONLY);
+			return (r);
+		}
+	}
+	_wsopen_s(&r, path, flags, _SH_DENYNO, pmode);
+	if (r < 0 && errno == EACCES && (flags & O_CREAT) != 0) {
+		/* Simulate other POSIX system action to pass our test suite. */
+		attr = GetFileAttributesW(path);
+		if (attr == (DWORD)-1)
+			la_dosmaperr(GetLastError());
+		else if (attr & FILE_ATTRIBUTE_DIRECTORY)
+			errno = EISDIR;
+		else
+			errno = EACCES;
+	}
+	free(fullpath);
+	return (r);
+}
+
 ssize_t
 __la_read(int fd, void *buf, size_t nbytes)
 {
@@ -561,6 +653,8 @@
 	st->st_mode = us->st_mode;
 	st->st_nlink = us->st_nlink;
 	st->st_size = (off_t)us->st_size;
+	if (st->st_size < 0 || (uint64_t)st->st_size != us->st_size)
+		st->st_size = 0;
 	st->st_uid = us->st_uid;
 	st->st_dev = us->st_dev;
 	st->st_rdev = us->st_rdev;
@@ -630,6 +724,53 @@
 	return (ret);
 }
 
+static void
+copy_seek_stat(la_seek_stat_t *st, struct ustat *us)
+{
+	st->st_mtime = us->st_mtime;
+	st->st_gid = us->st_gid;
+	st->st_ino = getino(us);
+	st->st_mode = us->st_mode;
+	st->st_nlink = us->st_nlink;
+	st->st_size = (la_seek_t)us->st_size;
+	if (st->st_size < 0 || (uint64_t)st->st_size != us->st_size)
+		st->st_size = -1;
+	st->st_uid = us->st_uid;
+	st->st_dev = us->st_dev;
+	st->st_rdev = us->st_rdev;
+}
+
+int
+__la_seek_fstat(int fd, la_seek_stat_t *st)
+{
+	struct ustat u;
+	int ret;
+
+	ret = __hstat((HANDLE)_get_osfhandle(fd), &u);
+	copy_seek_stat(st, &u);
+	return (ret);
+}
+
+int
+__la_seek_stat(const char *path, la_seek_stat_t *st)
+{
+	HANDLE handle;
+	struct ustat u;
+	int ret;
+
+	handle = la_CreateFile(path, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING,
+		FILE_FLAG_BACKUP_SEMANTICS,
+		NULL);
+	if (handle == INVALID_HANDLE_VALUE) {
+		la_dosmaperr(GetLastError());
+		return (-1);
+	}
+	ret = __hstat(handle, &u);
+	CloseHandle(handle);
+	copy_seek_stat(st, &u);
+	return (ret);
+}
+
 /*
  * This waitpid is limited implementation.
  */
@@ -641,13 +782,14 @@
 	(void)option;/* UNUSED */
 	do {
 		if (GetExitCodeProcess(child, &cs) == 0) {
-			CloseHandle(child);
 			la_dosmaperr(GetLastError());
+			CloseHandle(child);
 			*status = 0;
 			return (-1);
 		}
 	} while (cs == STILL_ACTIVE);
 
+	CloseHandle(child);
 	*status = (int)(cs & 0xff);
 	return (0);
 }
diff --git a/Utilities/cmlibarchive/libarchive/archive_windows.h b/Utilities/cmlibarchive/libarchive/archive_windows.h
index 8afe1f6..9facf5f 100644
--- a/Utilities/cmlibarchive/libarchive/archive_windows.h
+++ b/Utilities/cmlibarchive/libarchive/archive_windows.h
@@ -77,6 +77,9 @@
 #pragma warning(disable:4142)   /* benign redefinition of type */
 #pragma warning(disable:4761)   /* integral size mismatch in argument; conversion supplied */
 #endif
+
+#include "archive_platform_stat.h"
+
 #if defined(__BORLANDC__)
 #pragma warn -8068	/* Constant out of range in comparison. */
 #pragma warn -8072	/* Suspicious pointer arithmetic. */
@@ -111,6 +114,7 @@
 #endif
 #define	lstat		__la_stat
 #define	open		__la_open
+#define	_wopen		__la_wopen
 #define	read		__la_read
 #if !defined(__BORLANDC__) && !defined(__WATCOMC__)
 #define setmode		_setmode
@@ -267,6 +271,9 @@
     #define	F_OK    0       /*  Test for existence of file  */
 #endif
 
+/* Functions to circumvent off_t limitations */
+int __la_seek_fstat(int fd, la_seek_stat_t *st);
+int __la_seek_stat(const char *path, la_seek_stat_t *st);
 
 /* Replacement POSIX function */
 extern int	 __la_fstat(int fd, struct stat *st);
@@ -275,6 +282,7 @@
 extern __int64	 __la_lseek(int fd, __int64 offset, int whence);
 #endif
 extern int	 __la_open(const char *path, int flags, ...);
+extern int	 __la_wopen(const wchar_t *path, int flags, ...);
 extern ssize_t	 __la_read(int fd, void *buf, size_t nbytes);
 extern int	 __la_stat(const char *path, struct stat *st);
 extern pid_t	 __la_waitpid(HANDLE child, int *status, int option);
diff --git a/Utilities/cmlibarchive/libarchive/archive_write.c b/Utilities/cmlibarchive/libarchive/archive_write.c
index a8e7b63..9b9cb19 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write.c
@@ -360,7 +360,6 @@
 	struct archive_none *state;
 	void *buffer;
 	size_t buffer_size;
-	int ret;
 
 	f->bytes_per_block = archive_write_get_bytes_per_block(f->archive);
 	f->bytes_in_last_block =
@@ -385,13 +384,7 @@
 
 	if (a->client_opener == NULL)
 		return (ARCHIVE_OK);
-	ret = a->client_opener(f->archive, a->client_data);
-	if (ret != ARCHIVE_OK) {
-		free(state->buffer);
-		free(state);
-		f->data = NULL;
-	}
-	return (ret);
+	return (a->client_opener(f->archive, a->client_data));
 }
 
 static int
@@ -480,6 +473,7 @@
 archive_write_client_free(struct archive_write_filter *f)
 {
 	struct archive_write *a = (struct archive_write *)f->archive;
+	struct archive_none *state = (struct archive_none *)f->data;
 
 	if (a->client_freer)
 		(*a->client_freer)(&a->archive, a->client_data);
@@ -492,6 +486,13 @@
 		a->passphrase = NULL;
 	}
 
+	/* Free state. */
+	if (state != NULL) {
+		free(state->buffer);
+		free(state);
+		f->data = NULL;
+	}
+
 	return (ARCHIVE_OK);
 }
 
@@ -548,8 +549,6 @@
 	}
 	if (a->client_closer)
 		(*a->client_closer)(&a->archive, a->client_data);
-	free(state->buffer);
-	free(state);
 
 	/* Clear the close handler myself not to be called again. */
 	f->state = ARCHIVE_WRITE_FILTER_STATE_CLOSED;
@@ -807,7 +806,10 @@
 	if (a->archive.state & ARCHIVE_STATE_DATA
 	    && a->format_finish_entry != NULL)
 		ret = (a->format_finish_entry)(a);
-	a->archive.state = ARCHIVE_STATE_HEADER;
+	if (ret == ARCHIVE_FATAL)
+		a->archive.state = ARCHIVE_STATE_FATAL;
+	else
+		a->archive.state = ARCHIVE_STATE_HEADER;
 	return (ret);
 }
 
@@ -819,6 +821,7 @@
 {
 	struct archive_write *a = (struct archive_write *)_a;
 	const size_t max_write = INT_MAX;
+	int ret;
 
 	archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
 	    ARCHIVE_STATE_DATA, "archive_write_data");
@@ -826,7 +829,10 @@
 	if (s > max_write)
 		s = max_write;
 	archive_clear_error(&a->archive);
-	return ((a->format_write_data)(a, buff, s));
+	ret = (a->format_write_data)(a, buff, s);
+	if (ret == ARCHIVE_FATAL)
+		a->archive.state = ARCHIVE_STATE_FATAL;
+	return (ret);
 }
 
 static struct archive_write_filter *
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_bzip2.c b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_bzip2.c
index ea9e9b0..e5d2b0a 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_bzip2.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_bzip2.c
@@ -281,6 +281,10 @@
 archive_compressor_bzip2_free(struct archive_write_filter *f)
 {
 	struct private_data *data = (struct private_data *)f->data;
+
+	/* May already have been called, but not necessarily. */
+	(void)BZ2_bzCompressEnd(&(data->stream));
+
 	free(data->compressed);
 	free(data);
 	f->data = NULL;
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_gzip.c b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_gzip.c
index f509f76..69c6cf5 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_gzip.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_gzip.c
@@ -191,7 +191,8 @@
 archive_compressor_gzip_open(struct archive_write_filter *f)
 {
 	struct private_data *data = (struct private_data *)f->data;
-	int ret;
+	int ret = ARCHIVE_OK;
+	int init_success;
 
 	if (data->compressed == NULL) {
 		size_t bs = 65536, bpb;
@@ -221,44 +222,66 @@
 	data->compressed[0] = 0x1f; /* GZip signature bytes */
 	data->compressed[1] = 0x8b;
 	data->compressed[2] = 0x08; /* "Deflate" compression */
-	data->compressed[3] = data->original_filename == NULL ? 0 : 0x8;
+	data->compressed[3] = 0x00; /* Flags */
 	if (data->timestamp >= 0) {
 		time_t t = time(NULL);
 		data->compressed[4] = (uint8_t)(t)&0xff;  /* Timestamp */
 		data->compressed[5] = (uint8_t)(t>>8)&0xff;
 		data->compressed[6] = (uint8_t)(t>>16)&0xff;
 		data->compressed[7] = (uint8_t)(t>>24)&0xff;
-	} else
+	} else {
 		memset(&data->compressed[4], 0, 4);
-    if (data->compression_level == 9)
-	    data->compressed[8] = 2;
-    else if(data->compression_level == 1)
-	    data->compressed[8] = 4;
-    else
-	    data->compressed[8] = 0;
+	}
+	if (data->compression_level == 9) {
+		data->compressed[8] = 2;
+	} else if(data->compression_level == 1) {
+		data->compressed[8] = 4;
+	} else {
+		data->compressed[8] = 0;
+	}
 	data->compressed[9] = 3; /* OS=Unix */
 	data->stream.next_out += 10;
 	data->stream.avail_out -= 10;
 
 	if (data->original_filename != NULL) {
-		strcpy((char*)data->compressed + 10, data->original_filename);
-		data->stream.next_out += strlen(data->original_filename) + 1;
-		data->stream.avail_out -= strlen(data->original_filename) + 1;
+		/* Limit "original filename" to 32k or the
+		 * remaining space in the buffer, whichever is smaller.
+		 */
+		int ofn_length = strlen(data->original_filename);
+		int ofn_max_length = 32768;
+		int ofn_space_available = data->compressed
+			+ data->compressed_buffer_size
+			- data->stream.next_out
+			- 1;
+		if (ofn_max_length > ofn_space_available) {
+			ofn_max_length = ofn_space_available;
+		}
+		if (ofn_length < ofn_max_length) {
+			data->compressed[3] |= 0x8;
+			strcpy((char*)data->compressed + 10,
+			       data->original_filename);
+			data->stream.next_out += ofn_length + 1;
+			data->stream.avail_out -= ofn_length + 1;
+		} else {
+			archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
+					  "Gzip 'Original Filename' ignored because it is too long");
+			ret = ARCHIVE_WARN;
+		}
 	}
 
 	f->write = archive_compressor_gzip_write;
 
 	/* Initialize compression library. */
-	ret = deflateInit2(&(data->stream),
+	init_success = deflateInit2(&(data->stream),
 	    data->compression_level,
 	    Z_DEFLATED,
 	    -15 /* < 0 to suppress zlib header */,
 	    8,
 	    Z_DEFAULT_STRATEGY);
 
-	if (ret == Z_OK) {
+	if (init_success == Z_OK) {
 		f->data = data;
-		return (ARCHIVE_OK);
+		return (ret);
 	}
 
 	/* Library setup failed: clean up. */
@@ -266,7 +289,7 @@
 	    "initializing compression library");
 
 	/* Override the error message if we know what really went wrong. */
-	switch (ret) {
+	switch (init_success) {
 	case Z_STREAM_ERROR:
 		archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
 		    "Internal error initializing "
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_program.c b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_program.c
index c661cc7..f12db33 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_program.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_program.c
@@ -330,6 +330,7 @@
     struct archive_write_program_data *data)
 {
 	int ret, status;
+	pid_t pid;
 	ssize_t bytes_read;
 
 	if (data->child == 0)
@@ -373,14 +374,12 @@
 		close(data->child_stdin);
 	if (data->child_stdout != -1)
 		close(data->child_stdout);
-	while (waitpid(data->child, &status, 0) == -1 && errno == EINTR)
-		continue;
-#if defined(_WIN32) && !defined(__CYGWIN__)
-	CloseHandle(data->child);
-#endif
+	do {
+		pid = waitpid(data->child, &status, 0);
+	} while (pid == -1 && errno == EINTR);
 	data->child = 0;
 
-	if (status != 0) {
+	if (pid < 0 || status != 0) {
 		archive_set_error(f->archive, EIO,
 		    "Error closing program: %s", data->program_name);
 		ret = ARCHIVE_FATAL;
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_zstd.c b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_zstd.c
index ca421c9..b45af8b 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_zstd.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_zstd.c
@@ -391,6 +391,8 @@
 
 	ZSTD_CCtx_setParameter(data->cstream, ZSTD_c_nbWorkers, data->threads);
 
+	ZSTD_CCtx_setParameter(data->cstream, ZSTD_c_checksumFlag, 1);
+
 #if ZSTD_VERSION_NUMBER >= MINVER_LONG
 	ZSTD_CCtx_setParameter(data->cstream, ZSTD_c_windowLog, data->long_distance);
 #endif
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_disk_posix.c b/Utilities/cmlibarchive/libarchive/archive_write_disk_posix.c
index 3f4553c..b7528ab 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_disk_posix.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_disk_posix.c
@@ -2204,7 +2204,7 @@
 				(void)clear_nochange_fflags(a);
 
 			if ((a->flags & ARCHIVE_EXTRACT_SAFE_WRITES) &&
-			    S_ISREG(a->st.st_mode)) {
+			    S_ISREG(a->mode)) {
 				/* Use a temporary file to extract */
 				if ((a->fd = la_mktemp(a)) == -1) {
 					archive_set_error(&a->archive, errno,
@@ -2559,9 +2559,9 @@
 			 * for directories. For other file types
 			 * we need to verify via fstat() or lstat()
 			 */
-			if (fd == -1 || p->filetype != AE_IFDIR) {
+			if (fd < 0 || p->filetype != AE_IFDIR) {
 #if HAVE_FSTAT
-				if (fd > 0 && (
+				if (fd >= 0 && (
 				    fstat(fd, &st) != 0 ||
 				    la_verify_filetype(st.st_mode,
 				    p->filetype) == 0)) {
@@ -3930,10 +3930,14 @@
 #ifdef UF_APPEND
 	    | UF_APPEND
 #endif
-#ifdef EXT2_APPEND_FL
+#if defined(FS_APPEND_FL)
+	    | FS_APPEND_FL
+#elif defined(EXT2_APPEND_FL)
 	    | EXT2_APPEND_FL
 #endif
-#ifdef EXT2_IMMUTABLE_FL
+#if defined(FS_IMMUTABLE_FL)
+	    | FS_IMMUTABLE_FL
+#elif defined(EXT2_IMMUTABLE_FL)
 	    | EXT2_IMMUTABLE_FL
 #endif
 	;
@@ -4437,7 +4441,7 @@
 	 */
 	fd = open(pathname, O_RDONLY | O_BINARY | O_CLOEXEC);
 	__archive_ensure_cloexec_flag(fd);
-	if (fd == -1) {
+	if (fd < 0) {
 		archive_set_error(&a->archive, errno,
 		    "Failed to open a restoring file");
 		ret = ARCHIVE_WARN;
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_disk_windows.c b/Utilities/cmlibarchive/libarchive/archive_write_disk_windows.c
index c7339c4..d4f6f18 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_disk_windows.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_disk_windows.c
@@ -1618,7 +1618,7 @@
 				(void)clear_nochange_fflags(a);
 			}
 			if ((a->flags & ARCHIVE_EXTRACT_SAFE_WRITES) &&
-				S_ISREG(st_mode)) {
+				S_ISREG(a->mode)) {
 				int fd = la_mktemp(a);
 
 				if (fd == -1) {
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_open_fd.c b/Utilities/cmlibarchive/libarchive/archive_write_open_fd.c
index 8a3f68d..ba034ed 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_open_fd.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_open_fd.c
@@ -122,7 +122,7 @@
 	mine = (struct write_fd_data *)client_data;
 	for (;;) {
 		bytesWritten = write(mine->fd, buff, length);
-		if (bytesWritten <= 0) {
+		if (bytesWritten < 0) {
 			if (errno == EINTR)
 				continue;
 			archive_set_error(a, errno, "Write error");
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_open_file.c b/Utilities/cmlibarchive/libarchive/archive_write_open_file.c
index 4c6ebfb..0b310f3 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_open_file.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_open_file.c
@@ -85,16 +85,12 @@
 	size_t	bytesWritten;
 
 	mine = client_data;
-	for (;;) {
-		bytesWritten = fwrite(buff, 1, length, mine->f);
-		if (bytesWritten <= 0) {
-			if (errno == EINTR)
-				continue;
-			archive_set_error(a, errno, "Write error");
-			return (-1);
-		}
-		return (bytesWritten);
+	bytesWritten = fwrite(buff, 1, length, mine->f);
+	if (bytesWritten != length) {
+		archive_set_error(a, errno, "Write error");
+		return (-1);
 	}
+	return (bytesWritten);
 }
 
 static int
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_open_filename.c b/Utilities/cmlibarchive/libarchive/archive_write_open_filename.c
index 3420942..7d0f9bd 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_open_filename.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_open_filename.c
@@ -108,6 +108,7 @@
 	else
 		r = archive_mstring_copy_wcs(&mine->filename, filename);
 	if (r < 0) {
+		free(mine);
 		if (errno == ENOMEM) {
 			archive_set_error(a, ENOMEM, "No memory");
 			return (ARCHIVE_FATAL);
@@ -227,7 +228,7 @@
 	mine = (struct write_file_data *)client_data;
 	for (;;) {
 		bytesWritten = write(mine->fd, buff, length);
-		if (bytesWritten <= 0) {
+		if (bytesWritten < 0) {
 			if (errno == EINTR)
 				continue;
 			archive_set_error(a, errno, "Write error");
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_7zip.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_7zip.c
index fd41320..3415766 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_7zip.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_7zip.c
@@ -686,7 +686,7 @@
 		ws = write(zip->temp_fd, p, s);
 		if (ws < 0) {
 			archive_set_error(&(a->archive), errno,
-			    "fwrite function failed");
+			    "write function failed");
 			return (ARCHIVE_FATAL);
 		}
 		s -= ws;
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_mtree.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_mtree.c
index 02fbb2d..8131574 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_mtree.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_mtree.c
@@ -1927,7 +1927,7 @@
 	}
 
 	/*
-	 * Find out the position which points the last position of
+	 * Find out the position which points to the last position of
 	 * path separator('/').
 	 */
 	slash = NULL;
@@ -2024,7 +2024,7 @@
 }
 
 /*
- * Find a entry from a parent entry with the name.
+ * Find an entry from a parent entry with given name.
  */
 static struct mtree_entry *
 mtree_entry_find_child(struct mtree_entry *parent, const char *child_name)
@@ -2148,10 +2148,10 @@
 
 		/* Find next sub directory. */
 		if (!np->dir_info) {
-			/* NOT Directory! */
+			/* NOT a directory! */
 			archive_set_error(&a->archive,
 			    ARCHIVE_ERRNO_MISC,
-			    "`%s' is not directory, we cannot insert `%s' ",
+			    "`%s' is not a directory, we cannot insert `%s' ",
 			    np->pathname.s, file->pathname.s);
 			return (ARCHIVE_FAILED);
 		}
@@ -2243,10 +2243,7 @@
 	}
 
 same_entry:
-	/*
-	 * We have already has the entry the filename of which is
-	 * the same.
-	 */
+	/* We already have an entry with same filename. */
 	r = mtree_entry_exchange_same_entry(a, np, file);
 	if (r < ARCHIVE_WARN)
 		return (r);
@@ -2264,13 +2261,13 @@
 
 	if ((np->mode & AE_IFMT) != (file->mode & AE_IFMT)) {
 		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
-		    "Found duplicate entries `%s' and its file type is "
-		    "different",
+		    "Found duplicate entries for `%s' with "
+		    "differing file types.",
 		    np->pathname.s);
 		return (ARCHIVE_FAILED);
 	}
 
-	/* Update the existent mtree entry's attributes by the new one's. */
+	/* Update the existing mtree entry's attributes by the new one's. */
 	archive_string_empty(&np->symlink);
 	archive_string_concat(&np->symlink, &file->symlink);
 	archive_string_empty(&np->uname);
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_xar.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_xar.c
index 4b80fe1..3276f9c 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_xar.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_xar.c
@@ -689,7 +689,7 @@
 		ws = write(xar->temp_fd, p, s);
 		if (ws < 0) {
 			archive_set_error(&(a->archive), errno,
-			    "fwrite function failed");
+			    "write function failed");
 			return (ARCHIVE_FATAL);
 		}
 		s -= ws;
@@ -3418,8 +3418,8 @@
 xml_writer_get_final_content_and_length(struct xml_writer *ctx,
     const char **out, size_t *size)
 {
-	*out = (const char*)ctx->bp->content;
-	*size = (size_t)ctx->bp->use;
+	*out = (const char*)xmlBufferContent(ctx->bp);
+	*size = (size_t)xmlBufferLength(ctx->bp);
 	return (0);
 }
 
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_zip.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_zip.c
index 8644db7..bb4cb44 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_zip.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_zip.c
@@ -1856,7 +1856,10 @@
 			}
 			ret = __archive_write_output(a, zip->buf, remainder);
 			if (ret != ARCHIVE_OK)
+			{
+				deflateEnd(&zip->stream.deflate);
 				return (ret);
+			}
 			zip->entry_compressed_written += remainder;
 			zip->written_bytes += remainder;
 			zip->stream.deflate.next_out = zip->buf;
@@ -1898,7 +1901,10 @@
 			}
 			ret = __archive_write_output(a, zip->buf, remainder);
 			if (ret != ARCHIVE_OK)
+			{
+				BZ2_bzCompressEnd(&zip->stream.bzip2);
 				return (ret);
+			}
 			zip->entry_compressed_written += remainder;
 			zip->written_bytes += remainder;
 			zip->stream.bzip2.next_out = (char*)zip->buf;
@@ -1940,13 +1946,17 @@
 			}
 			ret = __archive_write_output(a, zip->buf, remainder);
 			if (ret != ARCHIVE_OK)
+			{
+				ZSTD_freeCStream(zip->stream.zstd.context);
 				return (ret);
+			}
 			zip->entry_compressed_written += remainder;
 			zip->written_bytes += remainder;
-			zip->stream.zstd.out.dst = zip->buf;
 			if (zip->stream.zstd.out.pos != zip->stream.zstd.out.size)
 				finishing = 0;
+			zip->stream.zstd.out.dst = zip->buf;
 			zip->stream.zstd.out.size = zip->len_buf;
+			zip->stream.zstd.out.pos = 0;
 		} while (finishing);
 		ZSTD_freeCStream(zip->stream.zstd.context);
 		break;
@@ -1984,7 +1994,10 @@
 			}
 			ret = __archive_write_output(a, zip->buf, remainder);
 			if (ret != ARCHIVE_OK)
+			{
+				lzma_end(&zip->stream.lzma.context);
 				return (ret);
+			}
 			zip->entry_compressed_written += remainder;
 			zip->written_bytes += remainder;
 			zip->stream.lzma.context.next_out = zip->buf;
@@ -2434,13 +2447,19 @@
 		    "Can't generate random number for encryption");
 		return (ARCHIVE_FATAL);
 	}
-	archive_pbkdf2_sha1(passphrase, strlen(passphrase),
+	ret = archive_pbkdf2_sha1(passphrase, strlen(passphrase),
 	    salt, salt_len, 1000, derived_key, key_len * 2 + 2);
+	if (ret != 0) {
+		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+		    ret == CRYPTOR_STUB_FUNCTION ? "Encryption is unsupported due to "
+			"lack of crypto library" : "Failed to process passphrase");
+		return (ARCHIVE_FAILED);
+	}
 
 	ret = archive_encrypto_aes_ctr_init(&zip->cctx, derived_key, key_len);
 	if (ret != 0) {
 		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
-		    "Decryption is unsupported due to lack of crypto library");
+		    "Failed to initialize AES CTR mode");
 		return (ARCHIVE_FAILED);
 	}
 	ret = archive_hmac_sha1_init(&zip->hctx, derived_key + key_len,
diff --git a/Utilities/cmlibarchive/libarchive/filter_fork_posix.c b/Utilities/cmlibarchive/libarchive/filter_fork_posix.c
index c895c08..7c48519 100644
--- a/Utilities/cmlibarchive/libarchive/filter_fork_posix.c
+++ b/Utilities/cmlibarchive/libarchive/filter_fork_posix.c
@@ -1,6 +1,6 @@
 /*-
  * Copyright (c) 2007 Joerg Sonnenberger
- * Copyright (c) 2012 Michihiro NAKAJIMA 
+ * Copyright (c) 2012 Michihiro NAKAJIMA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -76,7 +76,15 @@
 {
 	pid_t child = -1;
 	int stdin_pipe[2], stdout_pipe[2], tmp;
+
+#if !defined(POSIX_SPAWN_CLOEXEC_DEFAULT) && \
+    (HAVE_FORK || HAVE_VFORK) && \
+    (HAVE_CLOSEFROM || HAVE_CLOSE_RANGE || defined(_SC_OPEN_MAX))
+#undef HAVE_POSIX_SPAWNP
+#endif
+
 #if HAVE_POSIX_SPAWNP
+	posix_spawnattr_t attr;
 	posix_spawn_file_actions_t actions;
 	int r;
 #endif
@@ -107,11 +115,21 @@
 
 #if HAVE_POSIX_SPAWNP
 
-	r = posix_spawn_file_actions_init(&actions);
+	r = posix_spawnattr_init(&attr);
 	if (r != 0) {
 		errno = r;
 		goto stdout_opened;
 	}
+	r = posix_spawn_file_actions_init(&actions);
+	if (r != 0) {
+		errno = r;
+		goto attr_inited;
+	}
+#ifdef POSIX_SPAWN_CLOEXEC_DEFAULT
+	r = posix_spawnattr_setflags(&attr, POSIX_SPAWN_CLOEXEC_DEFAULT);
+	if (r != 0)
+		goto actions_inited;
+#endif
 	r = posix_spawn_file_actions_addclose(&actions, stdin_pipe[1]);
 	if (r != 0)
 		goto actions_inited;
@@ -136,11 +154,12 @@
 		if (r != 0)
 			goto actions_inited;
 	}
-	r = posix_spawnp(&child, cmdline->path, &actions, NULL,
+	r = posix_spawnp(&child, cmdline->path, &actions, &attr,
 		cmdline->argv, NULL);
 	if (r != 0)
 		goto actions_inited;
 	posix_spawn_file_actions_destroy(&actions);
+	posix_spawnattr_destroy(&attr);
 
 #else /* HAVE_POSIX_SPAWNP */
 
@@ -162,6 +181,16 @@
 			_exit(254);
 		if (stdout_pipe[1] != 1 /* stdout */)
 			close(stdout_pipe[1]);
+
+#if HAVE_CLOSEFROM
+		closefrom(3);
+#elif HAVE_CLOSE_RANGE
+		close_range(3, ~0U, 0);
+#elif defined(_SC_OPEN_MAX)
+		for (int i = sysconf(_SC_OPEN_MAX); i > 3;)
+			close(--i);
+#endif
+
 		execvp(cmdline->path, cmdline->argv);
 		_exit(254);
 	}
@@ -183,6 +212,8 @@
 actions_inited:
 	errno = r;
 	posix_spawn_file_actions_destroy(&actions);
+attr_inited:
+	posix_spawnattr_destroy(&attr);
 #endif
 stdout_opened:
 	close(stdout_pipe[0]);
diff --git a/Utilities/cmliblzma/CMakeLists.txt b/Utilities/cmliblzma/CMakeLists.txt
index 6ac02f0..e21117c 100644
--- a/Utilities/cmliblzma/CMakeLists.txt
+++ b/Utilities/cmliblzma/CMakeLists.txt
@@ -195,4 +195,4 @@
   target_precompile_headers(cmliblzma PRIVATE "common/mythread.h")
 endif()
 
-INSTALL(FILES COPYING DESTINATION ${CMAKE_DOC_DIR}/cmliblzma)
+INSTALL(FILES COPYING DESTINATION ${CMake_INSTALL_DOC_DIR}/cmliblzma)
diff --git a/Utilities/cmlibrhash/CMakeLists.txt b/Utilities/cmlibrhash/CMakeLists.txt
index 317c5f8..bec6ffd 100644
--- a/Utilities/cmlibrhash/CMakeLists.txt
+++ b/Utilities/cmlibrhash/CMakeLists.txt
@@ -39,4 +39,4 @@
 add_library(cmlibrhash ${librhash_sources})
 target_compile_definitions(cmlibrhash PRIVATE NO_IMPORT_EXPORT)
 
-install(FILES COPYING DESTINATION ${CMAKE_DOC_DIR}/cmlibrhash)
+install(FILES COPYING DESTINATION ${CMake_INSTALL_DOC_DIR}/cmlibrhash)
diff --git a/Utilities/cmlibuv/CMakeLists.txt b/Utilities/cmlibuv/CMakeLists.txt
index 495b5ed..027705a 100644
--- a/Utilities/cmlibuv/CMakeLists.txt
+++ b/Utilities/cmlibuv/CMakeLists.txt
@@ -341,4 +341,4 @@
   target_precompile_headers(cmlibuv PRIVATE "include/uv.h" "src/win/internal.h")
 endif()
 
-install(FILES LICENSE DESTINATION ${CMAKE_DOC_DIR}/cmlibuv)
+install(FILES LICENSE DESTINATION ${CMake_INSTALL_DOC_DIR}/cmlibuv)
diff --git a/Utilities/cmnghttp2/CMakeLists.txt b/Utilities/cmnghttp2/CMakeLists.txt
index 6d0c76f..d49693a 100644
--- a/Utilities/cmnghttp2/CMakeLists.txt
+++ b/Utilities/cmnghttp2/CMakeLists.txt
@@ -50,4 +50,4 @@
   ${CMAKE_CURRENT_SOURCE_DIR}/lib/includes
   )
 
-install(FILES COPYING DESTINATION ${CMAKE_DOC_DIR}/cmnghttp2)
+install(FILES COPYING DESTINATION ${CMake_INSTALL_DOC_DIR}/cmnghttp2)
diff --git a/Utilities/cmzlib/CMakeLists.txt b/Utilities/cmzlib/CMakeLists.txt
index ecbace6..6ac8896 100644
--- a/Utilities/cmzlib/CMakeLists.txt
+++ b/Utilities/cmzlib/CMakeLists.txt
@@ -25,4 +25,4 @@
   zutil.c
   )
 
-install(FILES Copyright.txt DESTINATION ${CMAKE_DOC_DIR}/cmzlib)
+install(FILES Copyright.txt DESTINATION ${CMake_INSTALL_DOC_DIR}/cmzlib)
diff --git a/Utilities/cmzstd/CMakeLists.txt b/Utilities/cmzstd/CMakeLists.txt
index e8bee76..6abfe69 100644
--- a/Utilities/cmzstd/CMakeLists.txt
+++ b/Utilities/cmzstd/CMakeLists.txt
@@ -52,4 +52,4 @@
   ZSTD_DISABLE_ASM=1
   )
 
-install(FILES LICENSE DESTINATION ${CMAKE_DOC_DIR}/cmzstd)
+install(FILES LICENSE DESTINATION ${CMake_INSTALL_DOC_DIR}/cmzstd)
diff --git a/Utilities/std/cm/type_traits b/Utilities/std/cm/type_traits
index 6bb6b5c..6126e71 100644
--- a/Utilities/std/cm/type_traits
+++ b/Utilities/std/cm/type_traits
@@ -11,27 +11,39 @@
 
 #if __cplusplus >= 201402L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)
 
-// Miscellaneous transformations
 template <bool B, typename T = void>
 using enable_if_t = std::enable_if_t<B, T>;
 
+using std::conditional_t;
+using std::decay_t;
+using std::remove_cv_t;
+using std::remove_reference_t;
+
 #else
 
-// Miscellaneous transformations
 template <bool B, typename T = void>
 using enable_if_t = typename std::enable_if<B, T>::type;
 
-#endif
+template <bool B, typename T, typename F>
+using conditional_t = typename std::conditional<B, T, F>::type;
+
+template <typename T>
+using decay_t = typename std::decay<T>::type;
+
+template <typename T>
+using remove_cv_t = typename std::remove_cv<T>::type;
+
+template <typename T>
+using remove_reference_t = typename std::remove_reference<T>::type;
+
+#endif // C++14 (_t aliases)
 
 #if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
 
-// Helper classes
 using std::bool_constant;
 
-// Miscellaneous transformations
 using std::invoke_result;
 using std::invoke_result_t;
-
 using std::void_t;
 
 #else
@@ -44,7 +56,7 @@
 template <typename F, typename... ArgTypes>
 using invoke_result = std::result_of<F(ArgTypes...)>;
 
-template <class F, typename... ArgTypes>
+template <typename F, typename... ArgTypes>
 using invoke_result_t = typename invoke_result<F, ArgTypes...>::type;
 
 template <typename... ArgTypes>
@@ -77,13 +89,13 @@
       !std::is_convertible<T, typename std::underlying_type<T>::type>::value>
 {
 };
-}
+} // namespace internals
 
 template <typename T>
 struct is_scoped_enum : public internals::is_scoped_enum_helper<T>
 {
 };
 
-#endif
+#endif // is_scoped_enum
 
 } // namespace cm
diff --git a/bootstrap b/bootstrap
index 12ba171..b7d608d 100755
--- a/bootstrap
+++ b/bootstrap
@@ -314,6 +314,7 @@
   cmCMakePath \
   cmCMakePathCommand \
   cmCMakePolicyCommand \
+  cmCMakeString \
   cmCPackPropertiesGenerator \
   cmCacheManager \
   cmCommands \