Merge topic 'modules-lang-specific-target-linked-dirs' into release-3.26

13810dee17 cmDependsFortran: require that dependency info files work
eed295fd8a cmGlobalNinjaGenerator: require that dependency info files work
837f7c113a cmCommonTargetGenerator: classify linked target directories by language
d19648a928 cmGeneratorTarget: add a method to query if Fortran sources exist
245a89d8b6 cmMakefileTargetGenerator: make "target linked info" variable Fortran-specific
aeb1b2ae3d cmMakefileTargetGenerator: simplify string streaming

Acked-by: Kitware Robot <kwrobot@kitware.com>
Tested-by: buildbot <buildbot@kitware.com>
Merge-request: !8146
diff --git a/Help/manual/cmake-configure-log.7.rst b/Help/manual/cmake-configure-log.7.rst
index a9c185d..72d4093 100644
--- a/Help/manual/cmake-configure-log.7.rst
+++ b/Help/manual/cmake-configure-log.7.rst
@@ -190,6 +190,8 @@
   directories:
     source: "/path/to/.../TryCompile-01234"
     binary: "/path/to/.../TryCompile-01234"
+  cmakeVariables:
+    SOME_VARIABLE: "Some Value"
   buildResult:
     variable: "COMPILE_RESULT"
     cached: true
@@ -217,6 +219,12 @@
     For non-project invocations, this is often the same as
     the source directory.
 
+``cmakeVariables``
+  An optional key that is present when CMake propagates variables
+  into the test project, either automatically or due to the
+  :variable:`CMAKE_TRY_COMPILE_PLATFORM_VARIABLES` variable.
+  Its value is a mapping from variable names to their values.
+
 ``buildResult``
   A mapping describing the result of compiling the test code.
   It has the following keys:
diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst
index 93c6d3e..fb84f5a 100644
--- a/Help/manual/cmake-properties.7.rst
+++ b/Help/manual/cmake-properties.7.rst
@@ -77,8 +77,6 @@
    /prop_dir/IMPORTED_TARGETS
    /prop_dir/INCLUDE_DIRECTORIES
    /prop_dir/INCLUDE_REGULAR_EXPRESSION
-   /prop_dir/INTERPROCEDURAL_OPTIMIZATION
-   /prop_dir/INTERPROCEDURAL_OPTIMIZATION_CONFIG
    /prop_dir/LABELS
    /prop_dir/LINK_DIRECTORIES
    /prop_dir/LINK_OPTIONS
@@ -621,6 +619,8 @@
 
    /prop_dir/ADDITIONAL_MAKE_CLEAN_FILES
    /prop_dir/COMPILE_DEFINITIONS_CONFIG
+   /prop_dir/INTERPROCEDURAL_OPTIMIZATION
+   /prop_dir/INTERPROCEDURAL_OPTIMIZATION_CONFIG
    /prop_dir/TEST_INCLUDE_FILE
 
 
diff --git a/Help/prop_dir/INTERPROCEDURAL_OPTIMIZATION.rst b/Help/prop_dir/INTERPROCEDURAL_OPTIMIZATION.rst
index 0c78dfb..6693a43 100644
--- a/Help/prop_dir/INTERPROCEDURAL_OPTIMIZATION.rst
+++ b/Help/prop_dir/INTERPROCEDURAL_OPTIMIZATION.rst
@@ -1,7 +1,6 @@
 INTERPROCEDURAL_OPTIMIZATION
 ----------------------------
 
-Enable interprocedural optimization for targets in a directory.
+This directory property does not exist anymore.
 
-If set to true, enables interprocedural optimizations if they are
-known to be supported by the compiler.
+See the target property :prop_tgt:`INTERPROCEDURAL_OPTIMIZATION` instead.
diff --git a/Help/prop_dir/INTERPROCEDURAL_OPTIMIZATION_CONFIG.rst b/Help/prop_dir/INTERPROCEDURAL_OPTIMIZATION_CONFIG.rst
index 840a1db..7ef1bb4 100644
--- a/Help/prop_dir/INTERPROCEDURAL_OPTIMIZATION_CONFIG.rst
+++ b/Help/prop_dir/INTERPROCEDURAL_OPTIMIZATION_CONFIG.rst
@@ -1,8 +1,6 @@
 INTERPROCEDURAL_OPTIMIZATION_<CONFIG>
 -------------------------------------
 
-Per-configuration interprocedural optimization for a directory.
+This directory property does not exist anymore.
 
-This is a per-configuration version of ``INTERPROCEDURAL_OPTIMIZATION``.
-If set, this property overrides the generic property for the named
-configuration.
+See the target property :prop_tgt:`INTERPROCEDURAL_OPTIMIZATION_<CONFIG>` instead.
diff --git a/Help/prop_sf/CXX_SCAN_FOR_MODULES.rst b/Help/prop_sf/CXX_SCAN_FOR_MODULES.rst
index 9d6c0a5..23c4859 100644
--- a/Help/prop_sf/CXX_SCAN_FOR_MODULES.rst
+++ b/Help/prop_sf/CXX_SCAN_FOR_MODULES.rst
@@ -17,3 +17,8 @@
 target and the source uses the ``CXX`` language.  Scanning for modules in
 sources belonging to file sets of type ``CXX_MODULES`` and
 ``CXX_MODULES_HEADER_UNITS`` is always performed.
+
+.. note ::
+
+  This setting is meaningful only when experimental support for C++ modules
+  has been enabled by the ``CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API`` gate.
diff --git a/Help/prop_tgt/CXX_SCAN_FOR_MODULES.rst b/Help/prop_tgt/CXX_SCAN_FOR_MODULES.rst
index 5e89ba2..e2127c2 100644
--- a/Help/prop_tgt/CXX_SCAN_FOR_MODULES.rst
+++ b/Help/prop_tgt/CXX_SCAN_FOR_MODULES.rst
@@ -20,3 +20,8 @@
 Note that scanning is only performed if C++20 or higher is enabled for the
 target.  Scanning for modules in the target's sources belonging to file sets
 of type ``CXX_MODULES`` and ``CXX_MODULES_HEADER_UNITS`` is always performed.
+
+.. note ::
+
+  This setting is meaningful only when experimental support for C++ modules
+  has been enabled by the ``CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API`` gate.
diff --git a/Help/prop_tgt/INTERPROCEDURAL_OPTIMIZATION.rst b/Help/prop_tgt/INTERPROCEDURAL_OPTIMIZATION.rst
index d3a5e94..0a4ac9a 100644
--- a/Help/prop_tgt/INTERPROCEDURAL_OPTIMIZATION.rst
+++ b/Help/prop_tgt/INTERPROCEDURAL_OPTIMIZATION.rst
@@ -11,3 +11,7 @@
 This property is initialized by the
 :variable:`CMAKE_INTERPROCEDURAL_OPTIMIZATION` variable if it is set when a
 target is created.
+
+There is also the per-configuration :prop_tgt:`INTERPROCEDURAL_OPTIMIZATION_<CONFIG>`
+target property, which overrides :prop_tgt:`INTERPROCEDURAL_OPTIMIZATION`
+if it is set.
diff --git a/Help/release/3.26.rst b/Help/release/3.26.rst
new file mode 100644
index 0000000..ff2e208
--- /dev/null
+++ b/Help/release/3.26.rst
@@ -0,0 +1,172 @@
+CMake 3.26 Release Notes
+************************
+
+.. only:: html
+
+  .. contents::
+
+Changes made since CMake 3.25 include the following.
+
+New Features
+============
+
+Languages
+---------
+
+* The ``ASM_MARMASM`` language was added to support the
+  Microsoft ARM assembler language.
+
+Command-Line
+------------
+
+* The :option:`cmake -E copy <cmake-E copy>` command-line tool now
+  supports a ``-t`` argument.
+
+* The :option:`cmake -E copy_directory_if_different
+  <cmake-E copy_directory_if_different>` command-line tool was added.
+
+Configure Log
+-------------
+
+* CMake now writes a YAML log of configure-time checks to
+  ``CMakeFiles/CMakeConfigureLog.yaml`` under the top of the build tree.
+  See the :manual:`cmake-configure-log(7)` manual.
+
+File-Based API
+--------------
+
+* The :manual:`cmake-file-api(7)` "codemodel" version 2 ``version`` field has
+  been updated to 2.5.
+
+* The :manual:`cmake-file-api(7)` "codemodel" version 2 "target" object
+  gained a new ``fileSets`` field and associated ``fileSetIndex``
+  field to ``sources`` objects.
+
+* The :manual:`cmake-file-api(7)` gained a new "configureLog" object kind
+  that enables stable access to the :manual:`cmake-configure-log(7)`.
+
+Commands
+--------
+
+* The :command:`add_custom_command` and :command:`add_custom_target` commands
+  now support :manual:`generator expressions <cmake-generator-expressions(7)>`
+  in their ``COMMENT`` option.
+
+* The :command:`message` command gained a ``CONFIGURE_LOG`` mode to
+  record an entry in the :manual:`cmake-configure-log(7)`.
+
+* The :command:`string(TIMESTAMP)` and :command:`file(TIMESTAMP)` commands
+  now support the ``%z`` and ``%Z`` specifiers for the time zone.
+
+* The :command:`try_compile` and :command:`try_run` commands gained
+  a ``LOG_DESCRIPTION`` option specifying text to be recorded in the
+  :manual:`cmake-configure-log(7)`.
+
+* The :command:`try_compile` and :command:`try_run` commands gained a
+  ``NO_LOG`` option to skip recording a :manual:`cmake-configure-log(7)`
+  entry.
+
+Variables
+---------
+
+* The :variable:`CMAKE_<LANG>_COMPILER_FRONTEND_VARIANT` variable is now
+  set for ``GNU``, ``MSVC``, and ``AppleClang`` compilers that have only
+  one frontend variant.
+
+* A :variable:`CMAKE_VS_VERSION_BUILD_NUMBER` variable is now set by
+  :ref:`Visual Studio Generators` for VS 2017 and above to report the
+  four-component Visual Studio version number.
+
+Properties
+----------
+
+* The :prop_tgt:`<LANG>_CLANG_TIDY_EXPORT_FIXES_DIR` target property was
+  added to allow the ``clang-tidy`` tool to export its suggested fixes to a
+  set of ``.yaml`` files. A new
+  :variable:`CMAKE_<LANG>_CLANG_TIDY_EXPORT_FIXES_DIR` variable was created to
+  initialize this property.
+
+* The :prop_tgt:`XCODE_EMBED_EXTENSIONKIT_EXTENSIONS <XCODE_EMBED_<type>>`
+  target property was added to tell the :generator:`Xcode` generator to
+  ExtensionKit-based extensions such as extensions using the Background
+  Assets framework.  Aspects of the embedding can be customized with:
+
+  * :prop_tgt:`XCODE_EMBED_EXTENSIONKIT_EXTENSIONS_PATH <XCODE_EMBED_<type>>`
+  * :prop_tgt:`XCODE_EMBED_EXTENSIONKIT_EXTENSIONS_CODE_SIGN_ON_COPY <XCODE_EMBED_<type>_CODE_SIGN_ON_COPY>`
+  * :prop_tgt:`XCODE_EMBED_EXTENSIONKIT_EXTENSIONS_REMOVE_HEADERS_ON_COPY <XCODE_EMBED_<type>_REMOVE_HEADERS_ON_COPY>`
+
+Modules
+-------
+
+* The :module:`ExternalProject` module :command:`ExternalProject_Add` command
+  gained an ``INSTALL_BYPRODUCTS`` option to specify files generated by the
+  ``install`` step.
+
+* The :module:`FindCUDAToolkit` module:
+
+  * gained support for the ``sbsa-linux`` cross compilation target, and
+
+  * now provides an imported target for ``nvrtc_static``, if found.
+
+* The :module:`FindImageMagick` module now provides imported targets.
+
+* The :module:`FindPython3` and :module:`FindPython` modules gained
+  support for the `Stable Application Binary Interface`_.
+
+* The :module:`UseSWIG` module gained the support for the ``perl5`` language.
+
+.. _`Stable Application Binary Interface`: https://docs.python.org/3/c-api/stable.html
+
+Generator Expressions
+---------------------
+
+* The :genex:`$<BUILD_LOCAL_INTERFACE:...>` generator expression was added to
+  prevent usage requirements from being exported to dependent projects.
+
+CTest
+-----
+
+* The :envvar:`CTEST_NO_TESTS_ACTION` environment variable was added to
+  provide a default value for the
+  :option:`--no-tests=\<action\> <ctest --no-tests>` command line
+  argument of :manual:`ctest(1)`.
+
+Deprecated and Removed Features
+===============================
+
+* The ``CMakeFiles/CMakeOutput.log`` and ``CMakeFiles/CMakeError.log``
+  files are no longer populated by CMake's builtin modules, and
+  :manual:`cmake(1)` no longer suggests looking at them after a
+  ``CMake Error`` occurs.  Information previously logged to those
+  files is instead logged to ``CMakeFiles/CMakeConfigureLog.yaml``,
+  the :manual:`cmake-configure-log(7)`.
+
+* On CYGWIN, the undocumented ``CMAKE_LEGACY_CYGWIN_WIN32`` mode for
+  compatibility with CMake versions older than 2.8.4 has been removed.
+
+Other Changes
+=============
+
+* :ref:`Language Standard Flags`, such as ``-std=c++11``, when generated due
+  to :command:`target_compile_features` or :variable:`CMAKE_<LANG>_STANDARD`,
+  are now placed before flags added by :command:`target_compile_options`,
+  rather than after them.
+
+* For all ``COMPILE_DEFINITIONS`` properties, any leading ``-D`` on an item
+  is removed whether or not it was specified by a generator expression.
+
+* The ``compile_commands.json`` database enabled by
+  :variable:`CMAKE_EXPORT_COMPILE_COMMANDS` now provides the ``output``
+  field in the compile commands objects.  This allows multi-config
+  generators, such as the :generator:`Ninja Multi-Config` generator,
+  to provide the compile commands for all configurations.
+
+* The :prop_gbl:`USE_FOLDERS` global property is treated as ``ON`` by default.
+  See policy :policy:`CMP0143`.
+
+* The top-level :command:`project` call will now emit an author warning if the
+  documented command order in relation to :command:`cmake_minimum_required` is
+  not respected.
+
+* The :option:`cmake --trace` option now follows :command:`try_compile` and
+  :command:`try_run` invocations.
diff --git a/Help/release/dev/0-sample-topic.rst b/Help/release/dev/0-sample-topic.rst
deleted file mode 100644
index e4cc01e..0000000
--- a/Help/release/dev/0-sample-topic.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-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/COMPILE_DEFINITIONS-property-cleanup.rst b/Help/release/dev/COMPILE_DEFINITIONS-property-cleanup.rst
deleted file mode 100644
index e24bc26..0000000
--- a/Help/release/dev/COMPILE_DEFINITIONS-property-cleanup.rst
+++ /dev/null
@@ -1,6 +0,0 @@
-COMPILE_DEFINITIONS-property-cleanup
-------------------------------------
-
-* For all ``COMPILE_DEFINITIONS`` properties, any leading ``-D`` on an item
-  will be removed regardless how to was defined: as is or inside a generator
-  expression.
diff --git a/Help/release/dev/ExternalProject-INSTALL_BYPRODUCTS.rst b/Help/release/dev/ExternalProject-INSTALL_BYPRODUCTS.rst
deleted file mode 100644
index 233596f..0000000
--- a/Help/release/dev/ExternalProject-INSTALL_BYPRODUCTS.rst
+++ /dev/null
@@ -1,6 +0,0 @@
-ExternalProject-INSTALL_BYPRODUCTS
-----------------------------------
-
-* The :module:`ExternalProject` module :command:`ExternalProject_Add` command
-  gained an ``INSTALL_BYPRODUCTS`` option to specify files generated by the
-  "install" step.
diff --git a/Help/release/dev/FindCUDAToolkit-arm64-sbsa.rst b/Help/release/dev/FindCUDAToolkit-arm64-sbsa.rst
deleted file mode 100644
index 55ddb99..0000000
--- a/Help/release/dev/FindCUDAToolkit-arm64-sbsa.rst
+++ /dev/null
@@ -1,4 +0,0 @@
-FindCUDAToolkit-arm64-sbsa
---------------------------
-
-* The :module:`FindCUDAToolkit` gained support for the `sbsa-linux` cross compilation target
diff --git a/Help/release/dev/FindCUDAToolkit-nvrtc.rst b/Help/release/dev/FindCUDAToolkit-nvrtc.rst
deleted file mode 100644
index 5f8bfdd..0000000
--- a/Help/release/dev/FindCUDAToolkit-nvrtc.rst
+++ /dev/null
@@ -1,5 +0,0 @@
-FindCUDAToolkit-nvrtc
----------------------
-
-* The :module:`FindCUDAToolkit` module now provides a target for
-  ``libnvrtc_static``, if found.
diff --git a/Help/release/dev/FindPython-Stable-ABI.rst b/Help/release/dev/FindPython-Stable-ABI.rst
deleted file mode 100644
index c6a06b9..0000000
--- a/Help/release/dev/FindPython-Stable-ABI.rst
+++ /dev/null
@@ -1,6 +0,0 @@
-FindPython-Stable-ABI
----------------------
-
-* The :module:`FindPython3` and :module:`FindPython` modules gain the support
-  of the
-  `Stable Application Binary Interface <https://docs.python.org/3/c-api/stable.html>`_.
diff --git a/Help/release/dev/UseSWIG-perl5.rst b/Help/release/dev/UseSWIG-perl5.rst
deleted file mode 100644
index 67d4161..0000000
--- a/Help/release/dev/UseSWIG-perl5.rst
+++ /dev/null
@@ -1,4 +0,0 @@
-UseSWIG-perl5
--------------
-
-* The :module:`UseSWIG` module gained the support of ``perl5`` language.
diff --git a/Help/release/dev/build-local-interface-genex.rst b/Help/release/dev/build-local-interface-genex.rst
deleted file mode 100644
index 7fe702e..0000000
--- a/Help/release/dev/build-local-interface-genex.rst
+++ /dev/null
@@ -1,5 +0,0 @@
-build-local-interface-genex
----------------------------
-
-* The :genex:`BUILD_LOCAL_INTERFACE` generator expression was added to
-  prevent usage requirements from being exported to dependent projects.
diff --git a/Help/release/dev/clang-tidy-export-fixes-dir.rst b/Help/release/dev/clang-tidy-export-fixes-dir.rst
deleted file mode 100644
index edb7ed5..0000000
--- a/Help/release/dev/clang-tidy-export-fixes-dir.rst
+++ /dev/null
@@ -1,8 +0,0 @@
-clang-tidy-export-fixes-dir
----------------------------
-
-* A new :prop_tgt:`<LANG>_CLANG_TIDY_EXPORT_FIXES_DIR` target property was
-  created to allow the ``clang-tidy`` tool to export its suggested fixes to a
-  set of ``.yaml`` files. A new
-  :variable:`CMAKE_<LANG>_CLANG_TIDY_EXPORT_FIXES_DIR` variable was created to
-  initialize this property.
diff --git a/Help/release/dev/cmake-E-copy-directory-if-different.rst b/Help/release/dev/cmake-E-copy-directory-if-different.rst
deleted file mode 100644
index 6e642c0..0000000
--- a/Help/release/dev/cmake-E-copy-directory-if-different.rst
+++ /dev/null
@@ -1,4 +0,0 @@
-cmake-E-copy-directory-if-different
------------------------------------
-
-* The :manual:`cmake(1)` ``-E`` option learned a new ``copy_directory_if_different`` command.
diff --git a/Help/release/dev/cmake-E-copy-t-arg.rst b/Help/release/dev/cmake-E-copy-t-arg.rst
deleted file mode 100644
index ca897d3..0000000
--- a/Help/release/dev/cmake-E-copy-t-arg.rst
+++ /dev/null
@@ -1,4 +0,0 @@
-cmake-E-copy-t-arg
-------------------
-
-* The :option:`cmake -E copy <cmake-E copy>` argument now supports a ``-t`` argument.
diff --git a/Help/release/dev/compile-commands-output-field.rst b/Help/release/dev/compile-commands-output-field.rst
deleted file mode 100644
index 110fd4e..0000000
--- a/Help/release/dev/compile-commands-output-field.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-compile-commands-output-field
------------------------------
-
-* The :prop_tgt:`EXPORT_COMPILE_COMMANDS` target property will now have the
-  ``output`` field in the compile commands objects. This allows multi-config
-  generators (namely :generator:`Ninja Multi-Config` generator) to contain the
-  compile commands for all configurations.
diff --git a/Help/release/dev/configure-log.rst b/Help/release/dev/configure-log.rst
deleted file mode 100644
index 588a54c..0000000
--- a/Help/release/dev/configure-log.rst
+++ /dev/null
@@ -1,19 +0,0 @@
-Configure Log
--------------
-
-* CMake now writes a YAML log of configure-time checks.
-  See the :manual:`cmake-configure-log(7)` manual.
-
-* The :manual:`cmake-file-api(7)` gained a new "configureLog" object kind
-  that enables stable access to the :manual:`cmake-configure-log(7)`.
-
-* The :command:`message` command gained a ``CONFIGURE_LOG`` mode to
-  record an entry in the :manual:`cmake-configure-log(7)`.
-
-* The :command:`try_compile` and :command:`try_run` commands gained
-  a ``LOG_DESCRIPTION`` option specifying text to be recorded in the
-  :manual:`cmake-configure-log(7)`.
-
-* The :command:`try_compile` and :command:`try_run` commands gained a
-  ``NO_LOG`` option to skip recording a :manual:`cmake-configure-log(7)`
-  entry.
diff --git a/Help/release/dev/ctest-no-tests-action-env-var.rst b/Help/release/dev/ctest-no-tests-action-env-var.rst
deleted file mode 100644
index 8679977..0000000
--- a/Help/release/dev/ctest-no-tests-action-env-var.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-ctest-no-tests-action-env-var
------------------------------
-
-* The :envvar:`CTEST_NO_TESTS_ACTION` environment variable was added to
-  provide a default value for the
-  :option:`--no-tests=\<action\> <ctest --no-tests>` command line
-  argument of :manual:`ctest(1)`.
diff --git a/Help/release/dev/custom-command-comment-genex.rst b/Help/release/dev/custom-command-comment-genex.rst
deleted file mode 100644
index f9402f2..0000000
--- a/Help/release/dev/custom-command-comment-genex.rst
+++ /dev/null
@@ -1,6 +0,0 @@
-custom-command-comment-genex
-----------------------------
-
-* :command:`add_custom_command` and :command:`add_custom_target` now
-  support :manual:`generator expressions <cmake-generator-expressions(7)>`
-  in their ``COMMENT`` option.
diff --git a/Help/release/dev/cxx-scanning-properties.rst b/Help/release/dev/cxx-scanning-properties.rst
deleted file mode 100644
index b393728..0000000
--- a/Help/release/dev/cxx-scanning-properties.rst
+++ /dev/null
@@ -1,5 +0,0 @@
-cxx-scanning-properties
------------------------
-
-* The :prop_tgt:`CXX_SCAN_FOR_MODULES` target and source file properties may
-  be used to enable or disable scanning for C++ module dependencies.
diff --git a/Help/release/dev/cygwin-no-legacy-win32.rst b/Help/release/dev/cygwin-no-legacy-win32.rst
deleted file mode 100644
index 7991138..0000000
--- a/Help/release/dev/cygwin-no-legacy-win32.rst
+++ /dev/null
@@ -1,5 +0,0 @@
-cygwin-no-legacy-win32
-----------------------
-
-* On CYGWIN, the undocumented ``CMAKE_LEGACY_CYGWIN_WIN32`` mode for
-  compatibility with CMake versions older than 2.8.4 has been removed.
diff --git a/Help/release/dev/file-api-file-sets.rst b/Help/release/dev/file-api-file-sets.rst
deleted file mode 100644
index 8a8b8d3..0000000
--- a/Help/release/dev/file-api-file-sets.rst
+++ /dev/null
@@ -1,9 +0,0 @@
-file-api-file-sets
-------------------
-
-* The :manual:`cmake-file-api(7)` "codemodel" version 2 ``version`` field has
-  been updated to 2.5.
-
-* The :manual:`cmake-file-api(7)` "codemodel" version 2 "target" object
-  gained a new ``fileSets`` field and associated ``fileSetIndex``
-  field to ``sources`` objects.
diff --git a/Help/release/dev/frontend-variant-always.rst b/Help/release/dev/frontend-variant-always.rst
deleted file mode 100644
index 111175c..0000000
--- a/Help/release/dev/frontend-variant-always.rst
+++ /dev/null
@@ -1,6 +0,0 @@
-frontend-variant-always
------------------------
-
-* The :variable:`CMAKE_<LANG>_COMPILER_FRONTEND_VARIANT` variable is now
-  set for ``GNU``, ``MSVC``, and ``AppleClang`` compilers that have only
-  one frontend variant.
diff --git a/Help/release/dev/lang-std-flag-order.rst b/Help/release/dev/lang-std-flag-order.rst
deleted file mode 100644
index 4ef4123..0000000
--- a/Help/release/dev/lang-std-flag-order.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-lang-std-flag-order
--------------------
-
-* :ref:`Language Standard Flags`, such as ``-std=c++11``, when generated due
-  to :command:`target_compile_features` or :variable:`CMAKE_<LANG>_STANDARD`,
-  are now placed before flags added by :command:`target_compile_options`,
-  rather than after them.
diff --git a/Help/release/dev/marmasm-language.rst b/Help/release/dev/marmasm-language.rst
deleted file mode 100644
index 2101e6c..0000000
--- a/Help/release/dev/marmasm-language.rst
+++ /dev/null
@@ -1,4 +0,0 @@
-marmasm-language
-----------------
-
-* The ``ASM_MARMASM`` language was added to support the Microsoft ARM assembler language.
diff --git a/Help/release/dev/timestamp-timezone.rst b/Help/release/dev/timestamp-timezone.rst
deleted file mode 100644
index 178fa9a..0000000
--- a/Help/release/dev/timestamp-timezone.rst
+++ /dev/null
@@ -1,5 +0,0 @@
-timestamp-timezone
-------------------
-
-* The :command:`string(TIMESTAMP)` and :command:`file(TIMESTAMP)` commands
-  now support the ``%z`` and ``%Z`` specifiers for the time zone.
diff --git a/Help/release/dev/top-level-command-order.rst b/Help/release/dev/top-level-command-order.rst
deleted file mode 100644
index 07f87fb..0000000
--- a/Help/release/dev/top-level-command-order.rst
+++ /dev/null
@@ -1,6 +0,0 @@
-top-level-command-order
------------------------
-
-* The top-level :command:`project` call will now emit an author warning if the
-  documented command order in relation to :command:`cmake_minimum_required` is
-  not respected.
diff --git a/Help/release/dev/trace-try_compile.rst b/Help/release/dev/trace-try_compile.rst
deleted file mode 100644
index 886aaad..0000000
--- a/Help/release/dev/trace-try_compile.rst
+++ /dev/null
@@ -1,5 +0,0 @@
-trace-try_compile
------------------
-
-* The :option:`cmake --trace` option now follows :command:`try_compile` and
-  :command:`try_run` invocations.
diff --git a/Help/release/dev/use-folder-on-by-default.rst b/Help/release/dev/use-folder-on-by-default.rst
deleted file mode 100644
index 4e91c2e..0000000
--- a/Help/release/dev/use-folder-on-by-default.rst
+++ /dev/null
@@ -1,5 +0,0 @@
-use-folder-on-by-default
-------------------------
-
-* Global property :prop_gbl:`USE_FOLDERS` is treated as ``ON`` by default.
-  See policy :policy:`CMP0143`.
diff --git a/Help/release/dev/vs-version-var.rst b/Help/release/dev/vs-version-var.rst
deleted file mode 100644
index 09daab7..0000000
--- a/Help/release/dev/vs-version-var.rst
+++ /dev/null
@@ -1,6 +0,0 @@
-vs-version-var
---------------
-
-* A :variable:`CMAKE_VS_VERSION_BUILD_NUMBER` variable is now set by
-  :ref:`Visual Studio Generators` for VS 2017 and above to report the
-  four-component Visual Studio version number.
diff --git a/Help/release/dev/xcode-ios-extensionkit.rst b/Help/release/dev/xcode-ios-extensionkit.rst
deleted file mode 100644
index b77b4ec..0000000
--- a/Help/release/dev/xcode-ios-extensionkit.rst
+++ /dev/null
@@ -1,11 +0,0 @@
-xcode-ios-extensionkit
-----------------------
-
-* The :prop_tgt:`XCODE_EMBED_EXTENSIONKIT_EXTENSIONS <XCODE_EMBED_<type>>` target property
-  was added to tell the :generator:`Xcode` generator to ExtensionKit-based extensions
-  such as extensions using the Background Assets framework.
-  Aspects of the embedding can be customized with the
-  :prop_tgt:`XCODE_EMBED_EXTENSIONKIT_EXTENSIONS_PATH <XCODE_EMBED_<type>>`,
-  :prop_tgt:`XCODE_EMBED_EXTENSIONKIT_EXTENSIONS_CODE_SIGN_ON_COPY <XCODE_EMBED_<type>_CODE_SIGN_ON_COPY>` and
-  :prop_tgt:`XCODE_EMBED_EXTENSIONKIT_EXTENSIONS_REMOVE_HEADERS_ON_COPY <XCODE_EMBED_<type>_REMOVE_HEADERS_ON_COPY>`
-  properties.
diff --git a/Help/release/index.rst b/Help/release/index.rst
index 50e06bb..c82889f 100644
--- a/Help/release/index.rst
+++ b/Help/release/index.rst
@@ -7,14 +7,13 @@
   This file should include the adjacent "dev.txt" file
   in development versions but not in release versions.
 
-.. include:: dev.txt
-
 Releases
 ========
 
 .. toctree::
    :maxdepth: 1
 
+   3.26 <3.26>
    3.25 <3.25>
    3.24 <3.24>
    3.23 <3.23>
diff --git a/Help/variable/CMAKE_CXX_SCAN_FOR_MODULES.rst b/Help/variable/CMAKE_CXX_SCAN_FOR_MODULES.rst
index 0d6c636..a40bf75 100644
--- a/Help/variable/CMAKE_CXX_SCAN_FOR_MODULES.rst
+++ b/Help/variable/CMAKE_CXX_SCAN_FOR_MODULES.rst
@@ -8,3 +8,8 @@
 This variable is used to initialize the :prop_tgt:`CXX_SCAN_FOR_MODULES`
 property on all the targets.  See that target property for additional
 information.
+
+.. note ::
+
+  This setting is meaningful only when experimental support for C++ modules
+  has been enabled by the ``CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API`` gate.
diff --git a/Modules/FindImageMagick.cmake b/Modules/FindImageMagick.cmake
index 2210e1b..6baf471 100644
--- a/Modules/FindImageMagick.cmake
+++ b/Modules/FindImageMagick.cmake
@@ -96,19 +96,13 @@
   Full path to <component> libraries.
 
 
-Example Usages:
-^^^^^^^^^^^^^^^
+Example Usage
+^^^^^^^^^^^^^
 
-  find_package(ImageMagick)
-  find_package(ImageMagick COMPONENTS convert)
-  find_package(ImageMagick COMPONENTS convert mogrify display)
+.. code-block:: cmake
+
   find_package(ImageMagick COMPONENTS Magick++)
-  find_package(ImageMagick COMPONENTS Magick++ convert)
-
   target_link_libraries(example PRIVATE ImageMagick::Magick++)
-
-Note that the standard :command:`find_package` features are supported (i.e.,
-``QUIET``, ``REQUIRED``, etc.).
 #]=======================================================================]
 
 find_package(PkgConfig QUIET)
diff --git a/Modules/FindThreads.cmake b/Modules/FindThreads.cmake
index 701c143..0fa6ae7 100644
--- a/Modules/FindThreads.cmake
+++ b/Modules/FindThreads.cmake
@@ -231,7 +231,7 @@
   if(THREADS_HAVE_PTHREAD_ARG)
     set_property(TARGET Threads::Threads
                  PROPERTY INTERFACE_COMPILE_OPTIONS "$<$<COMPILE_LANG_AND_ID:CUDA,NVIDIA>:SHELL:-Xcompiler -pthread>"
-                                                    "$<$<NOT:$<COMPILE_LANG_AND_ID:CUDA,NVIDIA>>:-pthread>")
+                                                    "$<$<AND:$<NOT:$<COMPILE_LANG_AND_ID:CUDA,NVIDIA>>,$<NOT:$<COMPILE_LANGUAGE:Swift>>>:-pthread>")
   endif()
 
   if(CMAKE_THREAD_LIBS_INIT)
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 66ffb9f..37be9c1 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,8 +1,8 @@
 # CMake version number components.
 set(CMake_VERSION_MAJOR 3)
-set(CMake_VERSION_MINOR 25)
-set(CMake_VERSION_PATCH 20230131)
-#set(CMake_VERSION_RC 0)
+set(CMake_VERSION_MINOR 26)
+set(CMake_VERSION_PATCH 0)
+set(CMake_VERSION_RC 0)
 set(CMake_VERSION_IS_DIRTY 0)
 
 # Start with the full version number used in tags.  It has no dev info.
diff --git a/Source/cmComputeComponentGraph.cxx b/Source/cmComputeComponentGraph.cxx
index 6591fb1..16540c3 100644
--- a/Source/cmComputeComponentGraph.cxx
+++ b/Source/cmComputeComponentGraph.cxx
@@ -4,6 +4,11 @@
 
 #include <algorithm>
 #include <cassert>
+#include <cstddef>
+#include <limits>
+
+const size_t cmComputeComponentGraph::INVALID_COMPONENT =
+  std::numeric_limits<size_t>::max();
 
 cmComputeComponentGraph::cmComputeComponentGraph(Graph const& input)
   : InputGraph(input)
@@ -25,16 +30,16 @@
 
 void cmComputeComponentGraph::Tarjan()
 {
-  int n = static_cast<int>(this->InputGraph.size());
+  size_t n = this->InputGraph.size();
   TarjanEntry entry = { 0, 0 };
   this->TarjanEntries.resize(0);
   this->TarjanEntries.resize(n, entry);
   this->TarjanComponents.resize(0);
-  this->TarjanComponents.resize(n, -1);
+  this->TarjanComponents.resize(n, INVALID_COMPONENT);
   this->TarjanWalkId = 0;
   this->TarjanVisited.resize(0);
   this->TarjanVisited.resize(n, 0);
-  for (int i = 0; i < n; ++i) {
+  for (size_t i = 0; i < n; ++i) {
     // Start a new DFS from this node if it has never been visited.
     if (!this->TarjanVisited[i]) {
       assert(this->TarjanStack.empty());
@@ -45,21 +50,21 @@
   }
 }
 
-void cmComputeComponentGraph::TarjanVisit(int i)
+void cmComputeComponentGraph::TarjanVisit(size_t i)
 {
   // We are now visiting this node.
   this->TarjanVisited[i] = this->TarjanWalkId;
 
   // Initialize the entry.
   this->TarjanEntries[i].Root = i;
-  this->TarjanComponents[i] = -1;
+  this->TarjanComponents[i] = INVALID_COMPONENT;
   this->TarjanEntries[i].VisitIndex = ++this->TarjanIndex;
   this->TarjanStack.push(i);
 
   // Follow outgoing edges.
   EdgeList const& nl = this->InputGraph[i];
   for (cmGraphEdge const& ni : nl) {
-    int j = ni;
+    size_t j = ni;
 
     // Ignore edges to nodes that have been reached by a previous DFS
     // walk.  Since we did not reach the current node from that walk
@@ -77,7 +82,7 @@
 
     // If the destination has not yet been assigned to a component,
     // check if it has a better root for the current object.
-    if (this->TarjanComponents[j] < 0) {
+    if (this->TarjanComponents[j] == INVALID_COMPONENT) {
       if (this->TarjanEntries[this->TarjanEntries[j].Root].VisitIndex <
           this->TarjanEntries[this->TarjanEntries[i].Root].VisitIndex) {
         this->TarjanEntries[i].Root = this->TarjanEntries[j].Root;
@@ -88,12 +93,12 @@
   // Check if we have found a component.
   if (this->TarjanEntries[i].Root == i) {
     // Yes.  Create it.
-    int c = static_cast<int>(this->Components.size());
+    size_t c = this->Components.size();
     this->Components.emplace_back();
     NodeList& component = this->Components[c];
 
     // Populate the component list.
-    int j;
+    size_t j;
     do {
       // Get the next member of the component.
       j = this->TarjanStack.top();
@@ -116,13 +121,13 @@
 {
   // Map inter-component edges in the original graph to edges in the
   // component graph.
-  int n = static_cast<int>(this->InputGraph.size());
-  for (int i = 0; i < n; ++i) {
-    int i_component = this->TarjanComponents[i];
+  size_t n = this->InputGraph.size();
+  for (size_t i = 0; i < n; ++i) {
+    size_t i_component = this->TarjanComponents[i];
     EdgeList const& nl = this->InputGraph[i];
     for (cmGraphEdge const& ni : nl) {
-      int j = ni;
-      int j_component = this->TarjanComponents[j];
+      size_t j = ni;
+      size_t j_component = this->TarjanComponents[j];
       if (i_component != j_component) {
         // We do not attempt to combine duplicate edges, but instead
         // store the inter-component edges with suitable multiplicity.
diff --git a/Source/cmComputeComponentGraph.h b/Source/cmComputeComponentGraph.h
index 1d1d134..878e36d 100644
--- a/Source/cmComputeComponentGraph.h
+++ b/Source/cmComputeComponentGraph.h
@@ -4,6 +4,7 @@
 
 #include "cmConfigure.h" // IWYU pragma: keep
 
+#include <cstddef>
 #include <stack>
 #include <vector>
 
@@ -35,7 +36,7 @@
 
   /** Get the adjacency list of the component graph.  */
   Graph const& GetComponentGraph() const { return this->ComponentGraph; }
-  EdgeList const& GetComponentGraphEdges(int c) const
+  EdgeList const& GetComponentGraphEdges(size_t c) const
   {
     return this->ComponentGraph[c];
   }
@@ -45,14 +46,16 @@
   {
     return this->Components;
   }
-  NodeList const& GetComponent(int c) const { return this->Components[c]; }
+  NodeList const& GetComponent(size_t c) const { return this->Components[c]; }
 
   /** Get map from original node index to component index.  */
-  std::vector<int> const& GetComponentMap() const
+  std::vector<size_t> const& GetComponentMap() const
   {
     return this->TarjanComponents;
   }
 
+  static const size_t INVALID_COMPONENT;
+
 private:
   void TransferEdges();
 
@@ -62,18 +65,18 @@
   // Tarjan's algorithm.
   struct TarjanEntry
   {
-    int Root;
-    int VisitIndex;
+    size_t Root;
+    size_t VisitIndex;
   };
-  std::vector<int> TarjanVisited;
-  std::vector<int> TarjanComponents;
+  std::vector<size_t> TarjanVisited;
+  std::vector<size_t> TarjanComponents;
   std::vector<TarjanEntry> TarjanEntries;
   std::vector<NodeList> Components;
-  std::stack<int> TarjanStack;
-  int TarjanWalkId;
-  int TarjanIndex;
+  std::stack<size_t> TarjanStack;
+  size_t TarjanWalkId;
+  size_t TarjanIndex;
   void Tarjan();
-  void TarjanVisit(int i);
+  void TarjanVisit(size_t i);
 
   // Connected components.
 };
diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx
index 8e05fac..5f408d0 100644
--- a/Source/cmComputeLinkDepends.cxx
+++ b/Source/cmComputeLinkDepends.cxx
@@ -4,6 +4,7 @@
 
 #include <algorithm>
 #include <cassert>
+#include <cstddef>
 #include <cstdio>
 #include <iterator>
 #include <sstream>
@@ -375,8 +376,8 @@
   // Compute the final set of link entries.
   // Iterate in reverse order so we can keep only the last occurrence
   // of a shared library.
-  std::set<int> emitted;
-  for (int i : cmReverseRange(this->FinalLinkOrder)) {
+  std::set<size_t> emitted;
+  for (size_t i : cmReverseRange(this->FinalLinkOrder)) {
     LinkEntry const& e = this->EntryList[i];
     cmGeneratorTarget const* t = e.Target;
     // Entries that we know the linker will re-use do not need to be repeated.
@@ -388,7 +389,7 @@
   // Place explicitly linked object files in the front.  The linker will
   // always use them anyway, and they may depend on symbols from libraries.
   // Append in reverse order since we reverse the final order below.
-  for (int i : cmReverseRange(this->ObjectEntries)) {
+  for (size_t i : cmReverseRange(this->ObjectEntries)) {
     this->FinalLinkEntries.emplace_back(this->EntryList[i]);
   }
   // Reverse the resulting order since we iterated in reverse.
@@ -432,11 +433,11 @@
   return it == this->LinkLibraryOverride.end() ? defaultFeature : it->second;
 }
 
-std::pair<std::map<cmLinkItem, int>::iterator, bool>
+std::pair<std::map<cmLinkItem, size_t>::iterator, bool>
 cmComputeLinkDepends::AllocateLinkEntry(cmLinkItem const& item)
 {
-  std::map<cmLinkItem, int>::value_type index_entry(
-    item, static_cast<int>(this->EntryList.size()));
+  std::map<cmLinkItem, size_t>::value_type index_entry(
+    item, static_cast<size_t>(this->EntryList.size()));
   auto lei = this->LinkEntryIndex.insert(index_entry);
   if (lei.second) {
     this->EntryList.emplace_back();
@@ -446,8 +447,8 @@
   return lei;
 }
 
-std::pair<int, bool> cmComputeLinkDepends::AddLinkEntry(cmLinkItem const& item,
-                                                        int groupIndex)
+std::pair<size_t, bool> cmComputeLinkDepends::AddLinkEntry(
+  cmLinkItem const& item, size_t groupIndex)
 {
   // Allocate a spot for the item entry.
   auto lei = this->AllocateLinkEntry(item);
@@ -459,7 +460,7 @@
   }
 
   // Initialize the item entry.
-  int index = lei.first->second;
+  size_t index = lei.first->second;
   LinkEntry& entry = this->EntryList[index];
   entry.Item = BT<std::string>(item.AsStr(), item.Backtrace);
   entry.Target = item.Target;
@@ -506,7 +507,7 @@
   }
 
   // Initialize the item entry.
-  int index = lei.first->second;
+  size_t index = lei.first->second;
   LinkEntry& entry = this->EntryList[index];
   entry.Item = BT<std::string>(item.AsStr(), item.Backtrace);
   entry.Kind = LinkEntry::Object;
@@ -518,7 +519,10 @@
 void cmComputeLinkDepends::FollowLinkEntry(BFSEntry qe)
 {
   // Get this entry representation.
-  int depender_index = qe.GroupIndex == -1 ? qe.Index : qe.GroupIndex;
+  size_t depender_index =
+    qe.GroupIndex == cmComputeComponentGraph::INVALID_COMPONENT
+    ? qe.Index
+    : qe.GroupIndex;
   LinkEntry const& entry = this->EntryList[qe.Index];
 
   // Follow the item's dependencies.
@@ -556,7 +560,7 @@
   }
 }
 
-void cmComputeLinkDepends::FollowSharedDeps(int depender_index,
+void cmComputeLinkDepends::FollowSharedDeps(size_t depender_index,
                                             cmLinkInterface const* iface,
                                             bool follow_interface)
 {
@@ -570,7 +574,7 @@
 }
 
 void cmComputeLinkDepends::QueueSharedDependencies(
-  int depender_index, std::vector<cmLinkItem> const& deps)
+  size_t depender_index, std::vector<cmLinkItem> const& deps)
 {
   for (cmLinkItem const& li : deps) {
     SharedDepEntry qe;
@@ -584,7 +588,7 @@
 {
   // Allocate a spot for the item entry.
   auto lei = this->AllocateLinkEntry(dep.Item);
-  int index = lei.first->second;
+  size_t index = lei.first->second;
 
   // Check if the target does not already has an entry.
   if (lei.second) {
@@ -617,7 +621,7 @@
   }
 }
 
-void cmComputeLinkDepends::AddVarLinkEntries(int depender_index,
+void cmComputeLinkDepends::AddVarLinkEntries(size_t depender_index,
                                              const char* value)
 {
   // This is called to add the dependencies named by
@@ -679,13 +683,15 @@
   // Add direct link dependencies in this configuration.
   cmLinkImplementation const* impl = this->Target->GetLinkImplementation(
     this->Config, cmGeneratorTarget::LinkInterfaceFor::Link);
-  this->AddLinkEntries(-1, impl->Libraries);
+  this->AddLinkEntries(cmComputeComponentGraph::INVALID_COMPONENT,
+                       impl->Libraries);
   this->AddLinkObjects(impl->Objects);
 
   for (auto const& language : impl->Languages) {
     auto runtimeEntries = impl->LanguageRuntimeLibraries.find(language);
     if (runtimeEntries != impl->LanguageRuntimeLibraries.end()) {
-      this->AddLinkEntries(-1, runtimeEntries->second);
+      this->AddLinkEntries(cmComputeComponentGraph::INVALID_COMPONENT,
+                           runtimeEntries->second);
     }
   }
   for (cmLinkItem const& wi : impl->WrongConfigLibraries) {
@@ -694,16 +700,18 @@
 }
 
 template <typename T>
-void cmComputeLinkDepends::AddLinkEntries(int depender_index,
+void cmComputeLinkDepends::AddLinkEntries(size_t depender_index,
                                           std::vector<T> const& libs)
 {
   // Track inferred dependency sets implied by this list.
-  std::map<int, DependSet> dependSets;
+  std::map<size_t, DependSet> dependSets;
   std::string feature = LinkEntry::DEFAULT;
 
   bool inGroup = false;
-  std::pair<int, bool> groupIndex{ -1, false };
-  std::vector<int> groupItems;
+  std::pair<size_t, bool> groupIndex{
+    cmComputeComponentGraph::INVALID_COMPONENT, false
+  };
+  std::vector<size_t> groupItems;
 
   // Loop over the libraries linked directly by the depender.
   for (T const& l : libs) {
@@ -719,7 +727,7 @@
       feature = ExtractFeature(item.AsStr());
       // emit a warning if an undefined feature is used as part of
       // an imported target
-      if (depender_index >= 0) {
+      if (depender_index != cmComputeComponentGraph::INVALID_COMPONENT) {
         const auto& depender = this->EntryList[depender_index];
         if (depender.Target != nullptr && depender.Target->IsImported() &&
             !IsFeatureSupported(this->Makefile, this->LinkLanguage, feature)) {
@@ -752,7 +760,7 @@
         entry.Feature = ExtractGroupFeature(item.AsStr());
       }
       inGroup = true;
-      if (depender_index >= 0) {
+      if (depender_index != cmComputeComponentGraph::INVALID_COMPONENT) {
         this->EntryConstraintGraph[depender_index].emplace_back(
           groupIndex.first, false, false, cmListFileBacktrace());
       } else {
@@ -762,7 +770,7 @@
       continue;
     }
 
-    int dependee_index;
+    size_t dependee_index;
 
     if (cmHasPrefix(item.AsStr(), LG_END) && cmHasSuffix(item.AsStr(), '>')) {
       dependee_index = groupIndex.first;
@@ -775,7 +783,8 @@
       continue;
     }
 
-    if (depender_index >= 0 && inGroup) {
+    if (depender_index != cmComputeComponentGraph::INVALID_COMPONENT &&
+        inGroup) {
       const auto& depender = this->EntryList[depender_index];
       const auto& groupFeature = this->EntryList[groupIndex.first].Feature;
       if (depender.Target != nullptr && depender.Target->IsImported() &&
@@ -895,7 +904,7 @@
       // store item index for dependencies handling
       groupItems.push_back(dependee_index);
     } else {
-      std::vector<int> indexes;
+      std::vector<size_t> indexes;
       bool entryHandled = false;
       // search any occurrence of the library in already defined groups
       for (const auto& group : this->GroupItems) {
@@ -913,7 +922,7 @@
 
       for (auto index : indexes) {
         // The dependee must come after the depender.
-        if (depender_index >= 0) {
+        if (depender_index != cmComputeComponentGraph::INVALID_COMPONENT) {
           this->EntryConstraintGraph[depender_index].emplace_back(
             index, false, false, cmListFileBacktrace());
         } else {
@@ -957,12 +966,12 @@
   }
 }
 
-cmLinkItem cmComputeLinkDepends::ResolveLinkItem(int depender_index,
+cmLinkItem cmComputeLinkDepends::ResolveLinkItem(size_t depender_index,
                                                  const std::string& name)
 {
   // Look for a target in the scope of the depender.
   cmGeneratorTarget const* from = this->Target;
-  if (depender_index >= 0) {
+  if (depender_index != cmComputeComponentGraph::INVALID_COMPONENT) {
     if (cmGeneratorTarget const* depender =
           this->EntryList[depender_index].Target) {
       from = depender;
@@ -976,7 +985,7 @@
   // The inferred dependency sets for each item list the possible
   // dependencies.  The intersection of the sets for one item form its
   // inferred dependencies.
-  for (unsigned int depender_index = 0;
+  for (size_t depender_index = 0;
        depender_index < this->InferredDependSets.size(); ++depender_index) {
     // Skip items for which dependencies do not need to be inferred or
     // for which the inferred dependency sets are empty.
@@ -1013,7 +1022,7 @@
   // over raw items by the group it belongs to, if any.
   for (auto& edgeList : this->EntryConstraintGraph) {
     for (auto& edge : edgeList) {
-      int index = edge;
+      size_t index = edge;
       if (this->EntryList[index].Kind == LinkEntry::Group ||
           this->EntryList[index].Kind == LinkEntry::Flag ||
           this->EntryList[index].Kind == LinkEntry::Object) {
@@ -1049,8 +1058,8 @@
 bool cmComputeLinkDepends::CheckCircularDependencies() const
 {
   std::vector<NodeList> const& components = this->CCG->GetComponents();
-  int nc = static_cast<int>(components.size());
-  for (int c = 0; c < nc; ++c) {
+  size_t nc = components.size();
+  for (size_t c = 0; c < nc; ++c) {
     // Get the current component.
     NodeList const& nl = components[c];
 
@@ -1061,7 +1070,7 @@
 
     // no group must be evolved
     bool cycleDetected = false;
-    for (int ni : nl) {
+    for (size_t ni : nl) {
       if (this->EntryList[ni].Kind == LinkEntry::Group) {
         cycleDetected = true;
         break;
@@ -1089,8 +1098,8 @@
       << this->Target->GetName()
       << "\", contains the following strongly connected component "
          "(cycle):\n";
-    std::vector<int> const& cmap = this->CCG->GetComponentMap();
-    for (int i : nl) {
+    std::vector<size_t> const& cmap = this->CCG->GetComponentMap();
+    for (size_t i : nl) {
       // Get the depender.
       LinkEntry const& depender = this->EntryList[i];
 
@@ -1100,7 +1109,7 @@
       // List its dependencies that are inside the component.
       EdgeList const& el = this->EntryConstraintGraph[i];
       for (cmGraphEdge const& ni : el) {
-        int j = ni;
+        size_t j = ni;
         if (cmap[j] == c) {
           LinkEntry const& dependee = this->EntryList[j];
           e << "    depends on " << formatItem(dependee) << "\n";
@@ -1120,7 +1129,7 @@
 {
   // Display the graph nodes and their edges.
   std::ostringstream e;
-  for (unsigned int i = 0; i < this->EntryConstraintGraph.size(); ++i) {
+  for (size_t i = 0; i < this->EntryConstraintGraph.size(); ++i) {
     EdgeList const& nl = this->EntryConstraintGraph[i];
     e << "item " << i << " is [" << this->EntryList[i].Item << "]\n";
     e << cmWrap("  item ", nl, " must follow it", "\n") << "\n";
@@ -1134,13 +1143,14 @@
   // from every entry to compute a topological order for the
   // components.
   Graph const& cgraph = this->CCG->GetComponentGraph();
-  int n = static_cast<int>(cgraph.size());
+  size_t n = cgraph.size();
   this->ComponentVisited.resize(cgraph.size(), 0);
   this->ComponentOrder.resize(cgraph.size(), n);
   this->ComponentOrderId = n;
   // Run in reverse order so the topological order will preserve the
   // original order where there are no constraints.
-  for (int c = n - 1; c >= 0; --c) {
+  for (size_t c = n - 1; c != cmComputeComponentGraph::INVALID_COMPONENT;
+       --c) {
     this->VisitComponent(c);
   }
 
@@ -1150,7 +1160,7 @@
   }
 
   // Start with the original link line.
-  for (int originalEntry : this->OriginalEntries) {
+  for (size_t originalEntry : this->OriginalEntries) {
     this->VisitEntry(originalEntry);
   }
 
@@ -1161,7 +1171,7 @@
     // logic will update the pending components accordingly.  Since
     // the pending components are kept in topological order this will
     // not repeat one.
-    int e = *this->PendingComponents.begin()->second.Entries.begin();
+    size_t e = *this->PendingComponents.begin()->second.Entries.begin();
     this->VisitEntry(e);
   }
 }
@@ -1170,24 +1180,24 @@
 {
   fprintf(stderr, "The strongly connected components are:\n");
   std::vector<NodeList> const& components = this->CCG->GetComponents();
-  for (unsigned int c = 0; c < components.size(); ++c) {
-    fprintf(stderr, "Component (%u):\n", c);
+  for (size_t c = 0; c < components.size(); ++c) {
+    fprintf(stderr, "Component (%zu):\n", c);
     NodeList const& nl = components[c];
-    for (int i : nl) {
-      fprintf(stderr, "  item %d [%s]\n", i,
+    for (size_t i : nl) {
+      fprintf(stderr, "  item %zu [%s]\n", i,
               this->EntryList[i].Item.Value.c_str());
     }
     EdgeList const& ol = this->CCG->GetComponentGraphEdges(c);
     for (cmGraphEdge const& oi : ol) {
-      int i = oi;
-      fprintf(stderr, "  followed by Component (%d)\n", i);
+      size_t i = oi;
+      fprintf(stderr, "  followed by Component (%zu)\n", i);
     }
-    fprintf(stderr, "  topo order index %d\n", this->ComponentOrder[c]);
+    fprintf(stderr, "  topo order index %zu\n", this->ComponentOrder[c]);
   }
   fprintf(stderr, "\n");
 }
 
-void cmComputeLinkDepends::VisitComponent(unsigned int c)
+void cmComputeLinkDepends::VisitComponent(size_t c)
 {
   // Check if the node has already been visited.
   if (this->ComponentVisited[c]) {
@@ -1209,14 +1219,14 @@
   this->ComponentOrder[c] = --this->ComponentOrderId;
 }
 
-void cmComputeLinkDepends::VisitEntry(int index)
+void cmComputeLinkDepends::VisitEntry(size_t index)
 {
   // Include this entry on the link line.
   this->FinalLinkOrder.push_back(index);
 
   // This entry has now been seen.  Update its component.
   bool completed = false;
-  int component = this->CCG->GetComponentMap()[index];
+  size_t component = this->CCG->GetComponentMap()[index];
   auto mi = this->PendingComponents.find(this->ComponentOrder[component]);
   if (mi != this->PendingComponents.end()) {
     // The entry is in an already pending component.
@@ -1267,7 +1277,7 @@
 }
 
 cmComputeLinkDepends::PendingComponent&
-cmComputeLinkDepends::MakePendingComponent(unsigned int component)
+cmComputeLinkDepends::MakePendingComponent(size_t component)
 {
   // Create an entry (in topological order) for the component.
   PendingComponent& pc =
@@ -1300,10 +1310,10 @@
   return pc;
 }
 
-int cmComputeLinkDepends::ComputeComponentCount(NodeList const& nl)
+size_t cmComputeLinkDepends::ComputeComponentCount(NodeList const& nl)
 {
-  unsigned int count = 2;
-  for (int ni : nl) {
+  size_t count = 2;
+  for (size_t ni : nl) {
     if (cmGeneratorTarget const* target = this->EntryList[ni].Target) {
       if (cmLinkInterface const* iface =
             target->GetLinkInterface(this->Config, this->Target)) {
diff --git a/Source/cmComputeLinkDepends.h b/Source/cmComputeLinkDepends.h
index 8cc916a..22c4e2a 100644
--- a/Source/cmComputeLinkDepends.h
+++ b/Source/cmComputeLinkDepends.h
@@ -4,6 +4,7 @@
 
 #include "cmConfigure.h" // IWYU pragma: keep
 
+#include <cstddef>
 #include <map>
 #include <memory>
 #include <queue>
@@ -12,12 +13,12 @@
 #include <utility>
 #include <vector>
 
+#include "cmComputeComponentGraph.h"
 #include "cmGraphAdjacencyList.h"
 #include "cmLinkItem.h"
 #include "cmListFileCache.h"
 #include "cmTargetLinkLibraryType.h"
 
-class cmComputeComponentGraph;
 class cmGeneratorTarget;
 class cmGlobalGenerator;
 class cmMakefile;
@@ -91,30 +92,31 @@
   std::string const& GetCurrentFeature(
     std::string const& item, std::string const& defaultFeature) const;
 
-  std::pair<std::map<cmLinkItem, int>::iterator, bool> AllocateLinkEntry(
+  std::pair<std::map<cmLinkItem, size_t>::iterator, bool> AllocateLinkEntry(
     cmLinkItem const& item);
-  std::pair<int, bool> AddLinkEntry(cmLinkItem const& item,
-                                    int groupIndex = -1);
+  std::pair<size_t, bool> AddLinkEntry(
+    cmLinkItem const& item,
+    size_t groupIndex = cmComputeComponentGraph::INVALID_COMPONENT);
   void AddLinkObject(cmLinkItem const& item);
-  void AddVarLinkEntries(int depender_index, const char* value);
+  void AddVarLinkEntries(size_t depender_index, const char* value);
   void AddDirectLinkEntries();
   template <typename T>
-  void AddLinkEntries(int depender_index, std::vector<T> const& libs);
+  void AddLinkEntries(size_t depender_index, std::vector<T> const& libs);
   void AddLinkObjects(std::vector<cmLinkItem> const& objs);
-  cmLinkItem ResolveLinkItem(int depender_index, const std::string& name);
+  cmLinkItem ResolveLinkItem(size_t depender_index, const std::string& name);
 
   // One entry for each unique item.
   std::vector<LinkEntry> EntryList;
-  std::map<cmLinkItem, int> LinkEntryIndex;
+  std::map<cmLinkItem, size_t> LinkEntryIndex;
 
   // map storing, for each group, the list of items
-  std::map<int, std::vector<int>> GroupItems;
+  std::map<size_t, std::vector<size_t>> GroupItems;
 
   // BFS of initial dependencies.
   struct BFSEntry
   {
-    int Index;
-    int GroupIndex;
+    size_t Index;
+    size_t GroupIndex;
     const char* LibDepends;
   };
   std::queue<BFSEntry> BFSQueue;
@@ -126,18 +128,18 @@
   struct SharedDepEntry
   {
     cmLinkItem Item;
-    int DependerIndex;
+    size_t DependerIndex;
   };
   std::queue<SharedDepEntry> SharedDepQueue;
-  std::set<int> SharedDepFollowed;
-  void FollowSharedDeps(int depender_index, cmLinkInterface const* iface,
+  std::set<size_t> SharedDepFollowed;
+  void FollowSharedDeps(size_t depender_index, cmLinkInterface const* iface,
                         bool follow_interface = false);
-  void QueueSharedDependencies(int depender_index,
+  void QueueSharedDependencies(size_t depender_index,
                                std::vector<cmLinkItem> const& deps);
   void HandleSharedDependency(SharedDepEntry const& dep);
 
   // Dependency inferral for each link item.
-  struct DependSet : public std::set<int>
+  struct DependSet : public std::set<size_t>
   {
   };
   struct DependSetList : public std::vector<DependSet>
@@ -162,41 +164,41 @@
   // Ordering algorithm.
   void OrderLinkEntries();
   std::vector<char> ComponentVisited;
-  std::vector<int> ComponentOrder;
+  std::vector<size_t> ComponentOrder;
 
   struct PendingComponent
   {
     // The real component id.  Needed because the map is indexed by
     // component topological index.
-    int Id;
+    size_t Id;
 
     // The number of times the component needs to be seen.  This is
     // always 1 for trivial components and is initially 2 for
     // non-trivial components.
-    int Count;
+    size_t Count;
 
     // The entries yet to be seen to complete the component.
-    std::set<int> Entries;
+    std::set<size_t> Entries;
   };
-  std::map<int, PendingComponent> PendingComponents;
+  std::map<size_t, PendingComponent> PendingComponents;
   std::unique_ptr<cmComputeComponentGraph> CCG;
-  std::vector<int> FinalLinkOrder;
+  std::vector<size_t> FinalLinkOrder;
   void DisplayComponents();
-  void VisitComponent(unsigned int c);
-  void VisitEntry(int index);
-  PendingComponent& MakePendingComponent(unsigned int component);
-  int ComputeComponentCount(NodeList const& nl);
+  void VisitComponent(size_t c);
+  void VisitEntry(size_t index);
+  PendingComponent& MakePendingComponent(size_t component);
+  size_t ComputeComponentCount(NodeList const& nl);
   void DisplayFinalEntries();
 
   // Record of the original link line.
-  std::vector<int> OriginalEntries;
+  std::vector<size_t> OriginalEntries;
   std::set<cmGeneratorTarget const*> OldWrongConfigItems;
   void CheckWrongConfigItem(cmLinkItem const& item);
 
   // Record of explicitly linked object files.
-  std::vector<int> ObjectEntries;
+  std::vector<size_t> ObjectEntries;
 
-  int ComponentOrderId;
+  size_t ComponentOrderId;
   cmTargetLinkLibraryType LinkType;
   bool HasConfig;
   bool DebugMode;
diff --git a/Source/cmComputeTargetDepends.cxx b/Source/cmComputeTargetDepends.cxx
index 3ff16a4..6763225 100644
--- a/Source/cmComputeTargetDepends.cxx
+++ b/Source/cmComputeTargetDepends.cxx
@@ -3,6 +3,7 @@
 #include "cmComputeTargetDepends.h"
 
 #include <cassert>
+#include <cstddef>
 #include <cstdio>
 #include <memory>
 #include <sstream>
@@ -159,7 +160,7 @@
   // this point.
   auto tii = this->TargetIndex.find(t);
   assert(tii != this->TargetIndex.end());
-  int i = tii->second;
+  size_t i = tii->second;
 
   // Get its final dependencies.
   EdgeList const& nl = this->FinalGraph[i];
@@ -178,7 +179,7 @@
   auto const& lgens = this->GlobalGenerator->GetLocalGenerators();
   for (const auto& lgen : lgens) {
     for (const auto& ti : lgen->GetGeneratorTargets()) {
-      int index = static_cast<int>(this->Targets.size());
+      size_t index = this->Targets.size();
       this->TargetIndex[ti.get()] = index;
       this->Targets.push_back(ti.get());
     }
@@ -191,12 +192,12 @@
   this->InitialGraph.resize(this->Targets.size());
 
   // Compute each dependency list.
-  for (unsigned int i = 0; i < this->Targets.size(); ++i) {
+  for (size_t i = 0; i < this->Targets.size(); ++i) {
     this->CollectTargetDepends(i);
   }
 }
 
-void cmComputeTargetDepends::CollectTargetDepends(int depender_index)
+void cmComputeTargetDepends::CollectTargetDepends(size_t depender_index)
 {
   // Get the depender.
   cmGeneratorTarget const* depender = this->Targets[depender_index];
@@ -261,7 +262,7 @@
 }
 
 void cmComputeTargetDepends::AddInterfaceDepends(
-  int depender_index, const cmGeneratorTarget* dependee,
+  size_t depender_index, const cmGeneratorTarget* dependee,
   cmListFileBacktrace const& dependee_backtrace, const std::string& config,
   std::set<cmLinkItem>& emitted)
 {
@@ -290,7 +291,7 @@
 }
 
 void cmComputeTargetDepends::AddInterfaceDepends(
-  int depender_index, cmLinkItem const& dependee_name,
+  size_t depender_index, cmLinkItem const& dependee_name,
   const std::string& config, std::set<cmLinkItem>& emitted)
 {
   cmGeneratorTarget const* depender = this->Targets[depender_index];
@@ -312,7 +313,7 @@
   }
 }
 
-void cmComputeTargetDepends::AddObjectDepends(int depender_index,
+void cmComputeTargetDepends::AddObjectDepends(size_t depender_index,
                                               cmSourceFile const* o,
                                               std::set<cmLinkItem>& emitted)
 {
@@ -340,7 +341,7 @@
   }
 }
 
-void cmComputeTargetDepends::AddTargetDepend(int depender_index,
+void cmComputeTargetDepends::AddTargetDepend(size_t depender_index,
                                              cmLinkItem const& dependee_name,
                                              bool linking, bool cross)
 {
@@ -394,7 +395,7 @@
 }
 
 void cmComputeTargetDepends::AddTargetDepend(
-  int depender_index, cmGeneratorTarget const* dependee,
+  size_t depender_index, cmGeneratorTarget const* dependee,
   cmListFileBacktrace const& dependee_backtrace, bool linking, bool cross)
 {
   if (!dependee->IsInBuildSystem()) {
@@ -412,7 +413,7 @@
     // this point.
     auto tii = this->TargetIndex.find(dependee);
     assert(tii != this->TargetIndex.end());
-    int dependee_index = tii->second;
+    size_t dependee_index = tii->second;
 
     // Add this entry to the dependency graph.
     this->InitialGraph[depender_index].emplace_back(dependee_index, !linking,
@@ -425,15 +426,15 @@
   this->SideEffects.resize(0);
   this->SideEffects.resize(this->InitialGraph.size());
 
-  int n = static_cast<int>(this->InitialGraph.size());
-  std::set<int> visited;
-  for (int i = 0; i < n; ++i) {
+  size_t n = this->InitialGraph.size();
+  std::set<size_t> visited;
+  for (size_t i = 0; i < n; ++i) {
     this->CollectSideEffectsForTarget(visited, i);
   }
 }
 
 void cmComputeTargetDepends::CollectSideEffectsForTarget(
-  std::set<int>& visited, int depender_index)
+  std::set<size_t>& visited, size_t depender_index)
 {
   if (!visited.count(depender_index)) {
     auto& se = this->SideEffects[depender_index];
@@ -461,8 +462,8 @@
   this->IntermediateGraph.resize(0);
   this->IntermediateGraph.resize(this->InitialGraph.size());
 
-  int n = static_cast<int>(this->InitialGraph.size());
-  for (int i = 0; i < n; ++i) {
+  size_t n = this->InitialGraph.size();
+  for (size_t i = 0; i < n; ++i) {
     auto const& initialEdges = this->InitialGraph[i];
     auto& intermediateEdges = this->IntermediateGraph[i];
     cmGeneratorTarget const* gt = this->Targets[i];
@@ -488,7 +489,7 @@
   cmGeneratorTarget const* gt, cmGraphEdgeList& outputEdges,
   cmGraphEdgeList const& inputEdges)
 {
-  std::set<int> emitted;
+  std::set<size_t> emitted;
   for (auto const& edge : inputEdges) {
     if (edge.IsStrong()) {
       // Preserve strong edges
@@ -529,16 +530,16 @@
                                           const std::string& name)
 {
   fprintf(stderr, "The %s target dependency graph is:\n", name.c_str());
-  int n = static_cast<int>(graph.size());
-  for (int depender_index = 0; depender_index < n; ++depender_index) {
+  size_t n = graph.size();
+  for (size_t depender_index = 0; depender_index < n; ++depender_index) {
     EdgeList const& nl = graph[depender_index];
     cmGeneratorTarget const* depender = this->Targets[depender_index];
-    fprintf(stderr, "target %d is [%s]\n", depender_index,
+    fprintf(stderr, "target %zu is [%s]\n", depender_index,
             depender->GetName().c_str());
     for (cmGraphEdge const& ni : nl) {
-      int dependee_index = ni;
+      size_t dependee_index = ni;
       cmGeneratorTarget const* dependee = this->Targets[dependee_index];
-      fprintf(stderr, "  depends on target %d [%s] (%s)\n", dependee_index,
+      fprintf(stderr, "  depends on target %zu [%s] (%s)\n", dependee_index,
               dependee->GetName().c_str(), ni.IsStrong() ? "strong" : "weak");
     }
   }
@@ -548,16 +549,16 @@
 void cmComputeTargetDepends::DisplaySideEffects()
 {
   fprintf(stderr, "The side effects are:\n");
-  int n = static_cast<int>(this->SideEffects.size());
-  for (int depender_index = 0; depender_index < n; ++depender_index) {
+  size_t n = this->SideEffects.size();
+  for (size_t depender_index = 0; depender_index < n; ++depender_index) {
     cmGeneratorTarget const* depender = this->Targets[depender_index];
-    fprintf(stderr, "target %d is [%s]\n", depender_index,
+    fprintf(stderr, "target %zu is [%s]\n", depender_index,
             depender->GetName().c_str());
     if (!this->SideEffects[depender_index].CustomCommandSideEffects.empty()) {
       fprintf(stderr, "  custom commands\n");
       for (auto const* gt :
            this->SideEffects[depender_index].CustomCommandSideEffects) {
-        fprintf(stderr, "    from target %d [%s]\n", this->TargetIndex[gt],
+        fprintf(stderr, "    from target %zu [%s]\n", this->TargetIndex[gt],
                 gt->GetName().c_str());
       }
     }
@@ -565,7 +566,7 @@
          this->SideEffects[depender_index].LanguageSideEffects) {
       fprintf(stderr, "  language %s\n", it.first.c_str());
       for (auto const* gt : it.second) {
-        fprintf(stderr, "    from target %d [%s]\n", this->TargetIndex[gt],
+        fprintf(stderr, "    from target %zu [%s]\n", this->TargetIndex[gt],
                 gt->GetName().c_str());
       }
     }
@@ -579,12 +580,12 @@
   fprintf(stderr, "The strongly connected components for the %s graph are:\n",
           name.c_str());
   std::vector<NodeList> const& components = ccg.GetComponents();
-  int n = static_cast<int>(components.size());
-  for (int c = 0; c < n; ++c) {
+  size_t n = components.size();
+  for (size_t c = 0; c < n; ++c) {
     NodeList const& nl = components[c];
-    fprintf(stderr, "Component (%d):\n", c);
-    for (int i : nl) {
-      fprintf(stderr, "  contains target %d [%s]\n", i,
+    fprintf(stderr, "Component (%zu):\n", c);
+    for (size_t i : nl) {
+      fprintf(stderr, "  contains target %zu [%s]\n", i,
               this->Targets[i]->GetName().c_str());
     }
   }
@@ -597,8 +598,8 @@
   // All non-trivial components should consist only of static
   // libraries.
   std::vector<NodeList> const& components = ccg.GetComponents();
-  int nc = static_cast<int>(components.size());
-  for (int c = 0; c < nc; ++c) {
+  size_t nc = components.size();
+  for (size_t c = 0; c < nc; ++c) {
     // Get the current component.
     NodeList const& nl = components[c];
 
@@ -614,7 +615,7 @@
     }
 
     // Make sure the component is all STATIC_LIBRARY targets.
-    for (int ni : nl) {
+    for (size_t ni : nl) {
       if (this->Targets[ni]->GetType() != cmStateEnums::STATIC_LIBRARY) {
         this->ComplainAboutBadComponent(ccg, c);
         return false;
@@ -625,16 +626,16 @@
 }
 
 void cmComputeTargetDepends::ComplainAboutBadComponent(
-  cmComputeComponentGraph const& ccg, int c, bool strong)
+  cmComputeComponentGraph const& ccg, size_t c, bool strong)
 {
   // Construct the error message.
   std::ostringstream e;
   e << "The inter-target dependency graph contains the following "
     << "strongly connected component (cycle):\n";
   std::vector<NodeList> const& components = ccg.GetComponents();
-  std::vector<int> const& cmap = ccg.GetComponentMap();
+  std::vector<size_t> const& cmap = ccg.GetComponentMap();
   NodeList const& cl = components[c];
-  for (int i : cl) {
+  for (size_t i : cl) {
     // Get the depender.
     cmGeneratorTarget const* depender = this->Targets[i];
 
@@ -645,7 +646,7 @@
     // List its dependencies that are inside the component.
     EdgeList const& nl = this->InitialGraph[i];
     for (cmGraphEdge const& ni : nl) {
-      int j = ni;
+      size_t j = ni;
       if (cmap[j] == c) {
         cmGeneratorTarget const* dependee = this->Targets[j];
         e << "    depends on \"" << dependee->GetName() << "\""
@@ -669,10 +670,10 @@
   cmSystemTools::Error(e.str());
 }
 
-bool cmComputeTargetDepends::IntraComponent(std::vector<int> const& cmap,
-                                            int c, int i, int* head,
-                                            std::set<int>& emitted,
-                                            std::set<int>& visited)
+bool cmComputeTargetDepends::IntraComponent(std::vector<size_t> const& cmap,
+                                            size_t c, size_t i, size_t* head,
+                                            std::set<size_t>& emitted,
+                                            std::set<size_t>& visited)
 {
   if (!visited.insert(i).second) {
     // Cycle in utility depends!
@@ -682,7 +683,7 @@
     // Honor strong intra-component edges in the final order.
     EdgeList const& el = this->InitialGraph[i];
     for (cmGraphEdge const& edge : el) {
-      int j = edge;
+      size_t j = edge;
       if (cmap[j] == c && edge.IsStrong()) {
         this->FinalGraph[i].emplace_back(j, true, edge.IsCross(),
                                          edge.GetBacktrace());
@@ -693,7 +694,7 @@
     }
 
     // Prepend to a linear linked-list of intra-component edges.
-    if (*head >= 0) {
+    if (*head != cmComputeComponentGraph::INVALID_COMPONENT) {
       this->FinalGraph[i].emplace_back(*head, false, false,
                                        cmListFileBacktrace());
     } else {
@@ -716,16 +717,16 @@
   this->FinalGraph.resize(this->InitialGraph.size());
 
   // Choose intra-component edges to linearize dependencies.
-  std::vector<int> const& cmap = ccg.GetComponentMap();
+  std::vector<size_t> const& cmap = ccg.GetComponentMap();
   this->ComponentHead.resize(components.size());
   this->ComponentTail.resize(components.size());
-  int nc = static_cast<int>(components.size());
-  for (int c = 0; c < nc; ++c) {
-    int head = -1;
-    std::set<int> emitted;
+  size_t nc = components.size();
+  for (size_t c = 0; c < nc; ++c) {
+    size_t head = cmComputeComponentGraph::INVALID_COMPONENT;
+    std::set<size_t> emitted;
     NodeList const& nl = components[c];
-    for (int ni : cmReverseRange(nl)) {
-      std::set<int> visited;
+    for (size_t ni : cmReverseRange(nl)) {
+      std::set<size_t> visited;
       if (!this->IntraComponent(cmap, c, ni, &head, emitted, visited)) {
         // Cycle in add_dependencies within component!
         this->ComplainAboutBadComponent(ccg, c, true);
@@ -736,14 +737,14 @@
   }
 
   // Convert inter-component edges to connect component tails to heads.
-  int n = static_cast<int>(cgraph.size());
-  for (int depender_component = 0; depender_component < n;
+  size_t n = cgraph.size();
+  for (size_t depender_component = 0; depender_component < n;
        ++depender_component) {
-    int depender_component_tail = this->ComponentTail[depender_component];
+    size_t depender_component_tail = this->ComponentTail[depender_component];
     EdgeList const& nl = cgraph[depender_component];
     for (cmGraphEdge const& ni : nl) {
-      int dependee_component = ni;
-      int dependee_component_head = this->ComponentHead[dependee_component];
+      size_t dependee_component = ni;
+      size_t dependee_component_head = this->ComponentHead[dependee_component];
       this->FinalGraph[depender_component_tail].emplace_back(
         dependee_component_head, ni.IsStrong(), ni.IsCross(),
         ni.GetBacktrace());
diff --git a/Source/cmComputeTargetDepends.h b/Source/cmComputeTargetDepends.h
index cdb66f8..3ed041b 100644
--- a/Source/cmComputeTargetDepends.h
+++ b/Source/cmComputeTargetDepends.h
@@ -4,6 +4,7 @@
 
 #include "cmConfigure.h" // IWYU pragma: keep
 
+#include <cstddef>
 #include <map>
 #include <set>
 #include <string>
@@ -51,28 +52,31 @@
 
   void CollectTargets();
   void CollectDepends();
-  void CollectTargetDepends(int depender_index);
-  void AddTargetDepend(int depender_index, cmLinkItem const& dependee_name,
+  void CollectTargetDepends(size_t depender_index);
+  void AddTargetDepend(size_t depender_index, cmLinkItem const& dependee_name,
                        bool linking, bool cross);
-  void AddTargetDepend(int depender_index, cmGeneratorTarget const* dependee,
+  void AddTargetDepend(size_t depender_index,
+                       cmGeneratorTarget const* dependee,
                        cmListFileBacktrace const& dependee_backtrace,
                        bool linking, bool cross);
   void CollectSideEffects();
-  void CollectSideEffectsForTarget(std::set<int>& visited, int depender_index);
+  void CollectSideEffectsForTarget(std::set<size_t>& visited,
+                                   size_t depender_index);
   void ComputeIntermediateGraph();
   void OptimizeLinkDependencies(cmGeneratorTarget const* gt,
                                 cmGraphEdgeList& outputEdges,
                                 cmGraphEdgeList const& inputEdges);
   bool ComputeFinalDepends(cmComputeComponentGraph const& ccg);
-  void AddInterfaceDepends(int depender_index, cmLinkItem const& dependee_name,
+  void AddInterfaceDepends(size_t depender_index,
+                           cmLinkItem const& dependee_name,
                            const std::string& config,
                            std::set<cmLinkItem>& emitted);
-  void AddInterfaceDepends(int depender_index,
+  void AddInterfaceDepends(size_t depender_index,
                            cmGeneratorTarget const* dependee,
                            cmListFileBacktrace const& dependee_backtrace,
                            const std::string& config,
                            std::set<cmLinkItem>& emitted);
-  void AddObjectDepends(int depender_index, cmSourceFile const* o,
+  void AddObjectDepends(size_t depender_index, cmSourceFile const* o,
                         std::set<cmLinkItem>& emitted);
   cmGlobalGenerator* GlobalGenerator;
   bool DebugMode;
@@ -80,7 +84,7 @@
 
   // Collect all targets.
   std::vector<cmGeneratorTarget const*> Targets;
-  std::map<cmGeneratorTarget const*, int> TargetIndex;
+  std::map<cmGeneratorTarget const*, size_t> TargetIndex;
 
   // Represent the target dependency graph.  The entry at each
   // top-level index corresponds to a depender whose dependencies are
@@ -99,11 +103,12 @@
   void DisplayComponents(cmComputeComponentGraph const& ccg,
                          const std::string& name);
   bool CheckComponents(cmComputeComponentGraph const& ccg);
-  void ComplainAboutBadComponent(cmComputeComponentGraph const& ccg, int c,
+  void ComplainAboutBadComponent(cmComputeComponentGraph const& ccg, size_t c,
                                  bool strong = false);
 
-  std::vector<int> ComponentHead;
-  std::vector<int> ComponentTail;
-  bool IntraComponent(std::vector<int> const& cmap, int c, int i, int* head,
-                      std::set<int>& emitted, std::set<int>& visited);
+  std::vector<size_t> ComponentHead;
+  std::vector<size_t> ComponentTail;
+  bool IntraComponent(std::vector<size_t> const& cmap, size_t c, size_t i,
+                      size_t* head, std::set<size_t>& emitted,
+                      std::set<size_t>& visited);
 };
diff --git a/Source/cmConfigureLog.cxx b/Source/cmConfigureLog.cxx
index 1b00b4f..a6658e2 100644
--- a/Source/cmConfigureLog.cxx
+++ b/Source/cmConfigureLog.cxx
@@ -136,7 +136,7 @@
   --this->Indent;
 }
 
-void cmConfigureLog::BeginEvent(std::string const& kind)
+void cmConfigureLog::BeginEvent(std::string const& kind, cmMakefile const& mf)
 {
   this->EnsureInit();
 
@@ -146,6 +146,8 @@
   ++this->Indent;
 
   this->WriteValue("kind"_s, kind);
+  this->WriteBacktrace(mf);
+  this->WriteChecks(mf);
 }
 
 void cmConfigureLog::EndEvent()
@@ -191,6 +193,30 @@
   this->EndObject();
 }
 
+void cmConfigureLog::WriteValue(cm::string_view key,
+                                std::map<std::string, std::string> const& map)
+{
+  static const std::string rawKeyChars = //
+    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"         //
+    "abcdefghijklmnopqrstuvwxyz"         //
+    "0123456789"                         //
+    "-_"                                 //
+    ;
+  this->BeginObject(key);
+  for (auto const& entry : map) {
+    if (entry.first.find_first_not_of(rawKeyChars) == std::string::npos) {
+      this->WriteValue(entry.first, entry.second);
+    } else {
+      this->BeginLine();
+      this->Encoder->write(entry.first, &this->Stream);
+      this->Stream << ": ";
+      this->Encoder->write(entry.second, &this->Stream);
+      this->EndLine();
+    }
+  }
+  this->EndObject();
+}
+
 void cmConfigureLog::WriteLiteralTextBlock(cm::string_view key,
                                            cm::string_view text)
 {
diff --git a/Source/cmConfigureLog.h b/Source/cmConfigureLog.h
index d672445..7edc3ed 100644
--- a/Source/cmConfigureLog.h
+++ b/Source/cmConfigureLog.h
@@ -2,6 +2,7 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #pragma once
 
+#include <map>
 #include <memory>
 #include <string>
 #include <vector>
@@ -28,12 +29,9 @@
       list is enabled.  */
   bool IsAnyLogVersionEnabled(std::vector<unsigned long> const& v) const;
 
-  void WriteBacktrace(cmMakefile const& mf);
-  void WriteChecks(cmMakefile const& mf);
-
   void EnsureInit();
 
-  void BeginEvent(std::string const& kind);
+  void BeginEvent(std::string const& kind, cmMakefile const& mf);
   void EndEvent();
 
   void BeginObject(cm::string_view key);
@@ -45,6 +43,8 @@
   void WriteValue(cm::string_view key, int value);
   void WriteValue(cm::string_view key, std::string const& value);
   void WriteValue(cm::string_view key, std::vector<std::string> const& list);
+  void WriteValue(cm::string_view key,
+                  std::map<std::string, std::string> const& map);
 
   void WriteTextBlock(cm::string_view key, cm::string_view text);
   void WriteLiteralTextBlock(cm::string_view key, cm::string_view text);
@@ -63,6 +63,9 @@
 
   std::unique_ptr<Json::StreamWriter> Encoder;
 
+  void WriteBacktrace(cmMakefile const& mf);
+  void WriteChecks(cmMakefile const& mf);
+
   cmsys::ofstream& BeginLine();
   void EndLine();
   void WriteEscape(unsigned char c);
diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx
index 618c794..acf1c20 100644
--- a/Source/cmCoreTryCompile.cxx
+++ b/Source/cmCoreTryCompile.cxx
@@ -471,6 +471,8 @@
     return cm::nullopt;
   }
 
+  std::map<std::string, std::string> cmakeVariables;
+
   std::string outFileName = this->BinaryDirectory + "/CMakeLists.txt";
   // which signature are we using? If we are using var srcfile bindir
   if (this->SrcFileSignature) {
@@ -592,6 +594,7 @@
             cmVersion::GetPatchVersion(), cmVersion::GetTweakVersion());
     if (def) {
       fprintf(fout, "set(CMAKE_MODULE_PATH \"%s\")\n", def->c_str());
+      cmakeVariables.emplace("CMAKE_MODULE_PATH", *def);
     }
 
     /* Set MSVC runtime library policy to match our selection.  */
@@ -653,10 +656,12 @@
             this->Makefile->GetDefinition(rulesOverrideLang)) {
         fprintf(fout, "set(%s \"%s\")\n", rulesOverrideLang.c_str(),
                 rulesOverridePath->c_str());
+        cmakeVariables.emplace(rulesOverrideLang, *rulesOverridePath);
       } else if (cmValue rulesOverridePath2 =
                    this->Makefile->GetDefinition(rulesOverrideBase)) {
         fprintf(fout, "set(%s \"%s\")\n", rulesOverrideBase.c_str(),
                 rulesOverridePath2->c_str());
+        cmakeVariables.emplace(rulesOverrideBase, *rulesOverridePath2);
       }
     }
     fprintf(fout, "project(CMAKE_TRY_COMPILE%s)\n", projectLangs.c_str());
@@ -687,6 +692,9 @@
               "set(CMAKE_%s_FLAGS \"${CMAKE_%s_FLAGS}"
               " ${COMPILE_DEFINITIONS}\")\n",
               li.c_str(), li.c_str());
+      if (flags) {
+        cmakeVariables.emplace(langFlags, *flags);
+      }
     }
     switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0066)) {
       case cmPolicies::WARN:
@@ -723,6 +731,9 @@
           cmValue flagsCfg = this->Makefile->GetDefinition(langFlagsCfg);
           fprintf(fout, "set(%s %s)\n", langFlagsCfg.c_str(),
                   cmOutputConverter::EscapeForCMake(*flagsCfg).c_str());
+          if (flagsCfg) {
+            cmakeVariables.emplace(langFlagsCfg, *flagsCfg);
+          }
         }
       } break;
     }
@@ -757,6 +768,9 @@
             this->Makefile->GetDefinition("CMAKE_EXE_LINKER_FLAGS");
           fprintf(fout, "set(CMAKE_EXE_LINKER_FLAGS %s)\n",
                   cmOutputConverter::EscapeForCMake(*exeLinkFlags).c_str());
+          if (exeLinkFlags) {
+            cmakeVariables.emplace("CMAKE_EXE_LINKER_FLAGS", *exeLinkFlags);
+          }
         }
         break;
     }
@@ -1044,12 +1058,14 @@
       vars.erase(kCMAKE_OSX_ARCHITECTURES);
       std::string flag = "-DCMAKE_OSX_ARCHITECTURES=" + *tcArchs;
       arguments.CMakeFlags.emplace_back(std::move(flag));
+      cmakeVariables.emplace("CMAKE_OSX_ARCHITECTURES", *tcArchs);
     }
 
     for (std::string const& var : vars) {
       if (cmValue val = this->Makefile->GetDefinition(var)) {
         std::string flag = "-D" + var + "=" + *val;
         arguments.CMakeFlags.emplace_back(std::move(flag));
+        cmakeVariables.emplace(var, *val);
       }
     }
   }
@@ -1060,6 +1076,7 @@
       if (cmValue val = this->Makefile->GetDefinition(var)) {
         std::string flag = "-D" + var + "=" + "'" + *val + "'";
         arguments.CMakeFlags.emplace_back(std::move(flag));
+        cmakeVariables.emplace(var, *val);
       }
     }
   }
@@ -1145,6 +1162,7 @@
   if (arguments.LogDescription) {
     result.LogDescription = *arguments.LogDescription;
   }
+  result.CMakeVariables = std::move(cmakeVariables);
   result.SourceDirectory = sourceDirectory;
   result.BinaryDirectory = this->BinaryDirectory;
   result.Variable = *arguments.CompileResultVariable;
@@ -1304,6 +1322,9 @@
   log.WriteValue("source"_s, compileResult.SourceDirectory);
   log.WriteValue("binary"_s, compileResult.BinaryDirectory);
   log.EndObject();
+  if (!compileResult.CMakeVariables.empty()) {
+    log.WriteValue("cmakeVariables"_s, compileResult.CMakeVariables);
+  }
   log.BeginObject("buildResult"_s);
   log.WriteValue("variable"_s, compileResult.Variable);
   log.WriteValue("cached"_s, compileResult.VariableCached);
diff --git a/Source/cmCoreTryCompile.h b/Source/cmCoreTryCompile.h
index 1ec4405..ba38c19 100644
--- a/Source/cmCoreTryCompile.h
+++ b/Source/cmCoreTryCompile.h
@@ -22,6 +22,7 @@
 struct cmTryCompileResult
 {
   cm::optional<std::string> LogDescription;
+  std::map<std::string, std::string> CMakeVariables;
 
   std::string SourceDirectory;
   std::string BinaryDirectory;
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index 8e6e706..f91879e 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -2975,7 +2975,8 @@
                               this->CreateString(extraLinkOptions));
   buildSettings->AddAttribute("OTHER_REZFLAGS", this->CreateString(""));
   buildSettings->AddAttribute("SECTORDER_FLAGS", this->CreateString(""));
-  buildSettings->AddAttribute("USE_HEADERMAP", this->CreateString("NO"));
+  buildSettings->AddAttribute("ALWAYS_SEARCH_USER_PATHS",
+                              this->CreateString("NO"));
   cmXCodeObject* group = this->CreateObject(cmXCodeObject::OBJECT_LIST);
   group->AddObject(this->CreateString("$(inherited)"));
   buildSettings->AddAttribute("WARNING_CFLAGS", group);
diff --git a/Source/cmGraphAdjacencyList.h b/Source/cmGraphAdjacencyList.h
index fe9fbe2..01fc5f9 100644
--- a/Source/cmGraphAdjacencyList.h
+++ b/Source/cmGraphAdjacencyList.h
@@ -4,6 +4,7 @@
 
 #include "cmConfigure.h" // IWYU pragma: keep
 
+#include <cstddef>
 #include <utility>
 #include <vector>
 
@@ -17,14 +18,14 @@
 class cmGraphEdge
 {
 public:
-  cmGraphEdge(int n, bool s, bool c, cmListFileBacktrace bt)
+  cmGraphEdge(size_t n, bool s, bool c, cmListFileBacktrace bt)
     : Dest(n)
     , Strong(s)
     , Cross(c)
     , Backtrace(std::move(bt))
   {
   }
-  operator int() const { return this->Dest; }
+  operator size_t() const { return this->Dest; }
 
   bool IsStrong() const { return this->Strong; }
 
@@ -33,7 +34,7 @@
   cmListFileBacktrace const& GetBacktrace() const { return this->Backtrace; }
 
 private:
-  int Dest;
+  size_t Dest;
   bool Strong;
   bool Cross;
   cmListFileBacktrace Backtrace;
@@ -41,7 +42,7 @@
 struct cmGraphEdgeList : public std::vector<cmGraphEdge>
 {
 };
-struct cmGraphNodeList : public std::vector<int>
+struct cmGraphNodeList : public std::vector<size_t>
 {
 };
 struct cmGraphAdjacencyList : public std::vector<cmGraphEdgeList>
diff --git a/Source/cmMessageCommand.cxx b/Source/cmMessageCommand.cxx
index 205f01f..52373f3 100644
--- a/Source/cmMessageCommand.cxx
+++ b/Source/cmMessageCommand.cxx
@@ -74,9 +74,7 @@
   static const std::vector<unsigned long> LogVersionsWithMessageV1{ 1 };
 
   if (log.IsAnyLogVersionEnabled(LogVersionsWithMessageV1)) {
-    log.BeginEvent("message-v1");
-    log.WriteBacktrace(mf);
-    log.WriteChecks(mf);
+    log.BeginEvent("message-v1", mf);
     log.WriteLiteralTextBlock("message"_s, message);
     log.EndEvent();
   }
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 37f9e98..debf593 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -4,7 +4,6 @@
 
 #include <algorithm>
 #include <cassert>
-#include <cstring>
 #include <initializer_list>
 #include <iterator>
 #include <map>
@@ -213,9 +212,16 @@
   FileSetEntries SelfEntries;
   FileSetEntries InterfaceEntries;
 
+  enum class Action
+  {
+    Set,
+    Append,
+  };
+
   template <typename ValueType>
   bool WriteProperties(cmTarget* tgt, cmTargetInternals* impl,
-                       const std::string& prop, ValueType value, bool clear);
+                       const std::string& prop, ValueType value,
+                       Action action);
   std::pair<bool, cmValue> ReadProperties(cmTarget const* tgt,
                                           cmTargetInternals const* impl,
                                           const std::string& prop) const;
@@ -223,6 +229,50 @@
   void AddFileSet(const std::string& name, cmFileSetVisibility vis,
                   cmListFileBacktrace bt);
 };
+
+struct UsageRequirementProperty
+{
+  enum class AppendEmpty
+  {
+    Yes,
+    No,
+  };
+
+  UsageRequirementProperty(cm::static_string_view name,
+                           AppendEmpty appendEmpty = AppendEmpty::No)
+    : Name(name)
+    , AppendBehavior(appendEmpty)
+  {
+  }
+
+  void CopyFromDirectory(cmBTStringRange directoryEntries)
+  {
+    return cm::append(this->Entries, directoryEntries);
+  }
+
+  enum class Action
+  {
+    Set,
+    Prepend,
+    Append,
+  };
+
+  template <typename ValueType>
+  bool Write(cmTargetInternals const* impl,
+             cm::optional<cmListFileBacktrace> const& bt,
+             const std::string& prop, ValueType value, Action action);
+  template <typename ValueType>
+  void WriteDirect(cmTargetInternals const* impl,
+                   cm::optional<cmListFileBacktrace> const& bt,
+                   ValueType value, Action action);
+  void WriteDirect(BT<std::string> value, Action action);
+  std::pair<bool, cmValue> Read(const std::string& prop) const;
+
+  cm::static_string_view const Name;
+  AppendEmpty const AppendBehavior;
+
+  std::vector<BT<std::string>> Entries;
+};
 }
 
 class cmTargetInternals
@@ -252,25 +302,26 @@
   std::set<std::string> SystemIncludeDirectories;
   cmTarget::LinkLibraryVectorType OriginalLinkLibraries;
   std::map<std::string, BTs<std::string>> LanguageStandardProperties;
-  std::vector<BT<std::string>> IncludeDirectoriesEntries;
   std::map<cmTargetExport const*, std::vector<std::string>>
     InstallIncludeDirectoriesEntries;
-  std::vector<BT<std::string>> CompileOptionsEntries;
-  std::vector<BT<std::string>> CompileFeaturesEntries;
-  std::vector<BT<std::string>> CompileDefinitionsEntries;
-  std::vector<BT<std::string>> PrecompileHeadersEntries;
-  std::vector<BT<std::string>> SourceEntries;
-  std::vector<BT<std::string>> LinkOptionsEntries;
-  std::vector<BT<std::string>> LinkDirectoriesEntries;
-  std::vector<BT<std::string>> LinkImplementationPropertyEntries;
-  std::vector<BT<std::string>> LinkInterfacePropertyEntries;
-  std::vector<BT<std::string>> LinkInterfaceDirectPropertyEntries;
-  std::vector<BT<std::string>> LinkInterfaceDirectExcludePropertyEntries;
   std::vector<std::pair<cmTarget::TLLSignature, cmListFileContext>>
     TLLCommands;
   std::map<std::string, cmFileSet> FileSets;
   cmListFileBacktrace Backtrace;
 
+  UsageRequirementProperty IncludeDirectories;
+  UsageRequirementProperty CompileOptions;
+  UsageRequirementProperty CompileFeatures;
+  UsageRequirementProperty CompileDefinitions;
+  UsageRequirementProperty PrecompileHeaders;
+  UsageRequirementProperty Sources;
+  UsageRequirementProperty LinkOptions;
+  UsageRequirementProperty LinkDirectories;
+  UsageRequirementProperty LinkLibraries;
+  UsageRequirementProperty InterfaceLinkLibraries;
+  UsageRequirementProperty InterfaceLinkLibrariesDirect;
+  UsageRequirementProperty InterfaceLinkLibrariesDirectExclude;
+
   FileSetType HeadersFileSets;
   FileSetType CxxModulesFileSets;
   FileSetType CxxModuleHeadersFileSets;
@@ -285,11 +336,13 @@
   template <typename ValueType>
   void AddDirectoryToFileSet(cmTarget* self, std::string const& fileSetName,
                              ValueType value, cm::string_view fileSetType,
-                             cm::string_view description, bool clear);
+                             cm::string_view description,
+                             FileSetType::Action action);
   template <typename ValueType>
   void AddPathToFileSet(cmTarget* self, std::string const& fileSetName,
                         ValueType value, cm::string_view fileSetType,
-                        cm::string_view description, bool clear);
+                        cm::string_view description,
+                        FileSetType::Action action);
   cmValue GetFileSetDirectories(cmTarget const* self,
                                 std::string const& fileSetName,
                                 cm::string_view fileSetType) const;
@@ -304,7 +357,20 @@
 };
 
 cmTargetInternals::cmTargetInternals()
-  : HeadersFileSets("HEADERS"_s, "HEADER_DIRS"_s, "HEADER_SET"_s,
+  : IncludeDirectories("INCLUDE_DIRECTORIES"_s)
+  , CompileOptions("COMPILE_OPTIONS"_s)
+  , CompileFeatures("COMPILE_FEATURES"_s)
+  , CompileDefinitions("COMPILE_DEFINITIONS"_s)
+  , PrecompileHeaders("PRECOMPILE_HEADERS"_s)
+  , Sources("SOURCES"_s, UsageRequirementProperty::AppendEmpty::Yes)
+  , LinkOptions("LINK_OPTIONS"_s)
+  , LinkDirectories("LINK_DIRECTORIES"_s)
+  , LinkLibraries("LINK_LIBRARIES"_s)
+  , InterfaceLinkLibraries("INTERFACE_LINK_LIBRARIES"_s)
+  , InterfaceLinkLibrariesDirect("INTERFACE_LINK_LIBRARIES_DIRECT"_s)
+  , InterfaceLinkLibrariesDirectExclude(
+      "INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE"_s)
+  , HeadersFileSets("HEADERS"_s, "HEADER_DIRS"_s, "HEADER_SET"_s,
                     "HEADER_DIRS_"_s, "HEADER_SET_"_s, "Header"_s,
                     "The default header set"_s, "Header set"_s,
                     FileSetEntries("HEADER_SETS"_s),
@@ -328,17 +394,17 @@
 template <typename ValueType>
 bool FileSetType::WriteProperties(cmTarget* tgt, cmTargetInternals* impl,
                                   const std::string& prop, ValueType value,
-                                  bool clear)
+                                  Action action)
 {
   if (prop == this->DefaultDirectoryProperty) {
     impl->AddDirectoryToFileSet(tgt, std::string(this->TypeName), value,
                                 this->TypeName, this->DefaultDescription,
-                                clear);
+                                action);
     return true;
   }
   if (prop == this->DefaultPathProperty) {
     impl->AddPathToFileSet(tgt, std::string(this->TypeName), value,
-                           this->TypeName, this->DefaultDescription, clear);
+                           this->TypeName, this->DefaultDescription, action);
     return true;
   }
   if (cmHasPrefix(prop, this->DirectoryPrefix)) {
@@ -350,7 +416,8 @@
     } else {
       impl->AddDirectoryToFileSet(
         tgt, fileSetName, value, this->TypeName,
-        cmStrCat(this->ArbitraryDescription, " \"", fileSetName, "\""), clear);
+        cmStrCat(this->ArbitraryDescription, " \"", fileSetName, "\""),
+        action);
     }
     return true;
   }
@@ -363,7 +430,8 @@
     } else {
       impl->AddPathToFileSet(
         tgt, fileSetName, value, this->TypeName,
-        cmStrCat(this->ArbitraryDescription, " \"", fileSetName, "\""), clear);
+        cmStrCat(this->ArbitraryDescription, " \"", fileSetName, "\""),
+        action);
     }
     return true;
   }
@@ -433,6 +501,67 @@
   }
 }
 
+template <typename ValueType>
+bool UsageRequirementProperty::Write(
+  cmTargetInternals const* impl, cm::optional<cmListFileBacktrace> const& bt,
+  const std::string& prop, ValueType value, Action action)
+{
+  if (prop == this->Name) {
+    this->WriteDirect(impl, bt, value, action);
+    return true;
+  }
+  return false;
+}
+
+template <typename ValueType>
+void UsageRequirementProperty::WriteDirect(
+  cmTargetInternals const* impl, cm::optional<cmListFileBacktrace> const& bt,
+  ValueType value, Action action)
+{
+  if (action == Action::Set) {
+    this->Entries.clear();
+  }
+  if (value) {
+    cmListFileBacktrace lfbt = impl->GetBacktrace(bt);
+    if (action == Action::Prepend) {
+      this->Entries.emplace(this->Entries.begin(), value, lfbt);
+    } else if (action == Action::Set || cmNonempty(value) ||
+               this->AppendBehavior == AppendEmpty::Yes) {
+      this->Entries.emplace_back(value, lfbt);
+    }
+  }
+}
+
+void UsageRequirementProperty::WriteDirect(BT<std::string> value,
+                                           Action action)
+{
+  if (action == Action::Set) {
+    this->Entries.clear();
+  }
+  if (action == Action::Prepend) {
+    this->Entries.emplace(this->Entries.begin(), std::move(value));
+  } else {
+    this->Entries.emplace_back(std::move(value));
+  }
+}
+
+std::pair<bool, cmValue> UsageRequirementProperty::Read(
+  const std::string& prop) const
+{
+  bool did_read = false;
+  cmValue value = nullptr;
+  if (prop == this->Name) {
+    if (!this->Entries.empty()) {
+      // Storage to back the returned `cmValue`.
+      static std::string output;
+      output = cmJoin(this->Entries, ";");
+      value = cmValue(output);
+    }
+    did_read = true;
+  }
+  return { did_read, value };
+}
+
 namespace {
 #define SETUP_COMMON_LANGUAGE_PROPERTIES(lang)                                \
   initProp(#lang "_COMPILER_LAUNCHER");                                       \
@@ -501,126 +630,186 @@
   // Setup default property values.
   if (this->CanCompileSources()) {
 
-    SETUP_COMMON_LANGUAGE_PROPERTIES(C);
-    SETUP_COMMON_LANGUAGE_PROPERTIES(OBJC);
-    SETUP_COMMON_LANGUAGE_PROPERTIES(CXX);
-    SETUP_COMMON_LANGUAGE_PROPERTIES(OBJCXX);
-    SETUP_COMMON_LANGUAGE_PROPERTIES(CUDA);
-    SETUP_COMMON_LANGUAGE_PROPERTIES(HIP);
-
+    // Compilation properties
+    initProp("INTERPROCEDURAL_OPTIMIZATION");
+    // initProp("INTERPROCEDURAL_OPTIMIZATION_<CONFIG>"); (per-config block)
+    initProp("NO_SYSTEM_FROM_IMPORTED");
+    initProp("VISIBILITY_INLINES_HIDDEN");
+    initProp("COMPILE_WARNING_AS_ERROR");
+    // -- Features
+    // ---- PCH
+    initProp("DISABLE_PRECOMPILE_HEADERS");
+    initPropValue("PCH_WARN_INVALID", "ON");
+    initPropValue("PCH_INSTANTIATE_TEMPLATES", "ON");
+    // -- Platforms
+    // ---- Android
     initProp("ANDROID_API");
     initProp("ANDROID_API_MIN");
     initProp("ANDROID_ARCH");
-    initProp("ANDROID_STL_TYPE");
-    initProp("ANDROID_SKIP_ANT_STEP");
-    initProp("ANDROID_PROCESS_MAX");
-    initProp("ANDROID_PROGUARD");
-    initProp("ANDROID_PROGUARD_CONFIG_PATH");
-    initProp("ANDROID_SECURE_PROPS_PATH");
-    initProp("ANDROID_NATIVE_LIB_DIRECTORIES");
-    initProp("ANDROID_NATIVE_LIB_DEPENDENCIES");
-    initProp("ANDROID_JAVA_SOURCE_DIR");
-    initProp("ANDROID_JAR_DIRECTORIES");
-    initProp("ANDROID_JAR_DEPENDENCIES");
     initProp("ANDROID_ASSETS_DIRECTORIES");
-    initProp("ANDROID_ANT_ADDITIONAL_OPTIONS");
-    initProp("BUILD_RPATH");
-    initProp("BUILD_RPATH_USE_ORIGIN");
-    initProp("CXX_SCAN_FOR_MODULES");
-    initProp("INSTALL_NAME_DIR");
-    initProp("INSTALL_REMOVE_ENVIRONMENT_RPATH");
-    initPropValue("INSTALL_RPATH", "");
-    initPropValue("INSTALL_RPATH_USE_LINK_PATH", "OFF");
-    initProp("INTERPROCEDURAL_OPTIMIZATION");
-    initPropValue("SKIP_BUILD_RPATH", "OFF");
-    initPropValue("BUILD_WITH_INSTALL_RPATH", "OFF");
-    initProp("ARCHIVE_OUTPUT_DIRECTORY");
-    initProp("LIBRARY_OUTPUT_DIRECTORY");
-    initProp("RUNTIME_OUTPUT_DIRECTORY");
-    initProp("PDB_OUTPUT_DIRECTORY");
-    initProp("COMPILE_PDB_OUTPUT_DIRECTORY");
-    initProp("FRAMEWORK");
-    initProp("FRAMEWORK_MULTI_CONFIG_POSTFIX");
+    initProp("ANDROID_JAVA_SOURCE_DIR");
+    initProp("ANDROID_STL_TYPE");
+    // ---- macOS
+    initProp("OSX_ARCHITECTURES");
+    // ---- Windows
+    initProp("MSVC_DEBUG_INFORMATION_FORMAT");
+    initProp("MSVC_RUNTIME_LIBRARY");
+    initProp("VS_JUST_MY_CODE_DEBUGGING");
+    // ---- OpenWatcom
+    initProp("WATCOM_RUNTIME_LIBRARY");
+    // -- Language
+    // ---- C
+    SETUP_COMMON_LANGUAGE_PROPERTIES(C);
+    // ---- C++
+    SETUP_COMMON_LANGUAGE_PROPERTIES(CXX);
+    // ---- CUDA
+    SETUP_COMMON_LANGUAGE_PROPERTIES(CUDA);
+    initProp("CUDA_SEPARABLE_COMPILATION");
+    initProp("CUDA_ARCHITECTURES");
+    // ---- Fortran
     initProp("Fortran_FORMAT");
     initProp("Fortran_MODULE_DIRECTORY");
     initProp("Fortran_COMPILER_LAUNCHER");
     initProp("Fortran_PREPROCESS");
     initProp("Fortran_VISIBILITY_PRESET");
-    initProp("GNUtoMS");
-    initProp("OSX_ARCHITECTURES");
-    initProp("IOS_INSTALL_COMBINED");
+    // ---- HIP
+    SETUP_COMMON_LANGUAGE_PROPERTIES(HIP);
+    initProp("HIP_ARCHITECTURES");
+    // ---- ISPC
+    initProp("ISPC_COMPILER_LAUNCHER");
+    initProp("ISPC_HEADER_DIRECTORY");
+    initPropValue("ISPC_HEADER_SUFFIX", "_ispc.h");
+    initProp("ISPC_INSTRUCTION_SETS");
+    // ---- Objective C
+    SETUP_COMMON_LANGUAGE_PROPERTIES(OBJC);
+    // ---- Objective C++
+    SETUP_COMMON_LANGUAGE_PROPERTIES(OBJCXX);
+    // ---- Swift
+    initProp("Swift_LANGUAGE_VERSION");
+    initProp("Swift_MODULE_DIRECTORY");
+    // ---- moc
     initProp("AUTOMOC");
-    initProp("AUTOUIC");
-    initProp("AUTORCC");
-    initProp("AUTOGEN_ORIGIN_DEPENDS");
-    initProp("AUTOGEN_PARALLEL");
     initProp("AUTOMOC_COMPILER_PREDEFINES");
-    initProp("AUTOMOC_DEPEND_FILTERS");
     initProp("AUTOMOC_MACRO_NAMES");
     initProp("AUTOMOC_MOC_OPTIONS");
-    initProp("AUTOUIC_OPTIONS");
     initProp("AUTOMOC_PATH_PREFIX");
+    // ---- uic
+    initProp("AUTOUIC");
+    initProp("AUTOUIC_OPTIONS");
     initProp("AUTOUIC_SEARCH_PATHS");
+    // ---- rcc
+    initProp("AUTORCC");
     initProp("AUTORCC_OPTIONS");
-    initProp("LINK_DEPENDS_NO_SHARED");
-    initProp("LINK_INTERFACE_LIBRARIES");
-    initProp("MSVC_DEBUG_INFORMATION_FORMAT");
-    initProp("MSVC_RUNTIME_LIBRARY");
-    initProp("WATCOM_RUNTIME_LIBRARY");
-    initProp("WIN32_EXECUTABLE");
-    initProp("MACOSX_BUNDLE");
+
+    // Linking properties
+    initProp("LINK_SEARCH_START_STATIC");
+    initProp("LINK_SEARCH_END_STATIC");
+    // -- Dependent library lookup
     initProp("MACOSX_RPATH");
-    initProp("NO_SYSTEM_FROM_IMPORTED");
+    // ---- Build
+    initProp("BUILD_RPATH");
+    initProp("BUILD_RPATH_USE_ORIGIN");
+    initPropValue("SKIP_BUILD_RPATH", "OFF");
+    initPropValue("BUILD_WITH_INSTALL_RPATH", "OFF");
     initProp("BUILD_WITH_INSTALL_NAME_DIR");
+    // ---- Install
+    initProp("INSTALL_NAME_DIR");
+    initProp("INSTALL_REMOVE_ENVIRONMENT_RPATH");
+    initPropValue("INSTALL_RPATH", "");
+    initPropValue("INSTALL_RPATH_USE_LINK_PATH", "OFF");
+    // -- Platforms
+    // ---- Android
+    initProp("ANDROID_JAR_DIRECTORIES");
+    initProp("ANDROID_JAR_DEPENDENCIES");
+    initProp("ANDROID_NATIVE_LIB_DIRECTORIES");
+    initProp("ANDROID_NATIVE_LIB_DEPENDENCIES");
+    initProp("ANDROID_PROGUARD");
+    initProp("ANDROID_PROGUARD_CONFIG_PATH");
+    initProp("ANDROID_SECURE_PROPS_PATH");
+    // ---- iOS
+    initProp("IOS_INSTALL_COMBINED");
+    // ---- Windows
+    initProp("GNUtoMS");
+    initProp("WIN32_EXECUTABLE");
+    // -- Languages
+    // ---- C
+    initProp("C_LINKER_LAUNCHER");
+    // ---- C++
+    initProp("CXX_LINKER_LAUNCHER");
+    // ---- CUDA
+    initProp("CUDA_RESOLVE_DEVICE_SYMBOLS");
+    initProp("CUDA_RUNTIME_LIBRARY");
+    // ---- HIP
+    initProp("HIP_RUNTIME_LIBRARY");
+    // ---- Objective C
+    initProp("OBJC_LINKER_LAUNCHER");
+    // ---- Objective C++
+    initProp("OBJCXX_LINKER_LAUNCHER");
+
+    // Static analysis
+    // -- C
     initProp("C_CLANG_TIDY");
     initProp("C_CLANG_TIDY_EXPORT_FIXES_DIR");
     initProp("C_CPPLINT");
     initProp("C_CPPCHECK");
     initProp("C_INCLUDE_WHAT_YOU_USE");
-    initProp("C_LINKER_LAUNCHER");
-    initProp("LINK_WHAT_YOU_USE");
+    // -- C++
     initProp("CXX_CLANG_TIDY");
     initProp("CXX_CLANG_TIDY_EXPORT_FIXES_DIR");
     initProp("CXX_CPPLINT");
     initProp("CXX_CPPCHECK");
     initProp("CXX_INCLUDE_WHAT_YOU_USE");
-    initProp("CXX_LINKER_LAUNCHER");
-    initProp("CUDA_SEPARABLE_COMPILATION");
-    initProp("CUDA_RESOLVE_DEVICE_SYMBOLS");
-    initProp("CUDA_RUNTIME_LIBRARY");
-    initProp("CUDA_ARCHITECTURES");
-    initProp("HIP_RUNTIME_LIBRARY");
-    initProp("HIP_ARCHITECTURES");
-    initProp("VISIBILITY_INLINES_HIDDEN");
+    // -- Objective C
+    initProp("OBJC_CLANG_TIDY");
+    initProp("OBJC_CLANG_TIDY_EXPORT_FIXES_DIR");
+    // -- Objective C++
+    initProp("OBJCXX_CLANG_TIDY");
+    initProp("OBJCXX_CLANG_TIDY_EXPORT_FIXES_DIR");
+    // -- Linking
+    initProp("LINK_WHAT_YOU_USE");
+
+    // Build graph properties
+    initProp("LINK_DEPENDS_NO_SHARED");
+    initProp("UNITY_BUILD");
+    initProp("UNITY_BUILD_UNIQUE_ID");
+    initPropValue("UNITY_BUILD_BATCH_SIZE", "8");
+    initPropValue("UNITY_BUILD_MODE", "BATCH");
+    initProp("OPTIMIZE_DEPENDENCIES");
+    // -- Android
+    initProp("ANDROID_ANT_ADDITIONAL_OPTIONS");
+    initProp("ANDROID_PROCESS_MAX");
+    initProp("ANDROID_SKIP_ANT_STEP");
+    // -- Autogen
+    initProp("AUTOGEN_ORIGIN_DEPENDS");
+    initProp("AUTOGEN_PARALLEL");
+    // -- moc
+    initProp("AUTOMOC_DEPEND_FILTERS");
+    // -- C++
+    initProp("CXX_SCAN_FOR_MODULES");
+    // -- Ninja
     initProp("JOB_POOL_COMPILE");
     initProp("JOB_POOL_LINK");
     initProp("JOB_POOL_PRECOMPILE_HEADER");
-    initProp("ISPC_COMPILER_LAUNCHER");
-    initProp("ISPC_HEADER_DIRECTORY");
-    initPropValue("ISPC_HEADER_SUFFIX", "_ispc.h");
-    initProp("ISPC_INSTRUCTION_SETS");
-    initProp("LINK_SEARCH_START_STATIC");
-    initProp("LINK_SEARCH_END_STATIC");
-    initProp("OBJC_CLANG_TIDY");
-    initProp("OBJC_CLANG_TIDY_EXPORT_FIXES_DIR");
-    initProp("OBJC_LINKER_LAUNCHER");
-    initProp("OBJCXX_CLANG_TIDY");
-    initProp("OBJCXX_CLANG_TIDY_EXPORT_FIXES_DIR");
-    initProp("OBJCXX_LINKER_LAUNCHER");
-    initProp("Swift_LANGUAGE_VERSION");
-    initProp("Swift_MODULE_DIRECTORY");
-    initProp("VS_JUST_MY_CODE_DEBUGGING");
+    // -- Visual Studio
     initProp("VS_NO_COMPILE_BATCHING");
-    initProp("DISABLE_PRECOMPILE_HEADERS");
-    initProp("UNITY_BUILD");
-    initProp("UNITY_BUILD_UNIQUE_ID");
-    initProp("OPTIMIZE_DEPENDENCIES");
+
+    // Output location properties
+    initProp("ARCHIVE_OUTPUT_DIRECTORY");
+    initProp("LIBRARY_OUTPUT_DIRECTORY");
+    initProp("RUNTIME_OUTPUT_DIRECTORY");
+    initProp("PDB_OUTPUT_DIRECTORY");
+    initProp("COMPILE_PDB_OUTPUT_DIRECTORY");
+
+    // -- macOS bundle properties
+    initProp("FRAMEWORK");
+    initProp("FRAMEWORK_MULTI_CONFIG_POSTFIX");
+    initProp("MACOSX_BUNDLE");
+
+    // Usage requirement properties
+    initProp("LINK_INTERFACE_LIBRARIES");
+
+    // Metadata
     initProp("EXPORT_COMPILE_COMMANDS");
-    initProp("COMPILE_WARNING_AS_ERROR");
-    initPropValue("UNITY_BUILD_BATCH_SIZE", "8");
-    initPropValue("UNITY_BUILD_MODE", "BATCH");
-    initPropValue("PCH_WARN_INVALID", "ON");
-    initPropValue("PCH_INSTANTIATE_TEMPLATES", "ON");
 
 #ifdef __APPLE__
     if (this->GetGlobalGenerator()->IsXcode()) {
@@ -664,10 +853,10 @@
       this->GetType() != cmStateEnums::GLOBAL_TARGET) {
     static const auto configProps = {
       /* clang-format needs this comment to break after the opening brace */
-      "ARCHIVE_OUTPUT_DIRECTORY_",     "LIBRARY_OUTPUT_DIRECTORY_",
-      "RUNTIME_OUTPUT_DIRECTORY_",     "PDB_OUTPUT_DIRECTORY_",
-      "COMPILE_PDB_OUTPUT_DIRECTORY_", "MAP_IMPORTED_CONFIG_",
-      "INTERPROCEDURAL_OPTIMIZATION_"
+      "ARCHIVE_OUTPUT_DIRECTORY_"_s,     "LIBRARY_OUTPUT_DIRECTORY_"_s,
+      "RUNTIME_OUTPUT_DIRECTORY_"_s,     "PDB_OUTPUT_DIRECTORY_"_s,
+      "COMPILE_PDB_OUTPUT_DIRECTORY_"_s, "MAP_IMPORTED_CONFIG_"_s,
+      "INTERPROCEDURAL_OPTIMIZATION_"_s
     };
     // Collect the set of configuration types.
     std::vector<std::string> configNames =
@@ -678,7 +867,7 @@
         // Interface libraries have no output locations, so honor only
         // the configuration map.
         if (this->impl->TargetType == cmStateEnums::INTERFACE_LIBRARY &&
-            strcmp(prop, "MAP_IMPORTED_CONFIG_") != 0) {
+            prop != "MAP_IMPORTED_CONFIG_") {
           continue;
         }
         std::string property = cmStrCat(prop, configUpper);
@@ -715,8 +904,8 @@
   if (!this->IsImported()) {
     // Initialize the INCLUDE_DIRECTORIES property based on the current value
     // of the same directory property:
-    cm::append(this->impl->IncludeDirectoriesEntries,
-               this->impl->Makefile->GetIncludeDirectoriesEntries());
+    this->impl->IncludeDirectories.CopyFromDirectory(
+      this->impl->Makefile->GetIncludeDirectoriesEntries());
 
     {
       auto const& sysInc = this->impl->Makefile->GetSystemIncludeDirectories();
@@ -724,14 +913,12 @@
                                                   sysInc.end());
     }
 
-    cm::append(this->impl->CompileOptionsEntries,
-               this->impl->Makefile->GetCompileOptionsEntries());
-
-    cm::append(this->impl->LinkOptionsEntries,
-               this->impl->Makefile->GetLinkOptionsEntries());
-
-    cm::append(this->impl->LinkDirectoriesEntries,
-               this->impl->Makefile->GetLinkDirectoriesEntries());
+    this->impl->CompileOptions.CopyFromDirectory(
+      this->impl->Makefile->GetCompileOptionsEntries());
+    this->impl->LinkOptions.CopyFromDirectory(
+      this->impl->Makefile->GetLinkOptionsEntries());
+    this->impl->LinkDirectories.CopyFromDirectory(
+      this->impl->Makefile->GetLinkDirectoriesEntries());
   }
 
   if (this->impl->TargetType == cmStateEnums::EXECUTABLE) {
@@ -858,7 +1045,7 @@
                                            const std::string& feature)
 {
   cmListFileBacktrace featureBacktrace;
-  for (auto const& entry : this->impl->CompileFeaturesEntries) {
+  for (auto const& entry : this->impl->CompileFeatures.Entries) {
     if (entry.Value == feature) {
       featureBacktrace = entry.Backtrace;
       break;
@@ -976,15 +1163,15 @@
 void cmTarget::AddTracedSources(std::vector<std::string> const& srcs)
 {
   if (!srcs.empty()) {
-    cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace();
-    this->impl->SourceEntries.emplace_back(cmJoin(srcs, ";"), lfbt);
+    this->impl->Sources.WriteDirect(this->impl.get(), {},
+                                    cmValue(cmJoin(srcs, ";")),
+                                    UsageRequirementProperty::Action::Append);
   }
 }
 
 void cmTarget::AddSources(std::vector<std::string> const& srcs)
 {
-  std::string srcFiles;
-  const char* sep = "";
+  std::vector<std::string> srcFiles;
   for (auto filename : srcs) {
     if (!cmGeneratorExpression::StartsWithGeneratorExpression(filename)) {
       if (!filename.empty()) {
@@ -995,14 +1182,9 @@
       }
       this->impl->Makefile->GetOrCreateSource(filename);
     }
-    srcFiles += sep;
-    srcFiles += filename;
-    sep = ";";
+    srcFiles.emplace_back(filename);
   }
-  if (!srcFiles.empty()) {
-    cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace();
-    this->impl->SourceEntries.emplace_back(std::move(srcFiles), lfbt);
-  }
+  this->AddTracedSources(srcFiles);
 }
 
 std::string cmTargetInternals::ProcessSourceItemCMP0049(
@@ -1106,13 +1288,13 @@
 {
   cmSourceFileLocation sfl(this->impl->Makefile, src,
                            cmSourceFileLocationKind::Known);
-  if (std::find_if(
-        this->impl->SourceEntries.begin(), this->impl->SourceEntries.end(),
-        TargetPropertyEntryFinder(sfl)) == this->impl->SourceEntries.end()) {
-    cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace();
-    this->impl->SourceEntries.insert(before ? this->impl->SourceEntries.begin()
-                                            : this->impl->SourceEntries.end(),
-                                     BT<std::string>(src, lfbt));
+  auto const& sources = this->impl->Sources.Entries;
+  if (std::find_if(sources.begin(), sources.end(),
+                   TargetPropertyEntryFinder(sfl)) == sources.end()) {
+    this->impl->Sources.WriteDirect(
+      this->impl.get(), {}, cmValue(src),
+      before ? UsageRequirementProperty::Action::Prepend
+             : UsageRequirementProperty::Action::Append);
   }
   if (cmGeneratorExpression::Find(src) != std::string::npos) {
     return nullptr;
@@ -1340,62 +1522,62 @@
 
 cmBTStringRange cmTarget::GetIncludeDirectoriesEntries() const
 {
-  return cmMakeRange(this->impl->IncludeDirectoriesEntries);
+  return cmMakeRange(this->impl->IncludeDirectories.Entries);
 }
 
 cmBTStringRange cmTarget::GetCompileOptionsEntries() const
 {
-  return cmMakeRange(this->impl->CompileOptionsEntries);
+  return cmMakeRange(this->impl->CompileOptions.Entries);
 }
 
 cmBTStringRange cmTarget::GetCompileFeaturesEntries() const
 {
-  return cmMakeRange(this->impl->CompileFeaturesEntries);
+  return cmMakeRange(this->impl->CompileFeatures.Entries);
 }
 
 cmBTStringRange cmTarget::GetCompileDefinitionsEntries() const
 {
-  return cmMakeRange(this->impl->CompileDefinitionsEntries);
+  return cmMakeRange(this->impl->CompileDefinitions.Entries);
 }
 
 cmBTStringRange cmTarget::GetPrecompileHeadersEntries() const
 {
-  return cmMakeRange(this->impl->PrecompileHeadersEntries);
+  return cmMakeRange(this->impl->PrecompileHeaders.Entries);
 }
 
 cmBTStringRange cmTarget::GetSourceEntries() const
 {
-  return cmMakeRange(this->impl->SourceEntries);
+  return cmMakeRange(this->impl->Sources.Entries);
 }
 
 cmBTStringRange cmTarget::GetLinkOptionsEntries() const
 {
-  return cmMakeRange(this->impl->LinkOptionsEntries);
+  return cmMakeRange(this->impl->LinkOptions.Entries);
 }
 
 cmBTStringRange cmTarget::GetLinkDirectoriesEntries() const
 {
-  return cmMakeRange(this->impl->LinkDirectoriesEntries);
+  return cmMakeRange(this->impl->LinkDirectories.Entries);
 }
 
 cmBTStringRange cmTarget::GetLinkImplementationEntries() const
 {
-  return cmMakeRange(this->impl->LinkImplementationPropertyEntries);
+  return cmMakeRange(this->impl->LinkLibraries.Entries);
 }
 
 cmBTStringRange cmTarget::GetLinkInterfaceEntries() const
 {
-  return cmMakeRange(this->impl->LinkInterfacePropertyEntries);
+  return cmMakeRange(this->impl->InterfaceLinkLibraries.Entries);
 }
 
 cmBTStringRange cmTarget::GetLinkInterfaceDirectEntries() const
 {
-  return cmMakeRange(this->impl->LinkInterfaceDirectPropertyEntries);
+  return cmMakeRange(this->impl->InterfaceLinkLibrariesDirect.Entries);
 }
 
 cmBTStringRange cmTarget::GetLinkInterfaceDirectExcludeEntries() const
 {
-  return cmMakeRange(this->impl->LinkInterfaceDirectExcludePropertyEntries);
+  return cmMakeRange(this->impl->InterfaceLinkLibrariesDirectExclude.Entries);
 }
 
 cmBTStringRange cmTarget::GetHeaderSetsEntries() const
@@ -1481,26 +1663,6 @@
   return std::string(*value);
 }
 
-template <typename ValueType>
-bool StringIsEmpty(ValueType const& value);
-
-template <>
-bool StringIsEmpty<const char*>(const char* const& value)
-{
-  return cmValue::IsEmpty(value);
-}
-
-template <>
-bool StringIsEmpty<cmValue>(cmValue const& value)
-{
-  return value.IsEmpty();
-}
-
-template <>
-bool StringIsEmpty<std::string>(std::string const& value)
-{
-  return value.empty();
-}
 }
 
 template <typename ValueType>
@@ -1544,80 +1706,42 @@
     return;
   }
 
-  if (prop == propINCLUDE_DIRECTORIES) {
-    this->impl->IncludeDirectoriesEntries.clear();
-    if (value) {
-      cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace();
-      this->impl->IncludeDirectoriesEntries.emplace_back(value, lfbt);
+  UsageRequirementProperty* usageRequirements[] = {
+    &this->impl->IncludeDirectories,
+    &this->impl->CompileOptions,
+    &this->impl->CompileFeatures,
+    &this->impl->CompileDefinitions,
+    &this->impl->PrecompileHeaders,
+    &this->impl->Sources,
+    &this->impl->LinkOptions,
+    &this->impl->LinkDirectories,
+    &this->impl->LinkLibraries,
+    &this->impl->InterfaceLinkLibraries,
+    &this->impl->InterfaceLinkLibrariesDirect,
+    &this->impl->InterfaceLinkLibrariesDirectExclude,
+  };
+
+  for (auto* usageRequirement : usageRequirements) {
+    if (usageRequirement->Write(this->impl.get(), {}, prop, value,
+                                UsageRequirementProperty::Action::Set)) {
+      return;
     }
-  } else if (prop == propCOMPILE_OPTIONS) {
-    this->impl->CompileOptionsEntries.clear();
-    if (value) {
-      cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace();
-      this->impl->CompileOptionsEntries.emplace_back(value, lfbt);
+  }
+
+  FileSetType* fileSetTypes[] = {
+    &this->impl->HeadersFileSets,
+    &this->impl->CxxModulesFileSets,
+    &this->impl->CxxModuleHeadersFileSets,
+  };
+
+  for (auto* fileSetType : fileSetTypes) {
+    if (fileSetType->WriteProperties(this, this->impl.get(), prop, value,
+                                     FileSetType::Action::Set)) {
+      return;
     }
-  } else if (prop == propCOMPILE_FEATURES) {
-    this->impl->CompileFeaturesEntries.clear();
-    if (value) {
-      cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace();
-      this->impl->CompileFeaturesEntries.emplace_back(value, lfbt);
-    }
-  } else if (prop == propCOMPILE_DEFINITIONS) {
-    this->impl->CompileDefinitionsEntries.clear();
-    if (value) {
-      cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace();
-      this->impl->CompileDefinitionsEntries.emplace_back(value, lfbt);
-    }
-  } else if (prop == propLINK_OPTIONS) {
-    this->impl->LinkOptionsEntries.clear();
-    if (value) {
-      cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace();
-      this->impl->LinkOptionsEntries.emplace_back(value, lfbt);
-    }
-  } else if (prop == propLINK_DIRECTORIES) {
-    this->impl->LinkDirectoriesEntries.clear();
-    if (value) {
-      cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace();
-      this->impl->LinkDirectoriesEntries.emplace_back(value, lfbt);
-    }
-  } else if (prop == propPRECOMPILE_HEADERS) {
-    this->impl->PrecompileHeadersEntries.clear();
-    if (value) {
-      cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace();
-      this->impl->PrecompileHeadersEntries.emplace_back(value, lfbt);
-    }
-  } else if (prop == propLINK_LIBRARIES) {
-    this->impl->LinkImplementationPropertyEntries.clear();
-    if (value) {
-      cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace();
-      this->impl->LinkImplementationPropertyEntries.emplace_back(value, lfbt);
-    }
-  } else if (prop == propINTERFACE_LINK_LIBRARIES) {
-    this->impl->LinkInterfacePropertyEntries.clear();
-    if (value) {
-      cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace();
-      this->impl->LinkInterfacePropertyEntries.emplace_back(value, lfbt);
-    }
-  } else if (prop == propINTERFACE_LINK_LIBRARIES_DIRECT) {
-    this->impl->LinkInterfaceDirectPropertyEntries.clear();
-    if (value) {
-      cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace();
-      this->impl->LinkInterfaceDirectPropertyEntries.emplace_back(value, lfbt);
-    }
-  } else if (prop == propINTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE) {
-    this->impl->LinkInterfaceDirectExcludePropertyEntries.clear();
-    if (value) {
-      cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace();
-      this->impl->LinkInterfaceDirectExcludePropertyEntries.emplace_back(value,
-                                                                         lfbt);
-    }
-  } else if (prop == propSOURCES) {
-    this->impl->SourceEntries.clear();
-    if (value) {
-      cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace();
-      this->impl->SourceEntries.emplace_back(value, lfbt);
-    }
-  } else if (prop == propIMPORTED_GLOBAL) {
+  }
+
+  if (prop == propIMPORTED_GLOBAL) {
     if (!cmIsOn(value)) {
       std::ostringstream e;
       e << "IMPORTED_GLOBAL property can't be set to FALSE on targets (\""
@@ -1685,15 +1809,6 @@
     } else {
       this->impl->LanguageStandardProperties.erase(prop);
     }
-  } else if (this->impl->HeadersFileSets.WriteProperties(
-               this, this->impl.get(), prop, value, true)) {
-    /* Handled in the `if` condition. */
-  } else if (this->impl->CxxModulesFileSets.WriteProperties(
-               this, this->impl.get(), prop, value, true)) {
-    /* Handled in the `if` condition. */
-  } else if (this->impl->CxxModuleHeadersFileSets.WriteProperties(
-               this, this->impl.get(), prop, value, true)) {
-    /* Handled in the `if` condition. */
   } else {
     this->impl->Properties.SetProperty(prop, value);
   }
@@ -1731,74 +1846,52 @@
     this->impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
     return;
   }
-  if (prop == "INCLUDE_DIRECTORIES") {
-    if (!value.empty()) {
-      cmListFileBacktrace lfbt = this->impl->GetBacktrace(bt);
-      this->impl->IncludeDirectoriesEntries.emplace_back(value, lfbt);
-    }
-  } else if (prop == "COMPILE_OPTIONS") {
-    if (!value.empty()) {
-      cmListFileBacktrace lfbt = this->impl->GetBacktrace(bt);
-      this->impl->CompileOptionsEntries.emplace_back(value, lfbt);
-    }
-  } else if (prop == "COMPILE_FEATURES") {
-    if (!value.empty()) {
-      cmListFileBacktrace lfbt = this->impl->GetBacktrace(bt);
-      this->impl->CompileFeaturesEntries.emplace_back(value, lfbt);
-    }
-  } else if (prop == "COMPILE_DEFINITIONS") {
-    if (!value.empty()) {
-      cmListFileBacktrace lfbt = this->impl->GetBacktrace(bt);
-      this->impl->CompileDefinitionsEntries.emplace_back(value, lfbt);
-    }
-  } else if (prop == "LINK_OPTIONS") {
-    if (!value.empty()) {
-      cmListFileBacktrace lfbt = this->impl->GetBacktrace(bt);
-      this->impl->LinkOptionsEntries.emplace_back(value, lfbt);
-    }
-  } else if (prop == "LINK_DIRECTORIES") {
-    if (!value.empty()) {
-      cmListFileBacktrace lfbt = this->impl->GetBacktrace(bt);
-      this->impl->LinkDirectoriesEntries.emplace_back(value, lfbt);
-    }
-  } else if (prop == "PRECOMPILE_HEADERS") {
-    if (this->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM")) {
-      std::ostringstream e;
-      e << "PRECOMPILE_HEADERS_REUSE_FROM property is already set on target "
-           "(\""
-        << this->impl->Name << "\")\n";
-      this->impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+  if (prop == propPRECOMPILE_HEADERS &&
+      this->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM")) {
+    std::ostringstream e;
+    e << "PRECOMPILE_HEADERS_REUSE_FROM property is already set on target "
+         "(\""
+      << this->impl->Name << "\")\n";
+    this->impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+    return;
+  }
+
+  UsageRequirementProperty* usageRequirements[] = {
+    &this->impl->IncludeDirectories,
+    &this->impl->CompileOptions,
+    &this->impl->CompileFeatures,
+    &this->impl->CompileDefinitions,
+    &this->impl->PrecompileHeaders,
+    &this->impl->Sources,
+    &this->impl->LinkOptions,
+    &this->impl->LinkDirectories,
+    &this->impl->LinkLibraries,
+    &this->impl->InterfaceLinkLibraries,
+    &this->impl->InterfaceLinkLibrariesDirect,
+    &this->impl->InterfaceLinkLibrariesDirectExclude,
+  };
+
+  for (auto* usageRequirement : usageRequirements) {
+    if (usageRequirement->Write(this->impl.get(), bt, prop, cmValue(value),
+                                UsageRequirementProperty::Action::Append)) {
       return;
     }
-    if (!value.empty()) {
-      cmListFileBacktrace lfbt = this->impl->GetBacktrace(bt);
-      this->impl->PrecompileHeadersEntries.emplace_back(value, lfbt);
+  }
+
+  FileSetType* fileSetTypes[] = {
+    &this->impl->HeadersFileSets,
+    &this->impl->CxxModulesFileSets,
+    &this->impl->CxxModuleHeadersFileSets,
+  };
+
+  for (auto* fileSetType : fileSetTypes) {
+    if (fileSetType->WriteProperties(this, this->impl.get(), prop, value,
+                                     FileSetType::Action::Append)) {
+      return;
     }
-  } else if (prop == "LINK_LIBRARIES") {
-    if (!value.empty()) {
-      cmListFileBacktrace lfbt = this->impl->GetBacktrace(bt);
-      this->impl->LinkImplementationPropertyEntries.emplace_back(value, lfbt);
-    }
-  } else if (prop == propINTERFACE_LINK_LIBRARIES) {
-    if (!value.empty()) {
-      cmListFileBacktrace lfbt = this->impl->GetBacktrace(bt);
-      this->impl->LinkInterfacePropertyEntries.emplace_back(value, lfbt);
-    }
-  } else if (prop == propINTERFACE_LINK_LIBRARIES_DIRECT) {
-    if (!value.empty()) {
-      cmListFileBacktrace lfbt = this->impl->GetBacktrace(bt);
-      this->impl->LinkInterfaceDirectPropertyEntries.emplace_back(value, lfbt);
-    }
-  } else if (prop == propINTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE) {
-    if (!value.empty()) {
-      cmListFileBacktrace lfbt = this->impl->GetBacktrace(bt);
-      this->impl->LinkInterfaceDirectExcludePropertyEntries.emplace_back(value,
-                                                                         lfbt);
-    }
-  } else if (prop == "SOURCES") {
-    cmListFileBacktrace lfbt = this->impl->GetBacktrace(bt);
-    this->impl->SourceEntries.emplace_back(value, lfbt);
-  } else if (cmHasLiteralPrefix(prop, "IMPORTED_LIBNAME")) {
+  }
+
+  if (cmHasLiteralPrefix(prop, "IMPORTED_LIBNAME")) {
     this->impl->Makefile->IssueMessage(
       MessageType::FATAL_ERROR, prop + " property may not be APPENDed.");
   } else if (prop == "C_STANDARD" || prop == "CXX_STANDARD" ||
@@ -1806,16 +1899,6 @@
              prop == "OBJC_STANDARD" || prop == "OBJCXX_STANDARD") {
     this->impl->Makefile->IssueMessage(
       MessageType::FATAL_ERROR, prop + " property may not be appended.");
-  } else if (this->impl->HeadersFileSets.WriteProperties(
-               this, this->impl.get(), prop, value,
-               false)) { // NOLINT(bugprone-branch-clone)
-    /* Handled in the `if` condition. */
-  } else if (this->impl->CxxModulesFileSets.WriteProperties(
-               this, this->impl.get(), prop, value, false)) {
-    /* Handled in the `if` condition. */
-  } else if (this->impl->CxxModuleHeadersFileSets.WriteProperties(
-               this, this->impl.get(), prop, value, false)) {
-    /* Handled in the `if` condition. */
   } else {
     this->impl->Properties.AppendProperty(prop, value, asString);
   }
@@ -1831,9 +1914,12 @@
 }
 
 template <typename ValueType>
-void cmTargetInternals::AddDirectoryToFileSet(
-  cmTarget* self, std::string const& fileSetName, ValueType value,
-  cm::string_view fileSetType, cm::string_view description, bool clear)
+void cmTargetInternals::AddDirectoryToFileSet(cmTarget* self,
+                                              std::string const& fileSetName,
+                                              ValueType value,
+                                              cm::string_view fileSetType,
+                                              cm::string_view description,
+                                              FileSetType::Action action)
 {
   auto* fileSet = self->GetFileSet(fileSetName);
   if (!fileSet) {
@@ -1849,19 +1935,22 @@
                                           "\"."));
     return;
   }
-  if (clear) {
+  if (action == FileSetType::Action::Set) {
     fileSet->ClearDirectoryEntries();
   }
-  if (!StringIsEmpty(value)) {
+  if (cmNonempty(value)) {
     fileSet->AddDirectoryEntry(
       BT<std::string>(value, this->Makefile->GetBacktrace()));
   }
 }
 
 template <typename ValueType>
-void cmTargetInternals::AddPathToFileSet(
-  cmTarget* self, std::string const& fileSetName, ValueType value,
-  cm::string_view fileSetType, cm::string_view description, bool clear)
+void cmTargetInternals::AddPathToFileSet(cmTarget* self,
+                                         std::string const& fileSetName,
+                                         ValueType value,
+                                         cm::string_view fileSetType,
+                                         cm::string_view description,
+                                         FileSetType::Action action)
 {
   auto* fileSet = self->GetFileSet(fileSetName);
   if (!fileSet) {
@@ -1877,10 +1966,10 @@
                                           "\"."));
     return;
   }
-  if (clear) {
+  if (action == FileSetType::Action::Set) {
     fileSet->ClearFileEntries();
   }
-  if (!StringIsEmpty(value)) {
+  if (cmNonempty(value)) {
     fileSet->AddFileEntry(
       BT<std::string>(value, this->Makefile->GetBacktrace()));
   }
@@ -1954,8 +2043,7 @@
 }
 
 namespace {
-bool CheckLinkLibraryPattern(cm::string_view property,
-                             const std::vector<BT<std::string>>& value,
+bool CheckLinkLibraryPattern(UsageRequirementProperty const& usage,
                              cmake* context)
 {
   // Look for <LINK_LIBRARY:> and </LINK_LIBRARY:> internal tags
@@ -1964,7 +2052,7 @@
 
   bool isValid = true;
 
-  for (const auto& item : value) {
+  for (const auto& item : usage.Entries) {
     if (!linkPattern.find(item.Value)) {
       continue;
     }
@@ -1975,8 +2063,8 @@
     context->IssueMessage(
       MessageType::FATAL_ERROR,
       cmStrCat(
-        "Property ", property, " contains the invalid item \"",
-        linkPattern.match(2), "\". The ", property,
+        "Property ", usage.Name, " contains the invalid item \"",
+        linkPattern.match(2), "\". The ", usage.Name,
         " property may contain the generator-expression \"$<LINK_",
         linkPattern.match(3),
         ":...>\" which may be used to specify how the libraries are linked."),
@@ -1995,14 +2083,11 @@
     return;
   }
 
-  if (!CheckLinkLibraryPattern("LINK_LIBRARIES"_s,
-                               this->impl->LinkImplementationPropertyEntries,
+  if (!CheckLinkLibraryPattern(this->impl->LinkLibraries,
                                this->GetMakefile()->GetCMakeInstance()) ||
-      !CheckLinkLibraryPattern("INTERFACE_LINK_LIBRARIES"_s,
-                               this->impl->LinkInterfacePropertyEntries,
+      !CheckLinkLibraryPattern(this->impl->InterfaceLinkLibraries,
                                this->GetMakefile()->GetCMakeInstance()) ||
-      !CheckLinkLibraryPattern("INTERFACE_LINK_LIBRARIES_DIRECT"_s,
-                               this->impl->LinkInterfaceDirectPropertyEntries,
+      !CheckLinkLibraryPattern(this->impl->InterfaceLinkLibrariesDirect,
                                this->GetMakefile()->GetCMakeInstance())) {
     return;
   }
@@ -2046,44 +2131,46 @@
 
 void cmTarget::InsertInclude(BT<std::string> const& entry, bool before)
 {
-  auto position = before ? this->impl->IncludeDirectoriesEntries.begin()
-                         : this->impl->IncludeDirectoriesEntries.end();
-
-  this->impl->IncludeDirectoriesEntries.insert(position, entry);
+  this->impl->IncludeDirectories.WriteDirect(
+    entry,
+    before ? UsageRequirementProperty::Action::Prepend
+           : UsageRequirementProperty::Action::Append);
 }
 
 void cmTarget::InsertCompileOption(BT<std::string> const& entry, bool before)
 {
-  auto position = before ? this->impl->CompileOptionsEntries.begin()
-                         : this->impl->CompileOptionsEntries.end();
-
-  this->impl->CompileOptionsEntries.insert(position, entry);
+  this->impl->CompileOptions.WriteDirect(
+    entry,
+    before ? UsageRequirementProperty::Action::Prepend
+           : UsageRequirementProperty::Action::Append);
 }
 
 void cmTarget::InsertCompileDefinition(BT<std::string> const& entry)
 {
-  this->impl->CompileDefinitionsEntries.push_back(entry);
+  this->impl->CompileDefinitions.WriteDirect(
+    entry, UsageRequirementProperty::Action::Append);
 }
 
 void cmTarget::InsertLinkOption(BT<std::string> const& entry, bool before)
 {
-  auto position = before ? this->impl->LinkOptionsEntries.begin()
-                         : this->impl->LinkOptionsEntries.end();
-
-  this->impl->LinkOptionsEntries.insert(position, entry);
+  this->impl->LinkOptions.WriteDirect(
+    entry,
+    before ? UsageRequirementProperty::Action::Prepend
+           : UsageRequirementProperty::Action::Append);
 }
 
 void cmTarget::InsertLinkDirectory(BT<std::string> const& entry, bool before)
 {
-  auto position = before ? this->impl->LinkDirectoriesEntries.begin()
-                         : this->impl->LinkDirectoriesEntries.end();
-
-  this->impl->LinkDirectoriesEntries.insert(position, entry);
+  this->impl->LinkDirectories.WriteDirect(
+    entry,
+    before ? UsageRequirementProperty::Action::Prepend
+           : UsageRequirementProperty::Action::Append);
 }
 
 void cmTarget::InsertPrecompileHeader(BT<std::string> const& entry)
 {
-  this->impl->PrecompileHeadersEntries.push_back(entry);
+  this->impl->PrecompileHeaders.WriteDirect(
+    entry, UsageRequirementProperty::Action::Append);
 }
 
 namespace {
@@ -2228,102 +2315,33 @@
       }
       return cmValue(propertyIter->second.Value);
     }
-    if (prop == propLINK_LIBRARIES) {
-      if (this->impl->LinkImplementationPropertyEntries.empty()) {
-        return nullptr;
-      }
 
-      static std::string output;
-      output = cmJoin(this->impl->LinkImplementationPropertyEntries, ";");
-      return cmValue(output);
-    }
-    if (prop == propINTERFACE_LINK_LIBRARIES) {
-      if (this->impl->LinkInterfacePropertyEntries.empty()) {
-        return nullptr;
-      }
+    UsageRequirementProperty const* usageRequirements[] = {
+      &this->impl->IncludeDirectories,
+      &this->impl->CompileOptions,
+      &this->impl->CompileFeatures,
+      &this->impl->CompileDefinitions,
+      &this->impl->PrecompileHeaders,
+      &this->impl->Sources,
+      &this->impl->LinkOptions,
+      &this->impl->LinkDirectories,
+      &this->impl->LinkLibraries,
+      &this->impl->InterfaceLinkLibraries,
+      &this->impl->InterfaceLinkLibrariesDirect,
+      &this->impl->InterfaceLinkLibrariesDirectExclude,
+    };
 
-      static std::string output;
-      output = cmJoin(this->impl->LinkInterfacePropertyEntries, ";");
-      return cmValue(output);
-    }
-    if (prop == propINTERFACE_LINK_LIBRARIES_DIRECT) {
-      if (this->impl->LinkInterfaceDirectPropertyEntries.empty()) {
-        return nullptr;
+    for (auto const* usageRequirement : usageRequirements) {
+      auto value = usageRequirement->Read(prop);
+      if (value.first) {
+        return value.second;
       }
-
-      static std::string output;
-      output = cmJoin(this->impl->LinkInterfaceDirectPropertyEntries, ";");
-      return cmValue(output);
     }
-    if (prop == propINTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE) {
-      if (this->impl->LinkInterfaceDirectExcludePropertyEntries.empty()) {
-        return nullptr;
-      }
 
-      static std::string output;
-      output =
-        cmJoin(this->impl->LinkInterfaceDirectExcludePropertyEntries, ";");
-      return cmValue(output);
-    }
     // the type property returns what type the target is
     if (prop == propTYPE) {
       return cmValue(cmState::GetTargetTypeName(this->GetType()));
     }
-    if (prop == propINCLUDE_DIRECTORIES) {
-      if (this->impl->IncludeDirectoriesEntries.empty()) {
-        return nullptr;
-      }
-
-      static std::string output;
-      output = cmJoin(this->impl->IncludeDirectoriesEntries, ";");
-      return cmValue(output);
-    }
-    if (prop == propCOMPILE_FEATURES) {
-      if (this->impl->CompileFeaturesEntries.empty()) {
-        return nullptr;
-      }
-
-      static std::string output;
-      output = cmJoin(this->impl->CompileFeaturesEntries, ";");
-      return cmValue(output);
-    }
-    if (prop == propCOMPILE_OPTIONS) {
-      if (this->impl->CompileOptionsEntries.empty()) {
-        return nullptr;
-      }
-
-      static std::string output;
-      output = cmJoin(this->impl->CompileOptionsEntries, ";");
-      return cmValue(output);
-    }
-    if (prop == propCOMPILE_DEFINITIONS) {
-      if (this->impl->CompileDefinitionsEntries.empty()) {
-        return nullptr;
-      }
-
-      static std::string output;
-      output = cmJoin(this->impl->CompileDefinitionsEntries, ";");
-      return cmValue(output);
-    }
-    if (prop == propLINK_OPTIONS) {
-      if (this->impl->LinkOptionsEntries.empty()) {
-        return nullptr;
-      }
-
-      static std::string output;
-      output = cmJoin(this->impl->LinkOptionsEntries, ";");
-      return cmValue(output);
-    }
-    if (prop == propLINK_DIRECTORIES) {
-      if (this->impl->LinkDirectoriesEntries.empty()) {
-        return nullptr;
-      }
-
-      static std::string output;
-      output = cmJoin(this->impl->LinkDirectoriesEntries, ";");
-
-      return cmValue(output);
-    }
     if (prop == propMANUALLY_ADDED_DEPENDENCIES) {
       if (this->impl->Utilities.empty()) {
         return nullptr;
@@ -2341,15 +2359,6 @@
       output = cmJoin(utilities, ";");
       return cmValue(output);
     }
-    if (prop == propPRECOMPILE_HEADERS) {
-      if (this->impl->PrecompileHeadersEntries.empty()) {
-        return nullptr;
-      }
-
-      static std::string output;
-      output = cmJoin(this->impl->PrecompileHeadersEntries, ";");
-      return cmValue(output);
-    }
     if (prop == propIMPORTED) {
       return this->IsImported() ? cmValue(propTRUE) : cmValue(propFALSE);
     }
@@ -2374,21 +2383,17 @@
 
   // Check fileset properties.
   {
-    auto headers =
-      this->impl->HeadersFileSets.ReadProperties(this, this->impl.get(), prop);
-    if (headers.first) {
-      return headers.second;
-    }
-    auto cxx_modules = this->impl->CxxModulesFileSets.ReadProperties(
-      this, this->impl.get(), prop);
-    if (cxx_modules.first) {
-      return cxx_modules.second;
-    }
-    auto cxx_module_headers =
-      this->impl->CxxModuleHeadersFileSets.ReadProperties(
-        this, this->impl.get(), prop);
-    if (cxx_module_headers.first) {
-      return cxx_module_headers.second;
+    FileSetType* fileSetTypes[] = {
+      &this->impl->HeadersFileSets,
+      &this->impl->CxxModulesFileSets,
+      &this->impl->CxxModuleHeadersFileSets,
+    };
+
+    for (auto* fileSetType : fileSetTypes) {
+      auto value = fileSetType->ReadProperties(this, this->impl.get(), prop);
+      if (value.first) {
+        return value.second;
+      }
     }
   }
 
diff --git a/Source/cmTryCompileCommand.cxx b/Source/cmTryCompileCommand.cxx
index 789ffe9..d2cc75b 100644
--- a/Source/cmTryCompileCommand.cxx
+++ b/Source/cmTryCompileCommand.cxx
@@ -25,9 +25,7 @@
   static const std::vector<unsigned long> LogVersionsWithTryCompileV1{ 1 };
 
   if (log.IsAnyLogVersionEnabled(LogVersionsWithTryCompileV1)) {
-    log.BeginEvent("try_compile-v1");
-    log.WriteBacktrace(mf);
-    log.WriteChecks(mf);
+    log.BeginEvent("try_compile-v1", mf);
     cmCoreTryCompile::WriteTryCompileEventFields(log, compileResult);
     log.EndEvent();
   }
diff --git a/Source/cmTryRunCommand.cxx b/Source/cmTryRunCommand.cxx
index 21bd95a..b648d9b 100644
--- a/Source/cmTryRunCommand.cxx
+++ b/Source/cmTryRunCommand.cxx
@@ -44,9 +44,7 @@
   static const std::vector<unsigned long> LogVersionsWithTryRunV1{ 1 };
 
   if (log.IsAnyLogVersionEnabled(LogVersionsWithTryRunV1)) {
-    log.BeginEvent("try_run-v1");
-    log.WriteBacktrace(mf);
-    log.WriteChecks(mf);
+    log.BeginEvent("try_run-v1", mf);
     cmCoreTryCompile::WriteTryCompileEventFields(log, compileResult);
 
     log.BeginObject("runResult"_s);
diff --git a/Source/kwsys/RegularExpression.cxx b/Source/kwsys/RegularExpression.cxx
index c96a96d..f2f5143 100644
--- a/Source/kwsys/RegularExpression.cxx
+++ b/Source/kwsys/RegularExpression.cxx
@@ -218,7 +218,7 @@
   20 // no   Mark this point in input as start of
      // #n.
 // OPEN+1 is number 1, etc.
-#define CLOSE 30 // no   Analogous to OPEN.
+#define CLOSE 52 // no   Analogous to OPEN.
 
 /*
  * Opcode notes:
@@ -1018,7 +1018,30 @@
       case OPEN + 6:
       case OPEN + 7:
       case OPEN + 8:
-      case OPEN + 9: {
+      case OPEN + 9:
+      case OPEN + 10:
+      case OPEN + 11:
+      case OPEN + 12:
+      case OPEN + 13:
+      case OPEN + 14:
+      case OPEN + 15:
+      case OPEN + 16:
+      case OPEN + 17:
+      case OPEN + 18:
+      case OPEN + 19:
+      case OPEN + 20:
+      case OPEN + 21:
+      case OPEN + 22:
+      case OPEN + 23:
+      case OPEN + 24:
+      case OPEN + 25:
+      case OPEN + 26:
+      case OPEN + 27:
+      case OPEN + 28:
+      case OPEN + 29:
+      case OPEN + 30:
+      case OPEN + 31:
+      case OPEN + 32: {
         int no;
         const char* save;
 
@@ -1046,7 +1069,30 @@
       case CLOSE + 6:
       case CLOSE + 7:
       case CLOSE + 8:
-      case CLOSE + 9: {
+      case CLOSE + 9:
+      case CLOSE + 10:
+      case CLOSE + 11:
+      case CLOSE + 12:
+      case CLOSE + 13:
+      case CLOSE + 14:
+      case CLOSE + 15:
+      case CLOSE + 16:
+      case CLOSE + 17:
+      case CLOSE + 18:
+      case CLOSE + 19:
+      case CLOSE + 20:
+      case CLOSE + 21:
+      case CLOSE + 22:
+      case CLOSE + 23:
+      case CLOSE + 24:
+      case CLOSE + 25:
+      case CLOSE + 26:
+      case CLOSE + 27:
+      case CLOSE + 28:
+      case CLOSE + 29:
+      case CLOSE + 30:
+      case CLOSE + 31:
+      case CLOSE + 32: {
         int no;
         const char* save;
 
diff --git a/Source/kwsys/RegularExpression.hxx.in b/Source/kwsys/RegularExpression.hxx.in
index 2cb7f5e..1dc1dfa 100644
--- a/Source/kwsys/RegularExpression.hxx.in
+++ b/Source/kwsys/RegularExpression.hxx.in
@@ -50,7 +50,7 @@
 
   enum
   {
-    NSUBEXP = 10
+    NSUBEXP = 32
   };
 
 private:
diff --git a/Tests/RunCMake/try_compile/ConfigureLog-config.txt b/Tests/RunCMake/try_compile/ConfigureLog-config.txt
index 42c1278..ef5c73e 100644
--- a/Tests/RunCMake/try_compile/ConfigureLog-config.txt
+++ b/Tests/RunCMake/try_compile/ConfigureLog-config.txt
@@ -20,6 +20,9 @@
     directories:
       source: "[^"]*/Tests/RunCMake/try_compile/ConfigureLog-build/CMakeFiles/CMakeScratch/TryCompile-[^/"]+"
       binary: "[^"]*/Tests/RunCMake/try_compile/ConfigureLog-build/CMakeFiles/CMakeScratch/TryCompile-[^/"]+"
+    cmakeVariables:(
+      CMAKE_[^
+]*)+
     buildResult:
       variable: "CMAKE_C_ABI_COMPILED"
       cached: true
@@ -41,6 +44,13 @@
     directories:
       source: "[^"]*/Tests/RunCMake/try_compile/ConfigureLog-build/CMakeFiles/CMakeScratch/TryCompile-[^/"]+"
       binary: "[^"]*/Tests/RunCMake/try_compile/ConfigureLog-build/CMakeFiles/CMakeScratch/TryCompile-[^/"]+"
+    cmakeVariables:
+      ABCDEFGHIJKLMNOPQRSTUVWXYZ: "Upper case"(
+      CMAKE_[^
+]*)+
+      "WITH SPACE": "Space"
+      _-0123456789: "Other chars"
+      abcdefghijklmnopqrstuvwxyz: "Lower case"
     buildResult:
       variable: "COMPILE_RESULT"
       cached: true
@@ -58,6 +68,9 @@
     directories:
       source: "[^"]*/Tests/RunCMake/try_compile/ConfigureLog-build/CMakeFiles/CMakeScratch/TryCompile-[^/"]+"
       binary: "[^"]*/Tests/RunCMake/try_compile/ConfigureLog-build/CMakeFiles/CMakeScratch/TryCompile-[^/"]+"
+    cmakeVariables:(
+      CMAKE_[^
+]*)+
     buildResult:
       variable: "COMPILE_RESULT"
       cached: true
diff --git a/Tests/RunCMake/try_compile/ConfigureLog.cmake b/Tests/RunCMake/try_compile/ConfigureLog.cmake
index 294e0f9..a897719 100644
--- a/Tests/RunCMake/try_compile/ConfigureLog.cmake
+++ b/Tests/RunCMake/try_compile/ConfigureLog.cmake
@@ -1,10 +1,23 @@
 enable_language(C)
 
+set(CMAKE_TRY_COMPILE_PLATFORM_VARIABLES
+  ABCDEFGHIJKLMNOPQRSTUVWXYZ
+  abcdefghijklmnopqrstuvwxyz
+  _-0123456789
+  "WITH SPACE"
+  )
+set(ABCDEFGHIJKLMNOPQRSTUVWXYZ "Upper case")
+set(abcdefghijklmnopqrstuvwxyz "Lower case")
+set(_-0123456789 "Other chars")
+set("WITH SPACE" "Space")
+
 try_compile(COMPILE_RESULT
   SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/ConfigureLog-bad.c
   LOG_DESCRIPTION "Source that should not compile."
   )
 
+unset(CMAKE_TRY_COMPILE_PLATFORM_VARIABLES)
+
 try_compile(COMPILE_RESULT
   SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/ConfigureLog-test.c
   NO_LOG
diff --git a/Tests/RunCMake/try_compile/Inspect-config.txt b/Tests/RunCMake/try_compile/Inspect-config.txt
index b0f90e5..44bd443 100644
--- a/Tests/RunCMake/try_compile/Inspect-config.txt
+++ b/Tests/RunCMake/try_compile/Inspect-config.txt
@@ -20,6 +20,9 @@
     directories:
       source: "[^"]*/Tests/RunCMake/try_compile/Inspect-build/CMakeFiles/CMakeScratch/TryCompile-[^/"]+"
       binary: "[^"]*/Tests/RunCMake/try_compile/Inspect-build/CMakeFiles/CMakeScratch/TryCompile-[^/"]+"
+    cmakeVariables:(
+      CMAKE_[^
+]*)+
     buildResult:
       variable: "CMAKE_C_ABI_COMPILED"
       cached: true
@@ -44,6 +47,9 @@
     directories:
       source: "[^"]*/Tests/RunCMake/try_compile/Inspect-build/CMakeFiles/CMakeScratch/TryCompile-[^/"]+"
       binary: "[^"]*/Tests/RunCMake/try_compile/Inspect-build/CMakeFiles/CMakeScratch/TryCompile-[^/"]+"
+    cmakeVariables:(
+      CMAKE_[^
+]*)+
     buildResult:
       variable: "CMAKE_CXX_ABI_COMPILED"
       cached: true
diff --git a/Tests/RunCMake/try_run/ConfigureLog-config.txt b/Tests/RunCMake/try_run/ConfigureLog-config.txt
index a68472c..e1d5fa7 100644
--- a/Tests/RunCMake/try_run/ConfigureLog-config.txt
+++ b/Tests/RunCMake/try_run/ConfigureLog-config.txt
@@ -19,6 +19,9 @@
     directories:
       source: "[^"]*/Tests/RunCMake/try_run/ConfigureLog-build/CMakeFiles/CMakeScratch/TryCompile-[^/"]+"
       binary: "[^"]*/Tests/RunCMake/try_run/ConfigureLog-build/CMakeFiles/CMakeScratch/TryCompile-[^/"]+"
+    cmakeVariables:(
+      CMAKE_[^
+]*)+
     buildResult:
       variable: "CMAKE_C_ABI_COMPILED"
       cached: true
@@ -40,6 +43,9 @@
     directories:
       source: "[^"]*/Tests/RunCMake/try_run/ConfigureLog-build/CMakeFiles/CMakeScratch/TryCompile-[^/"]+"
       binary: "[^"]*/Tests/RunCMake/try_run/ConfigureLog-build/CMakeFiles/CMakeScratch/TryCompile-[^/"]+"
+    cmakeVariables:(
+      CMAKE_[^
+]*)+
     buildResult:
       variable: "COMPILE_RESULT"
       cached: true
@@ -59,6 +65,9 @@
     directories:
       source: "[^"]*/Tests/RunCMake/try_run/ConfigureLog-build/CMakeFiles/CMakeScratch/TryCompile-[^/"]+"
       binary: "[^"]*/Tests/RunCMake/try_run/ConfigureLog-build/CMakeFiles/CMakeScratch/TryCompile-[^/"]+"
+    cmakeVariables:(
+      CMAKE_[^
+]*)+
     buildResult:
       variable: "COMPILE_RESULT"
       cached: true
@@ -83,6 +92,9 @@
     directories:
       source: "[^"]*/Tests/RunCMake/try_run/ConfigureLog-build/CMakeFiles/CMakeScratch/TryCompile-[^/"]+"
       binary: "[^"]*/Tests/RunCMake/try_run/ConfigureLog-build/CMakeFiles/CMakeScratch/TryCompile-[^/"]+"
+    cmakeVariables:(
+      CMAKE_[^
+]*)+
     buildResult:
       variable: "COMPILE_RESULT"
       cached: true
@@ -103,6 +115,9 @@
     directories:
       source: "[^"]*/Tests/RunCMake/try_run/ConfigureLog-build/CMakeFiles/CMakeScratch/TryCompile-[^/"]+"
       binary: "[^"]*/Tests/RunCMake/try_run/ConfigureLog-build/CMakeFiles/CMakeScratch/TryCompile-[^/"]+"
+    cmakeVariables:(
+      CMAKE_[^
+]*)+
     buildResult:
       variable: "COMPILE_RESULT"
       cached: true
diff --git a/Utilities/IWYU/mapping.imp b/Utilities/IWYU/mapping.imp
index 3d3aa8c..1afad43 100644
--- a/Utilities/IWYU/mapping.imp
+++ b/Utilities/IWYU/mapping.imp
@@ -79,6 +79,7 @@
   # Use 'CMake_IWYU_VERBOSE' to see the fully qualified names that need this.
   # TODO: Can this be simplified with an @-expression?
   #{ symbol: [ "@std::__decay_and_strip<.*>::__type", private, "\"cmConfigure.h\"", public ] },
+  { symbol: [ "std::__decay_and_strip<int>::__type", private, "\"cmConfigure.h\"", public ] },
   { symbol: [ "std::__decay_and_strip<bool>::__type", private, "\"cmConfigure.h\"", public ] },
   { symbol: [ "std::__decay_and_strip<char const (&)[1]>::__type", private, "\"cmConfigure.h\"", public ] },
   { symbol: [ "std::__decay_and_strip<cmCommand *&>::__type", private, "\"cmConfigure.h\"", public ] },