Merge branch 'release-4.4'
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4f8a022..ca18091 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,7 +1,7 @@
 # Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
 # file LICENSE.rst or https://cmake.org/licensing for details.
 
-cmake_minimum_required(VERSION 3.13...4.2 FATAL_ERROR)
+cmake_minimum_required(VERSION 3.13...4.3 FATAL_ERROR)
 
 if(CMake_TEST_HOST_CMAKE)
   get_filename_component(CMake_TEST_EXTERNAL_CMAKE "${CMAKE_COMMAND}" DIRECTORY)
diff --git a/Help/command/file.rst b/Help/command/file.rst
index 42b0871..094262e 100644
--- a/Help/command/file.rst
+++ b/Help/command/file.rst
@@ -764,10 +764,16 @@
 
     ``STATUS <variable>``
       Store the resulting status of the operation in a variable.
-      The status is a ``;`` separated list of length 2.
+      The status is a
+      :ref:`semicolon-separated list <CMake Language Lists>` of length 2.
       The first element is the numeric return value for the operation,
       and the second element is a string value for the error.
-      A ``0`` numeric error means no error in the operation.
+      A ``0`` numeric error means no error in the operation (``CURLE_OK``).
+
+      The return value and description are produced directly from libcurl.
+      See the `libcurl documentation`_ on error codes for more information.
+
+    .. _`libcurl documentation`: https://curl.se/libcurl/c/libcurl-errors.html
 
     ``TIMEOUT <seconds>``
       Terminate the operation after a given total time has elapsed.
@@ -1080,6 +1086,7 @@
     [DESTINATION <dir>]
     [ENCODING <encoding>]
     [PATTERNS <pattern>...]
+    [PATTERNS_EXCLUDE <pattern>...]
     [LIST_ONLY]
     [VERBOSE]
     [TOUCH])
@@ -1137,6 +1144,18 @@
     patterns.  Wildcards are supported.  If the ``PATTERNS`` option is
     not given, the entire archive will be listed or extracted.
 
+  ``PATTERNS_EXCLUDE <pattern>...``
+    .. versionadded:: 4.5
+
+    Do not extract or list files and directories that match one of the given
+    patterns.  Wildcards are supported.  This option may be combined with
+    ``PATTERNS``; an entry that matches both an inclusion pattern and an
+    exclusion pattern is excluded.
+
+    Unlike ``PATTERNS``, exclusion patterns are not anchored to the start of
+    an entry's path: a pattern matches if it matches any portion of the path.
+    This is consistent with the ``--exclude`` option of command-line ``tar``.
+
   ``LIST_ONLY``
     List the files in the archive rather than extract them.
 
diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst
index 9a4f7c0..a535116 100644
--- a/Help/manual/cmake-policies.7.rst
+++ b/Help/manual/cmake-policies.7.rst
@@ -36,10 +36,10 @@
 
 .. code-block:: cmake
 
-  cmake_minimum_required(VERSION 3.10...4.3)
+  cmake_minimum_required(VERSION 3.10...4.4)
 
 This uses the ``<min>...<policy_max>`` syntax to enable the ``NEW`` behaviors
-of policies introduced in CMake 4.3 and earlier while only requiring a
+of policies introduced in CMake 4.4 and earlier while only requiring a
 minimum version of CMake 3.10.  The project is expected to work with
 both the ``OLD`` and ``NEW`` behaviors of policies introduced between
 those versions.
diff --git a/Help/release/dev/0-sample-topic.rst b/Help/release/dev/0-sample-topic.rst
new file mode 100644
index 0000000..e4cc01e
--- /dev/null
+++ b/Help/release/dev/0-sample-topic.rst
@@ -0,0 +1,7 @@
+0-sample-topic
+--------------
+
+* This is a sample release note for the change in a topic.
+  Developers should add similar notes for each topic branch
+  making a noteworthy change.  Each document should be named
+  and titled to match the topic name to avoid merge conflicts.
diff --git a/Help/release/dev/file-ARCHIVE_EXTRACT-patterns-exclude.rst b/Help/release/dev/file-ARCHIVE_EXTRACT-patterns-exclude.rst
new file mode 100644
index 0000000..c661ceb
--- /dev/null
+++ b/Help/release/dev/file-ARCHIVE_EXTRACT-patterns-exclude.rst
@@ -0,0 +1,6 @@
+file-ARCHIVE_EXTRACT-patterns-exclude
+-------------------------------------
+
+* The :command:`file(ARCHIVE_EXTRACT)` command gained a ``PATTERNS_EXCLUDE``
+  option to omit archive entries matching the given patterns from being
+  extracted or listed.
diff --git a/Help/release/index.rst b/Help/release/index.rst
index 462babd..c422c77 100644
--- a/Help/release/index.rst
+++ b/Help/release/index.rst
@@ -7,6 +7,8 @@
   This file should include the adjacent "dev.txt" file
   in development versions but not in release versions.
 
+.. include:: dev.txt
+
 Releases
 ========
 
diff --git a/Modules/UseJava/javaTargets.cmake.in b/Modules/UseJava/javaTargets.cmake.in
index 157a60e..b7e6107 100644
--- a/Modules/UseJava/javaTargets.cmake.in
+++ b/Modules/UseJava/javaTargets.cmake.in
@@ -1,5 +1,5 @@
 cmake_policy(PUSH)
-cmake_policy(VERSION 2.8.12...4.2)
+cmake_policy(VERSION 2.8.12...4.3)
 
 #----------------------------------------------------------------
 # Generated CMake Java target import file.
diff --git a/Modules/UseSWIG.cmake b/Modules/UseSWIG.cmake
index 3d901dd..1666f35 100644
--- a/Modules/UseSWIG.cmake
+++ b/Modules/UseSWIG.cmake
@@ -589,39 +589,23 @@
 
   set (swig_source_file_flags ${CMAKE_SWIG_FLAGS})
   # handle various swig compile flags properties
-  get_source_file_property (include_directories "${infile}" INCLUDE_DIRECTORIES)
-  if (include_directories)
-    list (APPEND swig_source_file_flags "$<$<BOOL:${include_directories}>:-I$<JOIN:${include_directories},$<SEMICOLON>-I>>")
-  endif()
-  set (property "$<TARGET_PROPERTY:${target_name},SWIG_INCLUDE_DIRECTORIES>")
-  list (APPEND swig_source_file_flags "$<$<BOOL:${property}>:-I$<JOIN:$<TARGET_GENEX_EVAL:${target_name},${property}>,$<SEMICOLON>-I>>")
-  set (property "$<REMOVE_DUPLICATES:$<TARGET_PROPERTY:${target_name},INCLUDE_DIRECTORIES>>")
-  get_source_file_property(use_target_include_dirs "${infile}" USE_TARGET_INCLUDE_DIRECTORIES)
-  if (use_target_include_dirs)
-    list (APPEND swig_source_file_flags "$<$<BOOL:${property}>:-I$<JOIN:${property},$<SEMICOLON>-I>>")
-  elseif(use_target_include_dirs STREQUAL "NOTFOUND")
-    # not defined at source level, rely on target level
-    list (APPEND swig_source_file_flags "$<$<AND:$<BOOL:$<TARGET_PROPERTY:${target_name},SWIG_USE_TARGET_INCLUDE_DIRECTORIES>>,$<BOOL:${property}>>:-I$<JOIN:${property},$<SEMICOLON>-I>>")
-  endif()
+  ### include directories
+  list (APPEND swig_source_file_flags "$<LIST:TRANSFORM,$<LIST:REMOVE_DUPLICATES,$<SOURCE_PROPERTY:${infile},TARGET_DIRECTORY:${target_name},INCLUDE_DIRECTORIES>>,PREPEND,-I>")
+  list (APPEND swig_source_file_flags "$<LIST:TRANSFORM,$<LIST:REMOVE_DUPLICATES,$<TARGET_GENEX_EVAL:${target_name},$<TARGET_PROPERTY:${target_name},SWIG_INCLUDE_DIRECTORIES>>>,PREPEND,-I>")
+  # use target INCLUDE_DIRECTORIES if source property USE_TARGET_INCLUDE_DIRECTORIES is "ON" or,
+  # if undefined, if target property SWIG_USE_TARGET_INCLUDE_DIRECTORIES is "ON"
+  list (APPEND swig_source_file_flags "$<LIST:TRANSFORM,$<LIST:REMOVE_DUPLICATES,$<IF:$<BOOL:$<SOURCE_PROPERTY:${infile},TARGET_DIRECTORY:${target_name},USE_TARGET_INCLUDE_DIRECTORIES>>,$<TARGET_PROPERTY:${target_name},INCLUDE_DIRECTORIES>,$<$<AND:$<EQUAL:$<STRING:LENGTH,$<SOURCE_PROPERTY:${infile},TARGET_DIRECTORY:${target_name},USE_TARGET_INCLUDE_DIRECTORIES>>,0>,$<BOOL:$<TARGET_PROPERTY:${target_name},SWIG_USE_TARGET_INCLUDE_DIRECTORIES>>>:$<TARGET_PROPERTY:${target_name},INCLUDE_DIRECTORIES>>>>,PREPEND,-I>")
 
-  set (property "$<TARGET_PROPERTY:${target_name},SWIG_COMPILE_DEFINITIONS>")
-  list (APPEND swig_source_file_flags "$<$<BOOL:${property}>:-D$<JOIN:$<TARGET_GENEX_EVAL:${target_name},${property}>,$<SEMICOLON>-D>>")
-  get_source_file_property (compile_definitions "${infile}" COMPILE_DEFINITIONS)
-  if (compile_definitions)
-    list (APPEND swig_source_file_flags "$<$<BOOL:${compile_definitions}>:-D$<JOIN:${compile_definitions},$<SEMICOLON>-D>>")
-  endif()
+  ### compile definitions
+  list (APPEND swig_source_file_flags "$<LIST:TRANSFORM,$<LIST:REMOVE_DUPLICATES,$<TARGET_GENEX_EVAL:${target_name},$<TARGET_PROPERTY:${target_name},SWIG_COMPILE_DEFINITIONS>>>,PREPEND,-D>")
+  list (APPEND swig_source_file_flags "$<LIST:TRANSFORM,$<LIST:REMOVE_DUPLICATES,$<SOURCE_PROPERTY:${infile},TARGET_DIRECTORY:${target_name},COMPILE_DEFINITIONS>>,PREPEND,-D>")
 
+  ### compile options
   list (APPEND swig_source_file_flags "$<TARGET_GENEX_EVAL:${target_name},$<TARGET_PROPERTY:${target_name},SWIG_COMPILE_OPTIONS>>")
-  get_source_file_property (compile_options "${infile}" COMPILE_OPTIONS)
-  if (compile_options)
-    list (APPEND swig_source_file_flags ${compile_options})
-  endif()
+  list (APPEND swig_source_file_flags "$<SOURCE_PROPERTY:${infile},TARGET_DIRECTORY:${target_name},COMPILE_OPTIONS>")
 
   # legacy support
-  get_source_file_property (swig_flags "${infile}" SWIG_FLAGS)
-  if (swig_flags)
-    list (APPEND swig_source_file_flags ${swig_flags})
-  endif()
+  list (APPEND swig_source_file_flags "$<SOURCE_PROPERTY:${infile},TARGET_DIRECTORY:${target_name},SWIG_FLAGS>")
 
   get_filename_component(swig_source_file_fullname "${infile}" ABSOLUTE)
 
@@ -651,21 +635,16 @@
   list (REMOVE_DUPLICATES cmake_include_directories)
   set (swig_include_dirs)
   if (cmake_include_directories)
-    set (swig_include_dirs "$<$<BOOL:${cmake_include_directories}>:-I$<JOIN:${cmake_include_directories},$<SEMICOLON>-I>>")
+    set (swig_include_dirs "$<LIST:TRANSFORM,${cmake_include_directories},PREPEND,-I>")
   endif()
 
   set(swig_special_flags)
   # default is c, so add c++ flag if it is c++
-  if(swig_source_file_cplusplus)
-    list (APPEND swig_special_flags "-c++")
-  endif()
+  list (APPEND swig_special_flags "$<$<BOOL:$<SOURCE_PROPERTY:${infile},TARGET_DIRECTORY:${target_name},CPLUSPLUS>>:-c++>")
 
   cmake_policy(GET CMP0086 module_name_policy)
   if (module_name_policy STREQUAL "NEW")
-    get_source_file_property(module_name "${infile}" SWIG_MODULE_NAME)
-    if (module_name)
-      list (APPEND swig_special_flags "-module" "${module_name}")
-    endif()
+    list (APPEND swig_special_flags "$<$<BOOL:$<SOURCE_PROPERTY:${infile},TARGET_DIRECTORY:${target_name},SWIG_MODULE_NAME>>:-module$<SEMICOLON>$<SOURCE_PROPERTY:${infile},TARGET_DIRECTORY:${target_name},SWIG_MODULE_NAME>>")
   else()
     if (NOT module_name_policy)
       cmake_policy(ISSUE_WARNING CMP0086)
@@ -692,10 +671,7 @@
 
   # dependencies
   set (swig_dependencies DEPENDS ${SWIG_MODULE_${name}_EXTRA_DEPS} $<TARGET_PROPERTY:${target_name},SWIG_DEPENDS>)
-  get_source_file_property(file_depends "${infile}" DEPENDS)
-  if (file_depends)
-    list (APPEND swig_dependencies ${file_depends})
-  endif()
+  list (APPEND swig_dependencies "$<SOURCE_PROPERTY:${infile},TARGET_DIRECTORY:${target_name},DEPENDS>")
 
   if (UseSWIG_MODULE_VERSION VERSION_GREATER 1)
     # as part of custom command, start by removing old generated files
@@ -761,14 +737,17 @@
     PROPERTIES GENERATED 1)
 
   ## add all properties for generated file to various properties
-  get_property (include_directories SOURCE "${infile}" PROPERTY GENERATED_INCLUDE_DIRECTORIES)
-  set_property (SOURCE "${swig_generated_file_fullname}" PROPERTY INCLUDE_DIRECTORIES ${include_directories} $<TARGET_GENEX_EVAL:${target_name},$<TARGET_PROPERTY:${target_name},SWIG_GENERATED_INCLUDE_DIRECTORIES>>)
+  set_property (SOURCE "${swig_generated_file_fullname}" PROPERTY INCLUDE_DIRECTORIES
+        "$<TARGET_GENEX_EVAL:${target_name},$<SOURCE_PROPERTY:${infile},TARGET_DIRECTORY:${target_name},GENERATED_INCLUDE_DIRECTORIES>>"
+        "$<TARGET_GENEX_EVAL:${target_name},$<TARGET_PROPERTY:${target_name},SWIG_GENERATED_INCLUDE_DIRECTORIES>>")
 
-  get_property (compile_definitions SOURCE "${infile}" PROPERTY GENERATED_COMPILE_DEFINITIONS)
-  set_property (SOURCE "${swig_generated_file_fullname}" PROPERTY COMPILE_DEFINITIONS $<TARGET_GENEX_EVAL:${target_name},$<TARGET_PROPERTY:${target_name},SWIG_GENERATED_COMPILE_DEFINITIONS>> ${compile_definitions})
+  set_property (SOURCE "${swig_generated_file_fullname}" PROPERTY COMPILE_DEFINITIONS
+        "$<TARGET_GENEX_EVAL:${target_name},$<TARGET_PROPERTY:${target_name},SWIG_GENERATED_COMPILE_DEFINITIONS>>"
+        "$<TARGET_GENEX_EVAL:${target_name},$<SOURCE_PROPERTY:${infile},TARGET_DIRECTORY:${target_name},GENERATED_COMPILE_DEFINITIONS>>")
 
-  get_property (compile_options SOURCE "${infile}" PROPERTY GENERATED_COMPILE_OPTIONS)
-  set_property (SOURCE "${swig_generated_file_fullname}" PROPERTY COMPILE_OPTIONS $<TARGET_GENEX_EVAL:${target_name},$<TARGET_PROPERTY:${target_name},SWIG_GENERATED_COMPILE_OPTIONS>> ${compile_options})
+  set_property (SOURCE "${swig_generated_file_fullname}" PROPERTY COMPILE_OPTIONS
+        "$<TARGET_GENEX_EVAL:${target_name},$<TARGET_PROPERTY:${target_name},SWIG_GENERATED_COMPILE_OPTIONS>>"
+        "$<TARGET_GENEX_EVAL:${target_name},$<SOURCE_PROPERTY:${infile},TARGET_DIRECTORY:${target_name},GENERATED_COMPILE_OPTIONS>>")
 
   if (SWIG_MODULE_${name}_SWIG_LANGUAGE_FLAG MATCHES "php")
     set_property (SOURCE "${swig_generated_file_fullname}" APPEND PROPERTY INCLUDE_DIRECTORIES "${outdir}")
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 8d54fc9..252ae61 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,8 +1,8 @@
 # CMake version number components.
 set(CMake_VERSION_MAJOR 4)
 set(CMake_VERSION_MINOR 4)
-set(CMake_VERSION_PATCH 0)
-set(CMake_VERSION_RC 1)
+set(CMake_VERSION_PATCH 20260616)
+#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/Checks/Curses/CMakeLists.txt b/Source/Checks/Curses/CMakeLists.txt
index 2854172..f1f9319 100644
--- a/Source/Checks/Curses/CMakeLists.txt
+++ b/Source/Checks/Curses/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 3.13...4.2 FATAL_ERROR)
+cmake_minimum_required(VERSION 3.13...4.3 FATAL_ERROR)
 project(CheckCurses C)
 
 set(CURSES_NEED_NCURSES TRUE)
diff --git a/Source/cmBuildSbomBuilder.cxx b/Source/cmBuildSbomBuilder.cxx
index fbec0e1..24dbfa1 100644
--- a/Source/cmBuildSbomBuilder.cxx
+++ b/Source/cmBuildSbomBuilder.cxx
@@ -17,12 +17,13 @@
 {
 }
 
-bool cmBuildSbomBuilder::Generate(std::ostream& os)
+bool cmBuildSbomBuilder::Generate(std::ostream& os, std::string const& config)
 {
   if (!this->LocalGenerator) {
     return false;
   }
-  return this->GenerateForTargets(os, cmGeneratorExpression::BuildInterface);
+  return this->GenerateForTargets(os, config,
+                                  cmGeneratorExpression::BuildInterface);
 }
 
 cmExportFileGenerator::ExportInfo cmBuildSbomBuilder::FindExportInfoFor(
diff --git a/Source/cmBuildSbomBuilder.h b/Source/cmBuildSbomBuilder.h
index 6cca846..c9cf430 100644
--- a/Source/cmBuildSbomBuilder.h
+++ b/Source/cmBuildSbomBuilder.h
@@ -5,6 +5,7 @@
 #include "cmConfigure.h" // IWYU pragma: keep
 
 #include <iosfwd>
+#include <string>
 #include <vector>
 
 #include "cmExportFileGenerator.h"
@@ -23,7 +24,7 @@
                      std::vector<cmExportSet*> exportSets,
                      cmLocalGenerator* lg = nullptr);
 
-  bool Generate(std::ostream& os) override;
+  bool Generate(std::ostream& os, std::string const& config) override;
 
 protected:
   cmExportFileGenerator::ExportInfo FindExportInfoFor(
diff --git a/Source/cmBuildSbomGenerator.cxx b/Source/cmBuildSbomGenerator.cxx
index d77e583..1155604 100644
--- a/Source/cmBuildSbomGenerator.cxx
+++ b/Source/cmBuildSbomGenerator.cxx
@@ -3,14 +3,16 @@
 #include "cmBuildSbomGenerator.h"
 
 #include "cmGeneratedFileStream.h"
+#include "cmStringAlgorithms.h"
 
 void cmBuildSbomGenerator::Compute(cmLocalGenerator* lg)
 {
   this->Builder->Compute(lg);
 }
 
-bool cmBuildSbomGenerator::GenerateForBuild()
+bool cmBuildSbomGenerator::GenerateForBuild(std::string const& config)
 {
-  cmGeneratedFileStream os(this->OutputFile);
-  return this->Builder->Generate(os);
+  cmGeneratedFileStream os(
+    cmStrCat(this->OutputFile, "-", config, ".spdx.json"));
+  return this->Builder->Generate(os, config);
 }
diff --git a/Source/cmBuildSbomGenerator.h b/Source/cmBuildSbomGenerator.h
index 5c06835..9beaedd 100644
--- a/Source/cmBuildSbomGenerator.h
+++ b/Source/cmBuildSbomGenerator.h
@@ -2,6 +2,7 @@
    file LICENSE.rst or https://cmake.org/licensing for details.  */
 #pragma once
 
+#include <iosfwd>
 #include <string>
 #include <utility>
 #include <vector>
@@ -10,7 +11,6 @@
 
 #include "cmBuildSbomBuilder.h"
 #include "cmSbomArguments.h"
-
 class cmExportSet;
 class cmGeneratorTarget;
 class cmLocalGenerator;
@@ -45,13 +45,19 @@
   {
     return this->Builder->CoversTarget(target);
   }
+
+  bool GenerateForBuild(std::ostream& os, std::string const& config)
+  {
+    return this->Builder->Generate(os, config);
+  }
+
   std::string const& GetPackageName() const
   {
     return this->Builder->GetPackageName();
   }
 
   /** Open the output file and write the SBOM document to it. */
-  bool GenerateForBuild();
+  bool GenerateForBuild(std::string const& config);
 
 private:
   std::string OutputFile;
diff --git a/Source/cmExportCMakeConfigGenerator.cxx b/Source/cmExportCMakeConfigGenerator.cxx
index 353d38f..ef80d1c 100644
--- a/Source/cmExportCMakeConfigGenerator.cxx
+++ b/Source/cmExportCMakeConfigGenerator.cxx
@@ -176,7 +176,7 @@
   // Isolate the file policy level.
   // Support CMake versions as far back as the
   // RequiredCMakeVersion{Major,Minor,Patch}, but also support using NEW
-  // policy settings for up to CMake 4.2 (this upper limit may be reviewed
+  // policy settings for up to CMake 4.3 (this upper limit may be reviewed
   // and increased from time to time). This reduces the opportunity for CMake
   // warnings when an older export file is later used with newer CMake
   // versions.
@@ -185,7 +185,7 @@
         "cmake_policy(VERSION "
      << this->RequiredCMakeVersionMajor << '.'
      << this->RequiredCMakeVersionMinor << '.'
-     << this->RequiredCMakeVersionPatch << "...4.2)\n";
+     << this->RequiredCMakeVersionPatch << "...4.3)\n";
   /* clang-format on */
 }
 
diff --git a/Source/cmExportCommand.cxx b/Source/cmExportCommand.cxx
index 2f6434a..98208d7 100644
--- a/Source/cmExportCommand.cxx
+++ b/Source/cmExportCommand.cxx
@@ -459,7 +459,7 @@
 
   std::string const dir =
     arguments.GetDefaultDestination(mf.GetCurrentBinaryDirectory());
-  std::string const fpath = cmStrCat(dir, '/', arguments.GetPackageFileName());
+  std::string const fpath = cmStrCat(dir, '/', arguments.GetPackageName());
 
   if (gg->IsBuildSbomFile(fpath)) {
     status.SetError(cmStrCat("SBOM command already specified for the file "_s,
@@ -479,7 +479,6 @@
   }
 
   auto builder = cm::make_unique<cmBuildSbomGenerator>(arguments, sets, fpath);
-
   cmBuildSbomGenerator* rawPtr = builder.get();
   mf.AddBuildSbomGenerator(std::move(builder));
   gg->AddBuildSbomGenerator(rawPtr);
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index 366314c..222acd7 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -3888,17 +3888,20 @@
     bool ListOnly = false;
     std::string Destination;
     ArgumentParser::MaybeEmpty<std::vector<std::string>> Patterns;
+    ArgumentParser::MaybeEmpty<std::vector<std::string>> PatternsExclude;
     bool Touch = false;
   };
 
-  static auto const parser = cmArgumentParser<Arguments>{}
-                               .Bind("INPUT"_s, &Arguments::Input)
-                               .Bind("ENCODING"_s, &Arguments::Encoding)
-                               .Bind("VERBOSE"_s, &Arguments::Verbose)
-                               .Bind("LIST_ONLY"_s, &Arguments::ListOnly)
-                               .Bind("DESTINATION"_s, &Arguments::Destination)
-                               .Bind("PATTERNS"_s, &Arguments::Patterns)
-                               .Bind("TOUCH"_s, &Arguments::Touch);
+  static auto const parser =
+    cmArgumentParser<Arguments>{}
+      .Bind("INPUT"_s, &Arguments::Input)
+      .Bind("ENCODING"_s, &Arguments::Encoding)
+      .Bind("VERBOSE"_s, &Arguments::Verbose)
+      .Bind("LIST_ONLY"_s, &Arguments::ListOnly)
+      .Bind("DESTINATION"_s, &Arguments::Destination)
+      .Bind("PATTERNS"_s, &Arguments::Patterns)
+      .Bind("PATTERNS_EXCLUDE"_s, &Arguments::PatternsExclude)
+      .Bind("TOUCH"_s, &Arguments::Touch);
 
   std::vector<std::string> unrecognizedArguments;
   auto parsedArgs =
@@ -3928,6 +3931,7 @@
 
   if (parsedArgs.ListOnly) {
     if (!cmSystemTools::ListTar(inFile, parsedArgs.Patterns,
+                                parsedArgs.PatternsExclude,
                                 parsedArgs.Encoding, parsedArgs.Verbose)) {
       status.SetError(cmStrCat("failed to list: ", inFile));
       cmSystemTools::SetFatalErrorOccurred();
@@ -3962,7 +3966,7 @@
     }
 
     if (!cmSystemTools::ExtractTar(
-          inFile, parsedArgs.Patterns,
+          inFile, parsedArgs.Patterns, parsedArgs.PatternsExclude,
           parsedArgs.Touch ? cmSystemTools::cmTarExtractTimestamps::No
                            : cmSystemTools::cmTarExtractTimestamps::Yes,
           parsedArgs.Encoding, parsedArgs.Verbose)) {
diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx
index c7fffb4..7c8da04 100644
--- a/Source/cmGeneratorExpression.cxx
+++ b/Source/cmGeneratorExpression.cxx
@@ -521,7 +521,6 @@
     nullptr,
     context,
   };
-
   return this->CompiledGeneratorExpression->Evaluate(context, &dagChecker,
                                                      this->HeadTarget);
 }
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index 1203706..b4b702b 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -43,6 +43,7 @@
 #include "cmGeneratedFileStream.h"
 #include "cmGeneratorExpression.h"
 #include "cmGeneratorTarget.h"
+#include "cmInstallDirs.h"
 #include "cmInstallExportGenerator.h"
 #include "cmInstallGenerator.h"
 #include "cmInstallRuntimeDependencySet.h"
@@ -1731,12 +1732,6 @@
   // explicit install(SBOM) call.
   cmValue sbomFormat = this->GetGlobalSetting("CMAKE_INSTALL_SBOM_FORMATS");
   if (sbomFormat.IsSet() && sbomEnabled && !isTryCompile) {
-    std::string location =
-      this->Makefiles[0]->GetSafeDefinition("CMAKE_INSTALL_LIBDIR");
-    if (location.empty()) {
-      location = "lib";
-    }
-
     std::string projectName = this->LocalGenerators[0]->GetProjectName();
     for (auto& exportSet : this->ExportSets) {
       bool isCovered =
@@ -1748,17 +1743,23 @@
       if (isCovered) {
         continue;
       }
-      cmSbomArguments sbomDefaultArgs;
-      sbomDefaultArgs.ProjectName = projectName;
-      sbomDefaultArgs.PackageName = exportSet.first;
-      std::string dest = cmStrCat(location, "/sbom/", projectName);
-      this->Makefiles[0]->AddInstallGenerator(
-        cm::make_unique<cmInstallSbomGenerator>(
-          std::vector<cmExportSet*>{ &exportSet.second }, dest, "",
-          std::vector<std::string>(), "",
-          cmInstallGenerator::SelectMessageLevel(this->Makefiles[0].get()),
-          false, std::move(sbomDefaultArgs),
-          cmInstallGenerator::CaptureContext(this->Makefiles[0].get())));
+
+      cmSbomArguments args;
+      args.ProjectName = projectName;
+      args.PackageName = exportSet.first;
+      std::string dest = args.GetDefaultDestination(
+        cm::InstallDirs::GetLibraryDirectory(this->Makefiles[0].get()));
+
+      auto installGen = cm::make_unique<cmInstallSbomGenerator>(
+        std::vector<cmExportSet*>{ &exportSet.second }, dest, "",
+        std::vector<std::string>(), "",
+        cmInstallGenerator::SelectMessageLevel(this->Makefiles[0].get()),
+        false, std::move(args),
+        cmInstallGenerator::CaptureContext(this->Makefiles[0].get()));
+
+      cmInstallSbomGenerator const* rawPtr = installGen.get();
+      this->Makefiles[0]->AddInstallGenerator(std::move(installGen));
+      this->AddInstallSbomGenerator(rawPtr);
     }
   }
 #endif
@@ -1869,13 +1870,17 @@
     }
   }
 #ifndef CMAKE_BOOTSTRAP
+
   for (auto& sbomGen : this->BuildSbomGenerators) {
-    if (!sbomGen->GenerateForBuild()) {
-      if (!cmSystemTools::GetErrorOccurredFlag()) {
-        this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR,
-                                               "Could not write SBOM file.");
+    for (std::string const& c : this->Makefiles[0]->GetGeneratorConfigs(
+           cmMakefile::IncludeEmptyConfig)) {
+      if (!sbomGen->GenerateForBuild(c)) {
+        if (!cmSystemTools::GetErrorOccurredFlag()) {
+          this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR,
+                                                 "Could not write SBOM file.");
+        }
+        return;
       }
-      return;
     }
   }
 #endif
diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx
index 2ddf39a..1ac993c 100644
--- a/Source/cmInstallCommand.cxx
+++ b/Source/cmInstallCommand.cxx
@@ -2565,12 +2565,8 @@
   // Get or construct the destination path.
   std::string dest = ica.GetDestination();
   if (dest.empty()) {
-    if (helper.Makefile->GetSafeDefinition("CMAKE_SYSTEM_NAME") == "Windows") {
-      dest = arguments.GetDefaultDestination();
-    } else {
-      dest =
-        arguments.GetDefaultDestination(helper.GetLibraryDestination(nullptr));
-    }
+    dest =
+      arguments.GetDefaultDestination(helper.GetLibraryDestination(nullptr));
   }
 
   // Check for CMD_INSTALL_ABSOLUTE_DESTINATION diagnostics.
@@ -2578,8 +2574,7 @@
 
   cmGlobalGenerator* gg = helper.Makefile->GetGlobalGenerator();
 
-  std::string const fpath =
-    cmStrCat(dest, '/', arguments.GetPackageFileName());
+  std::string const fpath = cmStrCat(dest, '/', arguments.GetPackageName());
   if (gg->IsInstallSbomFile(fpath)) {
     status.SetError(cmStrCat("SBOM command already specified for the file "_s,
                              cmSystemTools::GetFilenameNameView(fpath), '.'));
diff --git a/Source/cmInstallSbomBuilder.cxx b/Source/cmInstallSbomBuilder.cxx
index 5561ff5..00178c7 100644
--- a/Source/cmInstallSbomBuilder.cxx
+++ b/Source/cmInstallSbomBuilder.cxx
@@ -17,12 +17,14 @@
 {
 }
 
-bool cmInstallSbomBuilder::Generate(std::ostream& os)
+bool cmInstallSbomBuilder::Generate(std::ostream& os,
+                                    std::string const& config)
 {
   if (!this->LocalGenerator) {
     return false;
   }
-  return this->GenerateForTargets(os, cmGeneratorExpression::InstallInterface);
+  return this->GenerateForTargets(os, config,
+                                  cmGeneratorExpression::InstallInterface);
 }
 
 cmExportFileGenerator::ExportInfo cmInstallSbomBuilder::FindExportInfoFor(
diff --git a/Source/cmInstallSbomBuilder.h b/Source/cmInstallSbomBuilder.h
index cb436c7..77f231d 100644
--- a/Source/cmInstallSbomBuilder.h
+++ b/Source/cmInstallSbomBuilder.h
@@ -5,6 +5,7 @@
 #include "cmConfigure.h" // IWYU pragma: keep
 
 #include <iosfwd>
+#include <string>
 #include <vector>
 
 #include "cmExportFileGenerator.h"
@@ -23,7 +24,7 @@
                        std::vector<cmExportSet*> exportSets,
                        cmLocalGenerator* lg = nullptr);
 
-  bool Generate(std::ostream& os) override;
+  bool Generate(std::ostream& os, std::string const& config) override;
 
 protected:
   cmExportFileGenerator::ExportInfo FindExportInfoFor(
diff --git a/Source/cmInstallSbomGenerator.cxx b/Source/cmInstallSbomGenerator.cxx
index 0224d06..0db7a444 100644
--- a/Source/cmInstallSbomGenerator.cxx
+++ b/Source/cmInstallSbomGenerator.cxx
@@ -2,6 +2,7 @@
    file LICENSE.rst or https://cmake.org/licensing for details.  */
 #include "cmInstallSbomGenerator.h"
 
+#include <ostream>
 #include <utility>
 #include <vector>
 
@@ -13,7 +14,9 @@
 #include "cmInstallSbomBuilder.h"
 #include "cmInstallType.h"
 #include "cmLocalGenerator.h"
+#include "cmMakefile.h"
 #include "cmSbomArguments.h"
+#include "cmScriptGenerator.h"
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
 
@@ -26,8 +29,9 @@
                        std::move(component), message, excludeFromAll, false,
                        std::move(context))
   , FilePermissions(std::move(filePermissions))
-  , SbomFileName(args.GetPackageFileName())
+  , SbomFileName(args.GetPackageName())
   , SbomFilePath(cmStrCat(this->Destination, '/', this->SbomFileName))
+  , SbomFormat(args.GetFormat())
   , Builder(cm::make_unique<cmInstallSbomBuilder>(std::move(args),
                                                   std::move(exportSets)))
 {
@@ -64,15 +68,20 @@
   cmCryptoHash hasher(cmCryptoHash::AlgoMD5);
   std::string const tempDir =
     cmStrCat(this->LocalGenerator->GetCurrentBinaryDirectory(),
-             "/CMakeFiles/Sbom/", hasher.HashString(this->Destination));
-
+             "/CMakeFiles/sbom/", hasher.HashString(this->Destination));
   cmSystemTools::MakeDirectory(tempDir);
 
-  this->TempSbomFilePath = cmStrCat(tempDir, '/', this->SbomFileName);
-
-  // Generate the SBOM file now, at cmake generate time.
-  cmGeneratedFileStream sbomStream(this->TempSbomFilePath);
-  this->Builder->Generate(sbomStream);
+  for (std::string const& c :
+       this->LocalGenerator->GetMakefile()->GetGeneratorConfigs(
+         cmMakefile::IncludeEmptyConfig)) {
+    std::string configName =
+      cmStrCat(tempDir, '/', this->SbomFileName, "-", c, ".spdx.json");
+    cmGeneratedFileStream sbomStream(configName);
+    this->TempSbomFiles.emplace(c, configName);
+    if (!this->Builder->Generate(sbomStream, c)) {
+      break;
+    }
+  }
 
   // Emit the cmake_install.cmake script to copy the file at install time.
   this->cmInstallGenerator::GenerateScript(os);
@@ -81,8 +90,12 @@
 void cmInstallSbomGenerator::GenerateScriptActions(std::ostream& os,
                                                    Indent indent)
 {
-  std::vector<std::string> files{ this->TempSbomFilePath };
-  this->AddInstallRule(os, this->Destination, cmInstallType_FILES, files,
-                       false, this->FilePermissions.c_str(), nullptr, nullptr,
-                       nullptr, indent);
+  for (auto const& i : this->TempSbomFiles) {
+    std::string configTest = this->CreateConfigTest(i.first);
+    os << indent << "if(" << configTest << ")\n";
+    this->AddInstallRule(os, this->Destination, cmInstallType_FILES,
+                         { i.second }, false, this->FilePermissions.c_str(),
+                         nullptr, nullptr, nullptr, indent.Next());
+    os << indent << "endif()\n";
+  }
 }
diff --git a/Source/cmInstallSbomGenerator.h b/Source/cmInstallSbomGenerator.h
index fd8dcde..2c65c05 100644
--- a/Source/cmInstallSbomGenerator.h
+++ b/Source/cmInstallSbomGenerator.h
@@ -5,18 +5,19 @@
 #include "cmConfigure.h" // IWYU pragma: keep
 
 #include <iosfwd>
+#include <map>
 #include <memory>
 #include <string>
 #include <vector>
 
 #include "cmInstallGenerator.h"
+#include "cmSbomArguments.h"
 
 class cmDiagnosticContext;
 class cmExportSet;
 class cmGeneratorTarget;
 class cmInstallSbomBuilder;
 class cmLocalGenerator;
-class cmSbomArguments;
 
 /** \class cmInstallSbomGenerator
  * \brief Generate installation rules for SBOM files.
@@ -59,10 +60,11 @@
   void GenerateScriptActions(std::ostream& os, Indent indent) override;
 
 private:
-  std::string TempSbomFilePath;
+  std::map<std::string, std::string> TempSbomFiles;
   std::string const FilePermissions;
   std::string const SbomFileName;
   std::string const SbomFilePath;
+  cmSbomArguments::SbomFormat SbomFormat;
   cmLocalGenerator* LocalGenerator = nullptr;
   std::unique_ptr<cmInstallSbomBuilder> Builder;
 };
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index fabf334..9dadef7 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -4251,7 +4251,7 @@
   }
 
   // Deprecate old policies.
-  if (status == cmPolicies::OLD && id <= cmPolicies::CMP0155 &&
+  if (status == cmPolicies::OLD && id <= cmPolicies::CMP0161 &&
       !(this->GetCMakeInstance()->GetIsInTryCompile() &&
         (
           // Policies set by cmCoreTryCompile::TryCompileCode.
@@ -4259,7 +4259,7 @@
           id == cmPolicies::CMP0104 || id == cmPolicies::CMP0123 ||
           id == cmPolicies::CMP0126 || id == cmPolicies::CMP0128 ||
           id == cmPolicies::CMP0136 || id == cmPolicies::CMP0141 ||
-          id == cmPolicies::CMP0155))) {
+          id == cmPolicies::CMP0155 || id == cmPolicies::CMP0157))) {
     std::unique_ptr<PolicyPushPop> ps;
     std::unique_ptr<DiagnosticPushPop> ds;
 
diff --git a/Source/cmSbomArguments.cxx b/Source/cmSbomArguments.cxx
index e3cdadd..155aefd 100644
--- a/Source/cmSbomArguments.cxx
+++ b/Source/cmSbomArguments.cxx
@@ -2,12 +2,8 @@
    file LICENSE.rst or https://cmake.org/licensing for details.  */
 #include "cmSbomArguments.h"
 
-#include <algorithm>
-
 #include <cm/string_view>
 
-#include "cmsys/String.h"
-
 #include "cmExecutionStatus.h"
 #include "cmGeneratorExpression.h"
 #include "cmStringAlgorithms.h"
@@ -82,7 +78,7 @@
   return cmStrCat(this->PackageName, "::"_s);
 }
 
-std::string cmSbomArguments::GetPackageDirName() const
+std::string cmSbomArguments::GetPackageName() const
 {
   return this->PackageName;
 }
@@ -91,9 +87,9 @@
   std::string const& root) const
 {
   if (root.empty()) {
-    return cmStrCat("sbom/"_s, this->GetPackageDirName());
+    return cmStrCat("sbom/"_s, this->GetPackageName());
   }
-  return cmStrCat(root, '/', "sbom/"_s, this->GetPackageDirName());
+  return cmStrCat(root, '/', "sbom/"_s, this->GetPackageName());
 }
 
 cmSbomArguments::SbomFormat cmSbomArguments::GetFormat() const
@@ -103,12 +99,3 @@
   }
   return ParseSbomFormat(this->Format);
 }
-
-std::string cmSbomArguments::GetPackageFileName() const
-{
-  std::string const pkgNameOnDisk = this->GetPackageDirName();
-  std::string format = GetSbomFileExtension(this->GetFormat());
-  std::transform(format.begin(), format.end(), format.begin(),
-                 cmsysString_tolower);
-  return cmStrCat(pkgNameOnDisk, format);
-}
diff --git a/Source/cmSbomArguments.h b/Source/cmSbomArguments.h
index 17bb3b5..ab62226 100644
--- a/Source/cmSbomArguments.h
+++ b/Source/cmSbomArguments.h
@@ -35,8 +35,7 @@
 
   bool Check(cmExecutionStatus& status) const override;
   std::string GetNamespace() const;
-  std::string GetPackageDirName() const;
-  std::string GetPackageFileName() const;
+  std::string GetPackageName() const;
   std::string GetDefaultDestination(std::string const& root = {}) const;
   SbomFormat GetFormat() const;
 
diff --git a/Source/cmSbomBuilder.cxx b/Source/cmSbomBuilder.cxx
index b4add75..16397a2 100644
--- a/Source/cmSbomBuilder.cxx
+++ b/Source/cmSbomBuilder.cxx
@@ -115,10 +115,11 @@
 }
 
 bool cmSbomBuilder::GenerateForTargets(
-  std::ostream& os, cmGeneratorExpression::PreprocessContext preprocessContext)
+  std::ostream& os, std::string const& config,
+  cmGeneratorExpression::PreprocessContext preprocessContext)
 {
   cmSbomDocument doc;
-  doc.Graph.reserve(256);
+  doc.Graph.reserve(512);
 
   cmSpdxCreationInfo const* ci =
     insert_back(doc.Graph, this->GenerateCreationInfo());
@@ -131,19 +132,23 @@
     this->PopulateLinkLibrariesProperty(target, preprocessContext, properties);
     this->PopulateInterfaceLinkLibrariesProperty(target, preprocessContext,
                                                  properties);
-
-    targetProps.push_back(
-      TargetProperties{ insert_back(project->RootElements,
-                                    this->GenerateImportTarget(ci, target)),
-                        target, std::move(properties) });
+    targetProps.push_back(TargetProperties{
+      insert_back(project->RootElements,
+                  this->GenerateImportTarget(ci, target)),
+      target,
+      std::move(properties),
+    });
   }
 
+  bool status = true;
   for (TargetProperties const& target : targetProps) {
-    this->GenerateProperties(doc, project, ci, target, targetProps);
+    status &=
+      this->GenerateProperties(doc, project, ci, target, targetProps, config);
   }
-
-  this->WriteSbom(doc, os);
-  return true;
+  if (status) {
+    this->WriteSbom(doc, os);
+  }
+  return status;
 }
 
 void cmSbomBuilder::WriteSbom(cmSbomDocument& doc, std::ostream& os) const
@@ -248,23 +253,31 @@
   return package;
 }
 
-void cmSbomBuilder::GenerateLinkProperties(
+bool cmSbomBuilder::GenerateLinkProperties(
   cmSbomDocument& doc, cmSpdxDocument* project, cmSpdxCreationInfo const* ci,
   std::string const& libraries, TargetProperties const& current,
-  std::vector<TargetProperties> const& allTargets) const
+  std::vector<TargetProperties> const& allTargets,
+  std::string const& config) const
 {
   auto itProp = current.Properties.find(libraries);
   if (itProp == current.Properties.end()) {
-    return;
+    return true;
   }
 
-  std::map<std::string, std::vector<std::string>> allowList = { { "LINK_ONLY",
-                                                                  {} } };
-  std::string interfaceLinkLibraries;
-  if (!cmGeneratorExpression::ForbidGeneratorExpressions(
-        current.Target, itProp->first, itProp->second, interfaceLinkLibraries,
-        allowList)) {
-    return;
+  cmGeneratorExpression ge(*current.Target->Makefile->GetCMakeInstance());
+  std::unique_ptr<cmCompiledGeneratorExpression> cge =
+    ge.Parse(itProp->second);
+  std::string evaluatedLibraries =
+    cge->Evaluate(current.Target->GetLocalGenerator(), config, current.Target);
+
+  if (cge->GetHadHeadSensitiveCondition()) {
+    current.Target->Makefile->IssueMessage(
+      MessageType::FATAL_ERROR,
+      cmStrCat("Property \"", libraries, "\" of target \"",
+               current.Target->GetName(),
+               "\" contains a generator expression that is not allowed for "
+               "SBOM generation."));
+    return false;
   }
 
   auto makeRel = [&](char const* id, char const* desc) {
@@ -316,26 +329,21 @@
     return { false, insert_back(project->Elements, std::move(pkg)) };
   };
 
-  auto handleDependencies = [&](std::vector<std::string> const& names,
-                                cmSpdxRelationship& internalDeps,
-                                cmSpdxRelationship& externalDeps) {
-    for (auto const& n : names) {
-      auto res = addArtifact(n);
-      if (!res.second) {
-        continue;
-      }
-
-      if (res.first) {
-        internalDeps.To.push_back(res.second);
-      } else {
-        externalDeps.To.push_back(res.second);
-      }
+  cmList names{ evaluatedLibraries };
+  names.sort();
+  names.remove_duplicates();
+  for (std::string const& n : names) {
+    auto res = addArtifact(n);
+    if (!res.second) {
+      continue;
     }
-  };
 
-  handleDependencies(allowList["LINK_ONLY"], linkLibraries, linkRequires);
-  handleDependencies(cmList{ interfaceLinkLibraries }, linkLibraries,
-                     buildRequires);
+    if (res.first) {
+      linkLibraries.To.push_back(res.second);
+    } else {
+      buildRequires.To.push_back(res.second);
+    }
+  }
 
   if (!linkLibraries.To.empty()) {
     insert_back(doc.Graph, std::move(linkLibraries));
@@ -346,18 +354,22 @@
   if (!buildRequires.To.empty()) {
     insert_back(doc.Graph, std::move(buildRequires));
   }
+  return true;
 }
 
 bool cmSbomBuilder::GenerateProperties(
   cmSbomDocument& doc, cmSpdxDocument* proj, cmSpdxCreationInfo const* ci,
   TargetProperties const& current,
-  std::vector<TargetProperties> const& allTargets) const
+  std::vector<TargetProperties> const& allTargets,
+  std::string const& config) const
 {
-  this->GenerateLinkProperties(doc, proj, ci, "LINK_LIBRARIES", current,
-                               allTargets);
-  this->GenerateLinkProperties(doc, proj, ci, "INTERFACE_LINK_LIBRARIES",
-                               current, allTargets);
-  return true;
+  bool status = true;
+  status &= this->GenerateLinkProperties(doc, proj, ci, "LINK_LIBRARIES",
+                                         current, allTargets, config);
+  status &= this->GenerateLinkProperties(
+    doc, proj, ci, "INTERFACE_LINK_LIBRARIES", current, allTargets, config);
+
+  return status;
 }
 
 bool cmSbomBuilder::PopulateLinkLibrariesProperty(
@@ -365,10 +377,11 @@
   cmGeneratorExpression::PreprocessContext preprocessRule,
   ImportPropertyMap& properties)
 {
-  static std::array<std::string, 3> const linkIfaceProps = {
-    { "LINK_LIBRARIES", "LINK_LIBRARIES_DIRECT",
-      "LINK_LIBRARIES_DIRECT_EXCLUDE" }
-  };
+  static std::array<std::string, 3> const linkIfaceProps = { {
+    "LINK_LIBRARIES",
+    "LINK_LIBRARIES_DIRECT",
+    "LINK_LIBRARIES_DIRECT_EXCLUDE",
+  } };
   bool hadLINK_LIBRARIES = false;
   for (std::string const& linkIfaceProp : linkIfaceProps) {
     if (cmValue input = target->GetProperty(linkIfaceProp)) {
diff --git a/Source/cmSbomBuilder.h b/Source/cmSbomBuilder.h
index 60672e6..961e9db 100644
--- a/Source/cmSbomBuilder.h
+++ b/Source/cmSbomBuilder.h
@@ -48,10 +48,9 @@
    *  query CoversTarget() before any Generate() runs. */
   void Compute(cmLocalGenerator* lg);
 
-  /** Produce the SBOM document on `os`.  Implementations pick the
-   *  generator-expression preprocess context (BuildInterface vs
-   *  InstallInterface) and delegate to GenerateForTargets. */
-  virtual bool Generate(std::ostream& os) = 0;
+  /** Produce the SBOM document on `os`.  Implementations select their own
+   *  target set (via CollectTargets) and preprocess context. */
+  virtual bool Generate(std::ostream& os, std::string const& config) = 0;
 
   /** Identifier this SBOM publishes itself as (the SPDX document name and
    *  the namespace under which other SBOMs refer to its contents). */
@@ -59,10 +58,13 @@
 
   /** True if `target` is one of the targets this SBOM directly describes. */
   bool CoversTarget(cmGeneratorTarget const* target) const;
-
-  /** True if `set` is one of the export sets this SBOM was built from. */
   bool CoversExportSet(cmExportSet const* set) const;
 
+  void AddConfiguration(std::string const& config)
+  {
+    this->Configurations.push_back(config);
+  }
+
   /** Names of peer SBOMs (same build/install mode) that cover a target.
    *  Used by NoteLinkedTarget to attribute a cross-reference when no
    *  install(export) namespace is available.  Sorted alphabetically. */
@@ -93,7 +95,7 @@
   /** Generate an sbom for the targets in this->SbomTargets. Each leaf class
    * calls this internally */
   bool GenerateForTargets(
-    std::ostream& os,
+    std::ostream& os, std::string const& config,
     cmGeneratorExpression::PreprocessContext preprocessContext);
 
   using ImportPropertyMap = std::map<std::string, std::string>;
@@ -115,15 +117,18 @@
   bool AddPackageInformation(cmSpdxPackage& artifact, std::string const& name,
                              cmPackageInformation const& package) const;
 
-  bool GenerateProperties(
-    cmSbomDocument& doc, cmSpdxDocument* project, cmSpdxCreationInfo const* ci,
-    TargetProperties const& current,
-    std::vector<TargetProperties> const& allTargets) const;
+  bool GenerateProperties(cmSbomDocument& doc, cmSpdxDocument* project,
+                          cmSpdxCreationInfo const* ci,
+                          TargetProperties const& current,
+                          std::vector<TargetProperties> const& allTargets,
+                          std::string const& config) const;
 
-  void GenerateLinkProperties(
-    cmSbomDocument& doc, cmSpdxDocument* project, cmSpdxCreationInfo const* ci,
-    std::string const& libraries, TargetProperties const& current,
-    std::vector<TargetProperties> const& allTargets) const;
+  bool GenerateLinkProperties(cmSbomDocument& doc, cmSpdxDocument* project,
+                              cmSpdxCreationInfo const* ci,
+                              std::string const& libraries,
+                              TargetProperties const& current,
+                              std::vector<TargetProperties> const& allTargets,
+                              std::string const& config) const;
 
   bool NoteLinkedTarget(cmGeneratorTarget const* target,
                         std::string const& linkedName,
@@ -176,4 +181,5 @@
   // Accumulated during generation
   std::map<std::string, LinkInfo> LinkTargets;
   std::map<std::string, cmPackageInformation> Requirements;
+  std::vector<std::string> Configurations;
 };
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index d9a77de..7711dd4 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -2505,6 +2505,7 @@
 
 bool extract_tar(std::string const& arFileName,
                  std::vector<std::string> const& files,
+                 std::vector<std::string> const& excludeFiles,
                  std::string const& encoding, bool verbose,
                  cmSystemTools::cmTarExtractTimestamps extractTimestamps,
                  bool extract)
@@ -2551,6 +2552,14 @@
     }
   }
 
+  for (auto const& filename : excludeFiles) {
+    if (archive_match_exclude_pattern(matching, filename.c_str()) !=
+        ARCHIVE_OK) {
+      cmSystemTools::Error("Failed to add to exclusion list: " + filename);
+      return false;
+    }
+  }
+
   int r = cm_archive_read_open_filename(a, arFileName.c_str(), 10240);
   if (r) {
     ArchiveError("Problem with archive_read_open_filename(): ", a);
@@ -2644,15 +2653,17 @@
 
 bool cmSystemTools::ExtractTar(std::string const& arFileName,
                                std::vector<std::string> const& files,
+                               std::vector<std::string> const& excludeFiles,
                                cmTarExtractTimestamps extractTimestamps,
                                std::string const& encoding, bool verbose)
 {
 #if !defined(CMAKE_BOOTSTRAP)
-  return extract_tar(arFileName, files, encoding, verbose, extractTimestamps,
-                     true);
+  return extract_tar(arFileName, files, excludeFiles, encoding, verbose,
+                     extractTimestamps, true);
 #else
   (void)arFileName;
   (void)files;
+  (void)excludeFiles;
   (void)extractTimestamps;
   (void)encoding;
   (void)verbose;
@@ -2662,14 +2673,16 @@
 
 bool cmSystemTools::ListTar(std::string const& arFileName,
                             std::vector<std::string> const& files,
+                            std::vector<std::string> const& excludeFiles,
                             std::string const& encoding, bool verbose)
 {
 #if !defined(CMAKE_BOOTSTRAP)
-  return extract_tar(arFileName, files, encoding, verbose,
+  return extract_tar(arFileName, files, excludeFiles, encoding, verbose,
                      cmTarExtractTimestamps::Yes, false);
 #else
   (void)arFileName;
   (void)files;
+  (void)excludeFiles;
   (void)encoding;
   (void)verbose;
   return false;
diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h
index 17a6310..e72e5ea 100644
--- a/Source/cmSystemTools.h
+++ b/Source/cmSystemTools.h
@@ -523,6 +523,7 @@
 
   static bool ListTar(std::string const& arFileName,
                       std::vector<std::string> const& files,
+                      std::vector<std::string> const& excludeFiles,
                       std::string const& encoding, bool verbose);
   static bool CreateTar(std::string const& arFileName,
                         std::vector<std::string> const& files,
@@ -534,6 +535,7 @@
                         int compressionLevel = 0, int numThreads = 1);
   static bool ExtractTar(std::string const& arFileName,
                          std::vector<std::string> const& files,
+                         std::vector<std::string> const& excludeFiles,
                          cmTarExtractTimestamps extractTimestamps,
                          std::string const& encoding, bool verbose);
 
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx
index 6610da0..e942370 100644
--- a/Source/cmcmd.cxx
+++ b/Source/cmcmd.cxx
@@ -2121,7 +2121,7 @@
       }
 
       if (action == cmSystemTools::TarActionList) {
-        if (!cmSystemTools::ListTar(outFile, files, encoding, verbose)) {
+        if (!cmSystemTools::ListTar(outFile, files, {}, encoding, verbose)) {
           cmSystemTools::Error("Problem listing tar: " + outFile);
           return 1;
         }
@@ -2136,7 +2136,7 @@
           return 1;
         }
       } else if (action == cmSystemTools::TarActionExtract) {
-        if (!cmSystemTools::ExtractTar(outFile, files, extractTimestamps,
+        if (!cmSystemTools::ExtractTar(outFile, files, {}, extractTimestamps,
                                        encoding, verbose)) {
           cmSystemTools::Error(
             cmStrCat("Problem extracting tar:\n  ", outFile));
diff --git a/Tests/Fuzzing/cmArchiveExtractFuzzer.cxx b/Tests/Fuzzing/cmArchiveExtractFuzzer.cxx
index 4fb2b73..ab72a9d 100644
--- a/Tests/Fuzzing/cmArchiveExtractFuzzer.cxx
+++ b/Tests/Fuzzing/cmArchiveExtractFuzzer.cxx
@@ -86,9 +86,10 @@
     std::vector<std::string> files;
 
     // Extract without verbose, with timestamps
+    std::vector<std::string> excludeFiles;
     bool result1 = cmSystemTools::ExtractTar(
-      archiveFile, files, cmSystemTools::cmTarExtractTimestamps::Yes, "UTF-8",
-      false);
+      archiveFile, files, excludeFiles,
+      cmSystemTools::cmTarExtractTimestamps::Yes, "UTF-8", false);
     (void)result1;
 
     // Restore directory BEFORE removing (can't remove cwd)
@@ -103,8 +104,8 @@
       // Extract with verbose, without timestamps
       files.clear();
       bool result2 = cmSystemTools::ExtractTar(
-        archiveFile, files, cmSystemTools::cmTarExtractTimestamps::No, "UTF-8",
-        true);
+        archiveFile, files, excludeFiles,
+        cmSystemTools::cmTarExtractTimestamps::No, "UTF-8", true);
       (void)result2;
 
       // Restore directory
diff --git a/Tests/RunCMake/CPackConfig/CMP0161-OLD-stderr.txt b/Tests/RunCMake/CPackConfig/CMP0161-OLD-stderr.txt
new file mode 100644
index 0000000..4d30221
--- /dev/null
+++ b/Tests/RunCMake/CPackConfig/CMP0161-OLD-stderr.txt
@@ -0,0 +1,12 @@
+^CMake Warning \(deprecated\) at CMP0161-OLD\.cmake:[0-9]+ \(cmake_policy\):
+  The OLD behavior for policy CMP0161 will be removed from a future version
+  of CMake\.
+
+  The cmake-policies\(7\) manual explains that the OLD behaviors of all
+  policies are deprecated and that a policy should be set to OLD only under
+  specific short-term circumstances\.  Projects should be ported to the NEW
+  behavior and not rely on setting a policy to OLD\.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
+This warning is for project developers\.  Use -Wno-author or -Wno-deprecated
+to suppress it\.
diff --git a/Tests/RunCMake/CrosscompilingEmulator/AddTest-CMP0158-OLD-stderr.txt b/Tests/RunCMake/CrosscompilingEmulator/AddTest-CMP0158-OLD-stderr.txt
new file mode 100644
index 0000000..36e7cea
--- /dev/null
+++ b/Tests/RunCMake/CrosscompilingEmulator/AddTest-CMP0158-OLD-stderr.txt
@@ -0,0 +1,12 @@
+^CMake Warning \(deprecated\) at AddTest-CMP0158-OLD\.cmake:[0-9]+ \(cmake_policy\):
+  The OLD behavior for policy CMP0158 will be removed from a future version
+  of CMake\.
+
+  The cmake-policies\(7\) manual explains that the OLD behaviors of all
+  policies are deprecated and that a policy should be set to OLD only under
+  specific short-term circumstances\.  Projects should be ported to the NEW
+  behavior and not rely on setting a policy to OLD\.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
+This warning is for project developers\.  Use -Wno-author or -Wno-deprecated
+to suppress it\.
diff --git a/Tests/RunCMake/EnvSbom/ApplicationTarget-install-check.cmake b/Tests/RunCMake/EnvSbom/ApplicationTarget-install-check.cmake
index b8c7070..8b670d5 100644
--- a/Tests/RunCMake/EnvSbom/ApplicationTarget-install-check.cmake
+++ b/Tests/RunCMake/EnvSbom/ApplicationTarget-install-check.cmake
@@ -1,2 +1,2 @@
-file(READ "${RunCMake_TEST_INSTALL_DIR}/lib/sbom/test_project/application_targets.spdx.json" content)
+file(READ "${RunCMake_TEST_INSTALL_DIR}/lib/sbom/application_targets/application_targets-Debug.spdx.json" content)
 include(${CMAKE_CURRENT_LIST_DIR}/../Sbom/ApplicationTarget-install-check.cmake)
diff --git a/Tests/RunCMake/EnvSbom/Config-check.cmake b/Tests/RunCMake/EnvSbom/Config-check.cmake
new file mode 100644
index 0000000..d5127a6
--- /dev/null
+++ b/Tests/RunCMake/EnvSbom/Config-check.cmake
@@ -0,0 +1,11 @@
+include(${CMAKE_CURRENT_LIST_DIR}/../Sbom/Assertions.cmake)
+
+get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
+if(_isMultiConfig)
+  file(READ "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/sbom/800147c20378e0c5769bafa56e83195d/foo-Debug.spdx.json" DebugSbom)
+  file(READ "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/sbom/800147c20378e0c5769bafa56e83195d/foo-Release.spdx.json" ReleaseSbom)
+else()
+  file(READ "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/sbom/800147c20378e0c5769bafa56e83195d/foo-Debug.spdx.json" DebugSbom)
+endif()
+
+include(${CMAKE_CURRENT_LIST_DIR}/../Sbom/Config-check.cmake)
diff --git a/Tests/RunCMake/EnvSbom/Config.cmake b/Tests/RunCMake/EnvSbom/Config.cmake
new file mode 100644
index 0000000..12f1808
--- /dev/null
+++ b/Tests/RunCMake/EnvSbom/Config.cmake
@@ -0,0 +1 @@
+include(${CMAKE_CURRENT_LIST_DIR}/../Sbom/Config.cmake)
diff --git a/Tests/RunCMake/EnvSbom/ForbiddenGenex-result.txt b/Tests/RunCMake/EnvSbom/ForbiddenGenex-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/EnvSbom/ForbiddenGenex-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/EnvSbom/ForbiddenGenex-stderr.txt b/Tests/RunCMake/EnvSbom/ForbiddenGenex-stderr.txt
new file mode 100644
index 0000000..d878e11
--- /dev/null
+++ b/Tests/RunCMake/EnvSbom/ForbiddenGenex-stderr.txt
@@ -0,0 +1,3 @@
+CMake Error in CMakeLists.txt:
+  Property "INTERFACE_LINK_LIBRARIES" of target "foo" contains a generator
+  expression that is not allowed for SBOM generation.
diff --git a/Tests/RunCMake/EnvSbom/ForbiddenGenex.cmake b/Tests/RunCMake/EnvSbom/ForbiddenGenex.cmake
new file mode 100644
index 0000000..623b5a8
--- /dev/null
+++ b/Tests/RunCMake/EnvSbom/ForbiddenGenex.cmake
@@ -0,0 +1 @@
+include(${CMAKE_CURRENT_LIST_DIR}/../Sbom/ForbiddenGenex.cmake)
diff --git a/Tests/RunCMake/EnvSbom/Genex-check.cmake b/Tests/RunCMake/EnvSbom/Genex-check.cmake
new file mode 100644
index 0000000..38c1ddf
--- /dev/null
+++ b/Tests/RunCMake/EnvSbom/Genex-check.cmake
@@ -0,0 +1,11 @@
+include(${CMAKE_CURRENT_LIST_DIR}/../Sbom/Assertions.cmake)
+
+get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
+if(_isMultiConfig)
+  file(READ "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/sbom/800147c20378e0c5769bafa56e83195d/foo-BarConfig.spdx.json" BarConfig)
+  file(READ "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/sbom/800147c20378e0c5769bafa56e83195d/foo-BazConfig.spdx.json" BazConfig)
+else()
+  file(READ "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/sbom/800147c20378e0c5769bafa56e83195d/foo-BarConfig.spdx.json" BarConfig)
+endif()
+
+include(${CMAKE_CURRENT_LIST_DIR}/../Sbom/Genex-check.cmake)
diff --git a/Tests/RunCMake/EnvSbom/Genex.cmake b/Tests/RunCMake/EnvSbom/Genex.cmake
new file mode 100644
index 0000000..208fc0b
--- /dev/null
+++ b/Tests/RunCMake/EnvSbom/Genex.cmake
@@ -0,0 +1 @@
+include(${CMAKE_CURRENT_LIST_DIR}/../Sbom/Genex.cmake)
diff --git a/Tests/RunCMake/EnvSbom/InterfaceTarget-install-check.cmake b/Tests/RunCMake/EnvSbom/InterfaceTarget-install-check.cmake
index 0fba94c..b99155a 100644
--- a/Tests/RunCMake/EnvSbom/InterfaceTarget-install-check.cmake
+++ b/Tests/RunCMake/EnvSbom/InterfaceTarget-install-check.cmake
@@ -1,2 +1,2 @@
-file(READ "${RunCMake_TEST_INSTALL_DIR}/lib/sbom/test_project/interface_targets.spdx.json" content)
+file(READ "${RunCMake_TEST_INSTALL_DIR}/lib/sbom/interface_targets/interface_targets-Debug.spdx.json" content)
 include(${CMAKE_CURRENT_LIST_DIR}/../Sbom/InterfaceTarget-install-check.cmake)
diff --git a/Tests/RunCMake/EnvSbom/MissingPackageNamespace-install-check.cmake b/Tests/RunCMake/EnvSbom/MissingPackageNamespace-install-check.cmake
index f162630..e2f1048 100644
--- a/Tests/RunCMake/EnvSbom/MissingPackageNamespace-install-check.cmake
+++ b/Tests/RunCMake/EnvSbom/MissingPackageNamespace-install-check.cmake
@@ -1,2 +1,2 @@
-file(READ "${RunCMake_TEST_INSTALL_DIR}/lib/sbom/test_project/test_targets.spdx.json" content)
+file(READ "${RunCMake_TEST_INSTALL_DIR}/lib/sbom/test_targets/test_targets-Debug.spdx.json" content)
 include(${CMAKE_CURRENT_LIST_DIR}/../Sbom/MissingPackageNamespace-install-check.cmake)
diff --git a/Tests/RunCMake/EnvSbom/PartialCoverage-install-check.cmake b/Tests/RunCMake/EnvSbom/PartialCoverage-install-check.cmake
index f33fa32..19892ca 100644
--- a/Tests/RunCMake/EnvSbom/PartialCoverage-install-check.cmake
+++ b/Tests/RunCMake/EnvSbom/PartialCoverage-install-check.cmake
@@ -1,20 +1,20 @@
 set(failures "")
 
 foreach(f explicit_root_sbom explicit_subdir_sbom)
-  if(NOT EXISTS "${RunCMake_TEST_INSTALL_DIR}/${f}.spdx.json")
-    list(APPEND failures "expected explicit SBOM ${f}.spdx.json to exist")
+  if(NOT EXISTS "${RunCMake_TEST_INSTALL_DIR}/${f}-Debug.spdx.json")
+    list(APPEND failures "expected explicit SBOM ${f}-Debug.spdx.json to exist")
   endif()
 endforeach()
 
 foreach(f implicit_root implicit_subdir)
-  if(NOT EXISTS "${RunCMake_TEST_INSTALL_DIR}/lib/sbom/test_project/${f}.spdx.json")
-    list(APPEND failures "expected autogen SBOM ${f}.spdx.json to exist")
+  if(NOT EXISTS "${RunCMake_TEST_INSTALL_DIR}/lib/sbom/${f}/${f}-Debug.spdx.json")
+    list(APPEND failures "expected autogen SBOM ${f}-Debug.spdx.json to exist")
   endif()
 endforeach()
 
 foreach(f explicit_root explicit_subdir)
-  if(EXISTS "${RunCMake_TEST_INSTALL_DIR}/lib/sbom/test_project/${f}.spdx.json")
-    list(APPEND failures "autogen wrongly produced ${f}.spdx.json (should be suppressed by explicit install(SBOM))")
+  if(EXISTS "${RunCMake_TEST_INSTALL_DIR}/lib/sbom/${f}/${f}-Debug.spdx.json")
+    list(APPEND failures "autogen wrongly produced ${f}-Debug.spdx.json (should be suppressed by explicit install(SBOM))")
   endif()
 endforeach()
 
diff --git a/Tests/RunCMake/EnvSbom/ProjectMetadata-install-check.cmake b/Tests/RunCMake/EnvSbom/ProjectMetadata-install-check.cmake
index f836b65..ae99a64 100644
--- a/Tests/RunCMake/EnvSbom/ProjectMetadata-install-check.cmake
+++ b/Tests/RunCMake/EnvSbom/ProjectMetadata-install-check.cmake
@@ -1,2 +1,2 @@
-file(READ "${RunCMake_TEST_INSTALL_DIR}/lib/sbom/test/test_targets.spdx.json" content)
+file(READ "${RunCMake_TEST_INSTALL_DIR}/lib/sbom/test_targets/test_targets-Debug.spdx.json" content)
 include(${CMAKE_CURRENT_LIST_DIR}/../Sbom/ProjectMetadata-install-check.cmake)
diff --git a/Tests/RunCMake/EnvSbom/RunCMakeTest.cmake b/Tests/RunCMake/EnvSbom/RunCMakeTest.cmake
index a188fcc..78debd2 100644
--- a/Tests/RunCMake/EnvSbom/RunCMakeTest.cmake
+++ b/Tests/RunCMake/EnvSbom/RunCMakeTest.cmake
@@ -11,7 +11,7 @@
   set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${test}-build)
   set(RunCMake_TEST_OPTIONS ${common_test_options})
   if(NOT RunCMake_GENERATOR_IS_MULTI_CONFIG)
-    list(APPEND RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=DEBUG)
+    list(APPEND RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Debug)
   endif()
   run_cmake(${test})
 endfunction()
@@ -23,7 +23,7 @@
   set(RunCMake_TEST_OPTIONS ${common_test_options} ${extra_options})
   list(APPEND RunCMake_TEST_OPTIONS -DCMAKE_INSTALL_PREFIX=${RunCMake_TEST_INSTALL_DIR})
   if(NOT RunCMake_GENERATOR_IS_MULTI_CONFIG)
-    list(APPEND RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=DEBUG)
+    list(APPEND RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Debug)
   endif()
 
   run_cmake(${test})
@@ -34,6 +34,14 @@
   run_cmake_command(${test}-install ${CMAKE_COMMAND} --install . --config Debug)
 endfunction()
 
+function(run_cmake_configure test)
+  set(extra_options ${ARGN})
+  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${test}-build)
+  set(RunCMake_TEST_OPTIONS ${common_test_options} ${extra_options})
+  run_cmake(${test})
+endfunction()
+
+
 run_cmake_install(ApplicationTarget)
 run_cmake_install(InterfaceTarget)
 run_cmake_install(SharedTarget)
@@ -43,3 +51,7 @@
 run_cmake_install(PartialCoverage)
 
 run_cmake_error(ReferencesNonExportedTarget)
+
+run_cmake_configure(Config)
+run_cmake_configure(Genex)
+run_cmake_configure(ForbiddenGenex)
diff --git a/Tests/RunCMake/EnvSbom/SharedTarget-install-check.cmake b/Tests/RunCMake/EnvSbom/SharedTarget-install-check.cmake
index 7bcf116..f418838 100644
--- a/Tests/RunCMake/EnvSbom/SharedTarget-install-check.cmake
+++ b/Tests/RunCMake/EnvSbom/SharedTarget-install-check.cmake
@@ -1,2 +1,2 @@
-file(READ "${RunCMake_TEST_INSTALL_DIR}/lib/sbom/test_project/shared_targets.spdx.json" content)
+file(READ "${RunCMake_TEST_INSTALL_DIR}/lib/sbom/shared_targets/shared_targets-Debug.spdx.json" content)
 include(${CMAKE_CURRENT_LIST_DIR}/../Sbom/SharedTarget-install-check.cmake)
diff --git a/Tests/RunCMake/ExportSbom/ApplicationTarget-install-check.cmake b/Tests/RunCMake/ExportSbom/ApplicationTarget-install-check.cmake
index 0ff030e..86e9fe3 100644
--- a/Tests/RunCMake/ExportSbom/ApplicationTarget-install-check.cmake
+++ b/Tests/RunCMake/ExportSbom/ApplicationTarget-install-check.cmake
@@ -1,2 +1,2 @@
-file(READ "${RunCMake_TEST_BINARY_DIR}/sbom/application_targets/application_targets.spdx.json" content)
+file(READ "${RunCMake_TEST_BINARY_DIR}/sbom/application_targets/application_targets-Debug.spdx.json" content)
 include(${CMAKE_CURRENT_LIST_DIR}/../Sbom/ApplicationTarget-install-check.cmake)
diff --git a/Tests/RunCMake/ExportSbom/Config-check.cmake b/Tests/RunCMake/ExportSbom/Config-check.cmake
new file mode 100644
index 0000000..61f1b06
--- /dev/null
+++ b/Tests/RunCMake/ExportSbom/Config-check.cmake
@@ -0,0 +1,11 @@
+include(${CMAKE_CURRENT_LIST_DIR}/../Sbom/Assertions.cmake)
+
+get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
+if(_isMultiConfig)
+  file(READ "${RunCMake_TEST_BINARY_DIR}/sbom/foo/foo-Debug.spdx.json" DebugSbom)
+  file(READ "${RunCMake_TEST_BINARY_DIR}/sbom/foo/foo-Release.spdx.json" ReleaseSbom)
+else()
+  file(READ "${RunCMake_TEST_BINARY_DIR}/sbom/foo/foo-Debug.spdx.json" DebugSbom)
+endif()
+
+include(${CMAKE_CURRENT_LIST_DIR}/../Sbom/Config-check.cmake)
diff --git a/Tests/RunCMake/ExportSbom/Config.cmake b/Tests/RunCMake/ExportSbom/Config.cmake
new file mode 100644
index 0000000..8d10713
--- /dev/null
+++ b/Tests/RunCMake/ExportSbom/Config.cmake
@@ -0,0 +1,6 @@
+include(${CMAKE_CURRENT_LIST_DIR}/../Sbom/Config.cmake)
+
+export(SBOM foo
+  EXPORTS foo
+  FORMAT "spdx-3.0+json"
+)
diff --git a/Tests/RunCMake/ExportSbom/DuplicateSbom-stderr.txt b/Tests/RunCMake/ExportSbom/DuplicateSbom-stderr.txt
index c0d4b12..bfc26ed 100644
--- a/Tests/RunCMake/ExportSbom/DuplicateSbom-stderr.txt
+++ b/Tests/RunCMake/ExportSbom/DuplicateSbom-stderr.txt
@@ -1,2 +1,2 @@
 CMake Error at DuplicateSbom\.cmake:[0-9]+ \(export\):
-  export SBOM command already specified for the file mySbom\.spdx\.json\.
+  export SBOM command already specified for the file mySbom.
diff --git a/Tests/RunCMake/ExportSbom/EmptyNamespaceFallback-install-check.cmake b/Tests/RunCMake/ExportSbom/EmptyNamespaceFallback-install-check.cmake
index ce8270e..ddc20d7 100644
--- a/Tests/RunCMake/ExportSbom/EmptyNamespaceFallback-install-check.cmake
+++ b/Tests/RunCMake/ExportSbom/EmptyNamespaceFallback-install-check.cmake
@@ -1,2 +1,2 @@
-file(READ "${RunCMake_TEST_BINARY_DIR}/sbom/mySbom/mySbom.spdx.json" content)
+file(READ "${RunCMake_TEST_BINARY_DIR}/sbom/mySbom/mySbom-Debug.spdx.json" content)
 include(${CMAKE_CURRENT_LIST_DIR}/../Sbom/EmptyNamespaceFallback-install-check.cmake)
diff --git a/Tests/RunCMake/ExportSbom/ForbiddenGenex-result.txt b/Tests/RunCMake/ExportSbom/ForbiddenGenex-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/ExportSbom/ForbiddenGenex-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/ExportSbom/ForbiddenGenex-stderr.txt b/Tests/RunCMake/ExportSbom/ForbiddenGenex-stderr.txt
new file mode 100644
index 0000000..d878e11
--- /dev/null
+++ b/Tests/RunCMake/ExportSbom/ForbiddenGenex-stderr.txt
@@ -0,0 +1,3 @@
+CMake Error in CMakeLists.txt:
+  Property "INTERFACE_LINK_LIBRARIES" of target "foo" contains a generator
+  expression that is not allowed for SBOM generation.
diff --git a/Tests/RunCMake/ExportSbom/ForbiddenGenex.cmake b/Tests/RunCMake/ExportSbom/ForbiddenGenex.cmake
new file mode 100644
index 0000000..2b6f6a5
--- /dev/null
+++ b/Tests/RunCMake/ExportSbom/ForbiddenGenex.cmake
@@ -0,0 +1,5 @@
+include(${CMAKE_CURRENT_LIST_DIR}/../Sbom/ForbiddenGenex.cmake)
+export(SBOM foo
+  EXPORTS foo
+  FORMAT "spdx-3.0+json"
+)
diff --git a/Tests/RunCMake/ExportSbom/Genex-check.cmake b/Tests/RunCMake/ExportSbom/Genex-check.cmake
new file mode 100644
index 0000000..9ae850e
--- /dev/null
+++ b/Tests/RunCMake/ExportSbom/Genex-check.cmake
@@ -0,0 +1,11 @@
+include(${CMAKE_CURRENT_LIST_DIR}/../Sbom/Assertions.cmake)
+
+get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
+if(_isMultiConfig)
+  file(READ "${RunCMake_TEST_BINARY_DIR}/sbom/foo/foo-BarConfig.spdx.json" BarConfig)
+  file(READ "${RunCMake_TEST_BINARY_DIR}/sbom/foo/foo-BazConfig.spdx.json" BazConfig)
+else()
+  file(READ "${RunCMake_TEST_BINARY_DIR}/sbom/foo/foo-BarConfig.spdx.json" BarConfig)
+endif()
+
+include(${CMAKE_CURRENT_LIST_DIR}/../Sbom/Genex-check.cmake)
diff --git a/Tests/RunCMake/ExportSbom/Genex.cmake b/Tests/RunCMake/ExportSbom/Genex.cmake
new file mode 100644
index 0000000..fadbf19
--- /dev/null
+++ b/Tests/RunCMake/ExportSbom/Genex.cmake
@@ -0,0 +1,5 @@
+include(${CMAKE_CURRENT_LIST_DIR}/../Sbom/Genex.cmake)
+export(SBOM foo
+  EXPORTS foo
+  FORMAT "spdx-3.0+json"
+)
diff --git a/Tests/RunCMake/ExportSbom/InterfaceTarget-install-check.cmake b/Tests/RunCMake/ExportSbom/InterfaceTarget-install-check.cmake
index 47f7e41..deaf2a1 100644
--- a/Tests/RunCMake/ExportSbom/InterfaceTarget-install-check.cmake
+++ b/Tests/RunCMake/ExportSbom/InterfaceTarget-install-check.cmake
@@ -1,2 +1,2 @@
-file(READ "${RunCMake_TEST_BINARY_DIR}/sbom/interface_targets/interface_targets.spdx.json" content)
+file(READ "${RunCMake_TEST_BINARY_DIR}/sbom/interface_targets/interface_targets-Debug.spdx.json" content)
 include(${CMAKE_CURRENT_LIST_DIR}/../Sbom/InterfaceTarget-install-check.cmake)
diff --git a/Tests/RunCMake/ExportSbom/MissingPackageNamespace-install-check.cmake b/Tests/RunCMake/ExportSbom/MissingPackageNamespace-install-check.cmake
index 2583d26..eacc28a 100644
--- a/Tests/RunCMake/ExportSbom/MissingPackageNamespace-install-check.cmake
+++ b/Tests/RunCMake/ExportSbom/MissingPackageNamespace-install-check.cmake
@@ -1,2 +1,2 @@
-file(READ "${RunCMake_TEST_BINARY_DIR}/sbom/test_targets/test_targets.spdx.json" content)
+file(READ "${RunCMake_TEST_BINARY_DIR}/sbom/test_targets/test_targets-Debug.spdx.json" content)
 include(${CMAKE_CURRENT_LIST_DIR}/../Sbom/MissingPackageNamespace-install-check.cmake)
diff --git a/Tests/RunCMake/ExportSbom/MultiSetSingleSbom-install-check.cmake b/Tests/RunCMake/ExportSbom/MultiSetSingleSbom-install-check.cmake
index 791c4cb..29a9c56 100644
--- a/Tests/RunCMake/ExportSbom/MultiSetSingleSbom-install-check.cmake
+++ b/Tests/RunCMake/ExportSbom/MultiSetSingleSbom-install-check.cmake
@@ -1,2 +1,2 @@
-file(READ "${RunCMake_TEST_BINARY_DIR}/sbom/mySbom/mySbom.spdx.json" content)
+file(READ "${RunCMake_TEST_BINARY_DIR}/sbom/mySbom/mySbom-Debug.spdx.json" content)
 include(${CMAKE_CURRENT_LIST_DIR}/../Sbom/MultiSetSingleSbom-install-check.cmake)
diff --git a/Tests/RunCMake/ExportSbom/ProjectMetadata-install-check.cmake b/Tests/RunCMake/ExportSbom/ProjectMetadata-install-check.cmake
index 502cd43..6797643 100644
--- a/Tests/RunCMake/ExportSbom/ProjectMetadata-install-check.cmake
+++ b/Tests/RunCMake/ExportSbom/ProjectMetadata-install-check.cmake
@@ -1,3 +1,3 @@
-file(READ "${RunCMake_TEST_BINARY_DIR}/sbom/test_targets/test_targets.spdx.json" content)
+file(READ "${RunCMake_TEST_BINARY_DIR}/sbom/test_targets/test_targets-Debug.spdx.json" content)
 include(${CMAKE_CURRENT_LIST_DIR}/../Sbom/ProjectMetadata-install-check.cmake)
 include(${CMAKE_CURRENT_LIST_DIR}/../Sbom/ProjectMetadataExplicitAssertions.cmake)
diff --git a/Tests/RunCMake/ExportSbom/Requirements-install-check.cmake b/Tests/RunCMake/ExportSbom/Requirements-install-check.cmake
index e0de7e7..c801c09 100644
--- a/Tests/RunCMake/ExportSbom/Requirements-install-check.cmake
+++ b/Tests/RunCMake/ExportSbom/Requirements-install-check.cmake
@@ -1,3 +1,3 @@
-file(READ "${RunCMake_TEST_BINARY_DIR}/sbom/bar_sbom/bar_sbom.spdx.json" BAR_CONTENT)
-file(READ "${RunCMake_TEST_BINARY_DIR}/sbom/foo_sbom/foo_sbom.spdx.json" FOO_CONTENT)
+file(READ "${RunCMake_TEST_BINARY_DIR}/sbom/bar_sbom/bar_sbom-Debug.spdx.json" BAR_CONTENT)
+file(READ "${RunCMake_TEST_BINARY_DIR}/sbom/foo_sbom/foo_sbom-Debug.spdx.json" FOO_CONTENT)
 include(${CMAKE_CURRENT_LIST_DIR}/../Sbom/Requirements-install-check.cmake)
diff --git a/Tests/RunCMake/ExportSbom/RunCMakeTest.cmake b/Tests/RunCMake/ExportSbom/RunCMakeTest.cmake
index 244b349..4f1f0ef 100644
--- a/Tests/RunCMake/ExportSbom/RunCMakeTest.cmake
+++ b/Tests/RunCMake/ExportSbom/RunCMakeTest.cmake
@@ -9,7 +9,7 @@
   set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${test}-build)
   set(RunCMake_TEST_OPTIONS ${common_test_options})
   if(NOT RunCMake_GENERATOR_IS_MULTI_CONFIG)
-    list(APPEND RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=DEBUG)
+    list(APPEND RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Debug)
   endif()
   run_cmake(${test})
 endfunction()
@@ -21,7 +21,7 @@
   set(RunCMake_TEST_OPTIONS ${common_test_options} ${extra_options})
   list(APPEND RunCMake_TEST_OPTIONS -DCMAKE_INSTALL_PREFIX=${RunCMake_TEST_INSTALL_DIR})
   if(NOT RunCMake_GENERATOR_IS_MULTI_CONFIG)
-    list(APPEND RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=DEBUG)
+    list(APPEND RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Debug)
   endif()
 
   run_cmake(${test})
@@ -32,6 +32,13 @@
   run_cmake_command(${test}-install ${CMAKE_COMMAND} --install . --config Debug)
 endfunction()
 
+function(run_cmake_configure test)
+  set(extra_options ${ARGN})
+  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${test}-build)
+  set(RunCMake_TEST_OPTIONS ${common_test_options} ${extra_options})
+  run_cmake(${test})
+endfunction()
+
 run_cmake_install(ApplicationTarget)
 run_cmake_install(InstallExportPlusSbomSameSet)
 run_cmake_install(InterfaceTarget)
@@ -50,3 +57,7 @@
 run_cmake_error(MultiNamespaceAmbiguity)
 run_cmake_error(MultiSetAmbiguity)
 run_cmake_error(DuplicateSbom)
+
+run_cmake_configure(Config)
+run_cmake_configure(Genex)
+run_cmake_configure(ForbiddenGenex)
diff --git a/Tests/RunCMake/ExportSbom/SbomNamespaceAmbiguity-install-check.cmake b/Tests/RunCMake/ExportSbom/SbomNamespaceAmbiguity-install-check.cmake
index 31aa1bc..79684b2 100644
--- a/Tests/RunCMake/ExportSbom/SbomNamespaceAmbiguity-install-check.cmake
+++ b/Tests/RunCMake/ExportSbom/SbomNamespaceAmbiguity-install-check.cmake
@@ -1,2 +1,2 @@
-file(READ "${RunCMake_TEST_BINARY_DIR}/sbom/bar_sbom/bar_sbom.spdx.json" BAR_CONTENT)
+file(READ "${RunCMake_TEST_BINARY_DIR}/sbom/bar_sbom/bar_sbom-Debug.spdx.json" BAR_CONTENT)
 include(${CMAKE_CURRENT_LIST_DIR}/../Sbom/SbomNamespaceAmbiguity-install-check.cmake)
diff --git a/Tests/RunCMake/ExportSbom/SbomNamespaceFallback-install-check.cmake b/Tests/RunCMake/ExportSbom/SbomNamespaceFallback-install-check.cmake
index df0183c..08ded79 100644
--- a/Tests/RunCMake/ExportSbom/SbomNamespaceFallback-install-check.cmake
+++ b/Tests/RunCMake/ExportSbom/SbomNamespaceFallback-install-check.cmake
@@ -1,3 +1,3 @@
-file(READ "${RunCMake_TEST_BINARY_DIR}/sbom/bar/bar.spdx.json" BAR_CONTENT)
-file(READ "${RunCMake_TEST_BINARY_DIR}/sbom/foo/foo.spdx.json" FOO_CONTENT)
+file(READ "${RunCMake_TEST_BINARY_DIR}/sbom/bar/bar-Debug.spdx.json" BAR_CONTENT)
+file(READ "${RunCMake_TEST_BINARY_DIR}/sbom/foo/foo-Debug.spdx.json" FOO_CONTENT)
 include(${CMAKE_CURRENT_LIST_DIR}/../Sbom/SbomNamespaceFallback-install-check.cmake)
diff --git a/Tests/RunCMake/ExportSbom/SharedTarget-install-check.cmake b/Tests/RunCMake/ExportSbom/SharedTarget-install-check.cmake
index 66c1817..83bf00f 100644
--- a/Tests/RunCMake/ExportSbom/SharedTarget-install-check.cmake
+++ b/Tests/RunCMake/ExportSbom/SharedTarget-install-check.cmake
@@ -1,2 +1,2 @@
-file(READ "${RunCMake_TEST_BINARY_DIR}/sbom/shared_targets/shared_targets.spdx.json" content)
+file(READ "${RunCMake_TEST_BINARY_DIR}/sbom/shared_targets/shared_targets-Debug.spdx.json" content)
 include(${CMAKE_CURRENT_LIST_DIR}/../Sbom/SharedTarget-install-check.cmake)
diff --git a/Tests/RunCMake/ExportSbom/TargetInMultipleSets-install-check.cmake b/Tests/RunCMake/ExportSbom/TargetInMultipleSets-install-check.cmake
index 6a0d77f..5a79552 100644
--- a/Tests/RunCMake/ExportSbom/TargetInMultipleSets-install-check.cmake
+++ b/Tests/RunCMake/ExportSbom/TargetInMultipleSets-install-check.cmake
@@ -1,2 +1,2 @@
-file(READ "${RunCMake_TEST_BINARY_DIR}/sbom/mySbom/mySbom.spdx.json" content)
+file(READ "${RunCMake_TEST_BINARY_DIR}/sbom/mySbom/mySbom-Debug.spdx.json" content)
 include(${CMAKE_CURRENT_LIST_DIR}/../Sbom/TargetInMultipleSets-install-check.cmake)
diff --git a/Tests/RunCMake/File_Archive/RunCMakeTest.cmake b/Tests/RunCMake/File_Archive/RunCMakeTest.cmake
index 63071cb..6b4da44 100644
--- a/Tests/RunCMake/File_Archive/RunCMakeTest.cmake
+++ b/Tests/RunCMake/File_Archive/RunCMakeTest.cmake
@@ -68,6 +68,10 @@
 # Extracting only selected files or directories
 run_cmake(zip-filtered)
 
+# Excluding selected files or directories from extraction
+run_cmake(zip-filtered-exclude)
+run_cmake(zip-filtered-exclude-precedence)
+
 run_cmake(create-missing-args)
 run_cmake(extract-missing-args)
 
diff --git a/Tests/RunCMake/File_Archive/zip-filtered-exclude-precedence.cmake b/Tests/RunCMake/File_Archive/zip-filtered-exclude-precedence.cmake
new file mode 100644
index 0000000..5930e77
--- /dev/null
+++ b/Tests/RunCMake/File_Archive/zip-filtered-exclude-precedence.cmake
@@ -0,0 +1,28 @@
+set(OUTPUT_NAME "test.zip")
+
+set(ARCHIVE_FORMAT zip)
+
+# Combine inclusion and exclusion patterns.  When an entry matches both,
+# the exclusion takes precedence.
+set(DECOMPRESSION_OPTIONS
+  PATTERNS
+    "compress_dir/d1/*"    # include contents of d1
+    "compress_dir/d_4/*"   # include contents of d_4 ...
+  PATTERNS_EXCLUDE
+    "d_4"                  # ... but exclude d_4: exclusion wins
+)
+
+# Only the included-and-not-excluded entry survives.
+set(CUSTOM_CHECK_FILES
+  "d1/f1.txt"
+)
+
+set(NOT_EXISTING_FILES_CHECK
+  "f1.txt"        # never included by PATTERNS
+  "d 2/f1.txt"    # never included by PATTERNS
+  "d_4/f1.txt"    # included by PATTERNS but excluded: exclusion wins
+)
+
+include(${CMAKE_CURRENT_LIST_DIR}/roundtrip.cmake)
+
+check_magic("504b0304" LIMIT 4 HEX)
diff --git a/Tests/RunCMake/File_Archive/zip-filtered-exclude.cmake b/Tests/RunCMake/File_Archive/zip-filtered-exclude.cmake
new file mode 100644
index 0000000..866236a
--- /dev/null
+++ b/Tests/RunCMake/File_Archive/zip-filtered-exclude.cmake
@@ -0,0 +1,30 @@
+set(OUTPUT_NAME "test.zip")
+
+set(ARCHIVE_FORMAT zip)
+
+# Extract the whole archive except entries matching PATTERNS_EXCLUDE.
+set(DECOMPRESSION_OPTIONS
+  PATTERNS_EXCLUDE
+    "compress_dir/d 2/*"   # exclude everything under a directory
+    "d-4"                  # exclude by unanchored name (dir + contents)
+    "no_such_entry"        # matches nothing: must not be an error
+)
+
+# Everything that was not excluded must still be extracted.
+set(CUSTOM_CHECK_FILES
+  "f1.txt"
+  "d1/f1.txt"
+  "d + 3/f1.txt"
+  "d_4/f1.txt"                   # underscore, not the excluded "d-4"
+  "My Special Directory/f1.txt"
+)
+
+# The excluded entries must not be extracted.
+set(NOT_EXISTING_FILES_CHECK
+  "d 2/f1.txt"
+  "d-4/f1.txt"
+)
+
+include(${CMAKE_CURRENT_LIST_DIR}/roundtrip.cmake)
+
+check_magic("504b0304" LIMIT 4 HEX)
diff --git a/Tests/RunCMake/InstallSbom/ApplicationTarget-install-check.cmake b/Tests/RunCMake/InstallSbom/ApplicationTarget-install-check.cmake
index 5e1e606..874a424 100644
--- a/Tests/RunCMake/InstallSbom/ApplicationTarget-install-check.cmake
+++ b/Tests/RunCMake/InstallSbom/ApplicationTarget-install-check.cmake
@@ -1,2 +1,2 @@
-file(READ "${RunCMake_TEST_INSTALL_DIR}/application_targets.spdx.json" content)
+file(READ "${RunCMake_TEST_INSTALL_DIR}/application_targets-Debug.spdx.json" content)
 include(${CMAKE_CURRENT_LIST_DIR}/../Sbom/ApplicationTarget-install-check.cmake)
diff --git a/Tests/RunCMake/InstallSbom/Config-check.cmake b/Tests/RunCMake/InstallSbom/Config-check.cmake
new file mode 100644
index 0000000..634960b
--- /dev/null
+++ b/Tests/RunCMake/InstallSbom/Config-check.cmake
@@ -0,0 +1,11 @@
+include(${CMAKE_CURRENT_LIST_DIR}/../Sbom/Assertions.cmake)
+
+get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
+if(_isMultiConfig)
+  file(READ "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/sbom/5058f1af8388633f609cadb75a75dc9d/foo-Debug.spdx.json" DebugSbom)
+  file(READ "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/sbom/5058f1af8388633f609cadb75a75dc9d/foo-Release.spdx.json" ReleaseSbom)
+else()
+  file(READ "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/sbom/5058f1af8388633f609cadb75a75dc9d/foo-Debug.spdx.json" DebugSbom)
+endif()
+
+include(${CMAKE_CURRENT_LIST_DIR}/../Sbom/Config-check.cmake)
diff --git a/Tests/RunCMake/InstallSbom/Config.cmake b/Tests/RunCMake/InstallSbom/Config.cmake
new file mode 100644
index 0000000..71f076a
--- /dev/null
+++ b/Tests/RunCMake/InstallSbom/Config.cmake
@@ -0,0 +1,6 @@
+include(${CMAKE_CURRENT_LIST_DIR}/../Sbom/Config.cmake)
+install(SBOM foo
+  EXPORTS foo
+  FORMAT "spdx-3.0+json"
+  DESTINATION .
+)
diff --git a/Tests/RunCMake/InstallSbom/DuplicateSbom-stderr.txt b/Tests/RunCMake/InstallSbom/DuplicateSbom-stderr.txt
index 97a197b..03fdab3 100644
--- a/Tests/RunCMake/InstallSbom/DuplicateSbom-stderr.txt
+++ b/Tests/RunCMake/InstallSbom/DuplicateSbom-stderr.txt
@@ -1,2 +1,2 @@
 CMake Error at DuplicateSbom\.cmake:[0-9]+ \(install\):
-  install SBOM command already specified for the file mySbom\.spdx\.json\.
+  install SBOM command already specified for the file mySbom.
diff --git a/Tests/RunCMake/InstallSbom/EmptyNamespaceFallback-install-check.cmake b/Tests/RunCMake/InstallSbom/EmptyNamespaceFallback-install-check.cmake
index 3f61b5b..6fe86b3 100644
--- a/Tests/RunCMake/InstallSbom/EmptyNamespaceFallback-install-check.cmake
+++ b/Tests/RunCMake/InstallSbom/EmptyNamespaceFallback-install-check.cmake
@@ -1,2 +1,2 @@
-file(READ "${RunCMake_TEST_INSTALL_DIR}/mySbom.spdx.json" content)
+file(READ "${RunCMake_TEST_INSTALL_DIR}/mySbom-Debug.spdx.json" content)
 include(${CMAKE_CURRENT_LIST_DIR}/../Sbom/EmptyNamespaceFallback-install-check.cmake)
diff --git a/Tests/RunCMake/InstallSbom/ForbiddenGenex-result.txt b/Tests/RunCMake/InstallSbom/ForbiddenGenex-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/InstallSbom/ForbiddenGenex-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/InstallSbom/ForbiddenGenex-stderr.txt b/Tests/RunCMake/InstallSbom/ForbiddenGenex-stderr.txt
new file mode 100644
index 0000000..d878e11
--- /dev/null
+++ b/Tests/RunCMake/InstallSbom/ForbiddenGenex-stderr.txt
@@ -0,0 +1,3 @@
+CMake Error in CMakeLists.txt:
+  Property "INTERFACE_LINK_LIBRARIES" of target "foo" contains a generator
+  expression that is not allowed for SBOM generation.
diff --git a/Tests/RunCMake/InstallSbom/ForbiddenGenex.cmake b/Tests/RunCMake/InstallSbom/ForbiddenGenex.cmake
new file mode 100644
index 0000000..536d43e
--- /dev/null
+++ b/Tests/RunCMake/InstallSbom/ForbiddenGenex.cmake
@@ -0,0 +1,6 @@
+include(${CMAKE_CURRENT_LIST_DIR}/../Sbom/ForbiddenGenex.cmake)
+install(SBOM foo
+  EXPORTS foo
+  FORMAT "spdx-3.0+json"
+  DESTINATION .
+)
diff --git a/Tests/RunCMake/InstallSbom/Genex-check.cmake b/Tests/RunCMake/InstallSbom/Genex-check.cmake
new file mode 100644
index 0000000..d03682b
--- /dev/null
+++ b/Tests/RunCMake/InstallSbom/Genex-check.cmake
@@ -0,0 +1,11 @@
+include(${CMAKE_CURRENT_LIST_DIR}/../Sbom/Assertions.cmake)
+
+get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
+if(_isMultiConfig)
+  file(READ "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/sbom/5058f1af8388633f609cadb75a75dc9d/foo-BarConfig.spdx.json" BarConfig)
+  file(READ "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/sbom/5058f1af8388633f609cadb75a75dc9d/foo-BazConfig.spdx.json" BazConfig)
+else()
+  file(READ "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/sbom/5058f1af8388633f609cadb75a75dc9d/foo-BarConfig.spdx.json" BarConfig)
+endif()
+
+include(${CMAKE_CURRENT_LIST_DIR}/../Sbom/Genex-check.cmake)
diff --git a/Tests/RunCMake/InstallSbom/Genex.cmake b/Tests/RunCMake/InstallSbom/Genex.cmake
new file mode 100644
index 0000000..e07deb9
--- /dev/null
+++ b/Tests/RunCMake/InstallSbom/Genex.cmake
@@ -0,0 +1,6 @@
+include(${CMAKE_CURRENT_LIST_DIR}/../Sbom/Genex.cmake)
+install(SBOM foo
+  EXPORTS foo
+  FORMAT "spdx-3.0+json"
+  DESTINATION .
+)
diff --git a/Tests/RunCMake/InstallSbom/InterfaceTarget-install-check.cmake b/Tests/RunCMake/InstallSbom/InterfaceTarget-install-check.cmake
index ef7f389..a181d84 100644
--- a/Tests/RunCMake/InstallSbom/InterfaceTarget-install-check.cmake
+++ b/Tests/RunCMake/InstallSbom/InterfaceTarget-install-check.cmake
@@ -1,2 +1,2 @@
-file(READ "${RunCMake_TEST_INSTALL_DIR}/interface_targets.spdx.json" content)
+file(READ "${RunCMake_TEST_INSTALL_DIR}/interface_targets-Debug.spdx.json" content)
 include(${CMAKE_CURRENT_LIST_DIR}/../Sbom/InterfaceTarget-install-check.cmake)
diff --git a/Tests/RunCMake/InstallSbom/MissingPackageNamespace-install-check.cmake b/Tests/RunCMake/InstallSbom/MissingPackageNamespace-install-check.cmake
index fe16bd8..3888828 100644
--- a/Tests/RunCMake/InstallSbom/MissingPackageNamespace-install-check.cmake
+++ b/Tests/RunCMake/InstallSbom/MissingPackageNamespace-install-check.cmake
@@ -1,2 +1,2 @@
-file(READ "${RunCMake_TEST_INSTALL_DIR}/test_targets.spdx.json" content)
+file(READ "${RunCMake_TEST_INSTALL_DIR}/test_targets-Debug.spdx.json" content)
 include(${CMAKE_CURRENT_LIST_DIR}/../Sbom/MissingPackageNamespace-install-check.cmake)
diff --git a/Tests/RunCMake/InstallSbom/MultiSetSingleSbom-install-check.cmake b/Tests/RunCMake/InstallSbom/MultiSetSingleSbom-install-check.cmake
index e1e8aa1..47cf3ca 100644
--- a/Tests/RunCMake/InstallSbom/MultiSetSingleSbom-install-check.cmake
+++ b/Tests/RunCMake/InstallSbom/MultiSetSingleSbom-install-check.cmake
@@ -1,2 +1,2 @@
-file(READ "${RunCMake_TEST_INSTALL_DIR}/mySbom.spdx.json" content)
+file(READ "${RunCMake_TEST_INSTALL_DIR}/mySbom-Debug.spdx.json" content)
 include(${CMAKE_CURRENT_LIST_DIR}/../Sbom/MultiSetSingleSbom-install-check.cmake)
diff --git a/Tests/RunCMake/InstallSbom/ProjectMetadata-install-check.cmake b/Tests/RunCMake/InstallSbom/ProjectMetadata-install-check.cmake
index 75adf4e..7308b84 100644
--- a/Tests/RunCMake/InstallSbom/ProjectMetadata-install-check.cmake
+++ b/Tests/RunCMake/InstallSbom/ProjectMetadata-install-check.cmake
@@ -1,3 +1,3 @@
-file(READ "${RunCMake_TEST_INSTALL_DIR}/test_targets.spdx.json" content)
+file(READ "${RunCMake_TEST_INSTALL_DIR}/test_targets-Debug.spdx.json" content)
 include(${CMAKE_CURRENT_LIST_DIR}/../Sbom/ProjectMetadata-install-check.cmake)
 include(${CMAKE_CURRENT_LIST_DIR}/../Sbom/ProjectMetadataExplicitAssertions.cmake)
diff --git a/Tests/RunCMake/InstallSbom/Requirements-install-check.cmake b/Tests/RunCMake/InstallSbom/Requirements-install-check.cmake
index 1c2f057..09f9a2a 100644
--- a/Tests/RunCMake/InstallSbom/Requirements-install-check.cmake
+++ b/Tests/RunCMake/InstallSbom/Requirements-install-check.cmake
@@ -1,3 +1,3 @@
-file(READ "${RunCMake_TEST_INSTALL_DIR}/bar_sbom.spdx.json" BAR_CONTENT)
-file(READ "${RunCMake_TEST_INSTALL_DIR}/foo_sbom.spdx.json" FOO_CONTENT)
+file(READ "${RunCMake_TEST_INSTALL_DIR}/bar_sbom-Debug.spdx.json" BAR_CONTENT)
+file(READ "${RunCMake_TEST_INSTALL_DIR}/foo_sbom-Debug.spdx.json" FOO_CONTENT)
 include(${CMAKE_CURRENT_LIST_DIR}/../Sbom/Requirements-install-check.cmake)
diff --git a/Tests/RunCMake/InstallSbom/RunCMakeTest.cmake b/Tests/RunCMake/InstallSbom/RunCMakeTest.cmake
index fcf9986..fd567a8 100644
--- a/Tests/RunCMake/InstallSbom/RunCMakeTest.cmake
+++ b/Tests/RunCMake/InstallSbom/RunCMakeTest.cmake
@@ -9,7 +9,7 @@
   set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${test}-build)
   set(RunCMake_TEST_OPTIONS ${common_test_options})
   if(NOT RunCMake_GENERATOR_IS_MULTI_CONFIG)
-    list(APPEND RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=DEBUG)
+    list(APPEND RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Debug)
   endif()
   run_cmake(${test})
 endfunction()
@@ -21,7 +21,7 @@
   set(RunCMake_TEST_OPTIONS ${common_test_options} ${extra_options})
   list(APPEND RunCMake_TEST_OPTIONS -DCMAKE_INSTALL_PREFIX=${RunCMake_TEST_INSTALL_DIR})
   if(NOT RunCMake_GENERATOR_IS_MULTI_CONFIG)
-    list(APPEND RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=DEBUG)
+    list(APPEND RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Debug)
   endif()
 
   run_cmake(${test})
@@ -32,13 +32,16 @@
   run_cmake_command(${test}-install ${CMAKE_COMMAND} --install . --config Debug)
 endfunction()
 
+function(run_cmake_configure test)
+  set(extra_options ${ARGN})
+  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${test}-build)
+  set(RunCMake_TEST_OPTIONS ${common_test_options} ${extra_options})
+  run_cmake(${test})
+endfunction()
+
 run_cmake_install(ApplicationTarget)
 run_cmake_install(InstallExportPlusSbomSameSet)
 run_cmake_install(InterfaceTarget)
-run_cmake_install(SharedTarget)
-run_cmake_install(Requirements)
-run_cmake_install(SbomNamespaceFallback)
-run_cmake_install(MultiSetSingleSbom)
 run_cmake_install(TargetInMultipleSets)
 run_cmake_install(EmptyNamespaceFallback -Wauthor)
 run_cmake_install(SbomNamespaceAmbiguity -Wauthor)
@@ -51,3 +54,7 @@
 run_cmake_error(MultiNamespaceAmbiguity)
 run_cmake_error(MultiSetAmbiguity)
 run_cmake_error(DuplicateSbom)
+
+run_cmake_configure(Config)
+run_cmake_configure(Genex)
+run_cmake_configure(ForbiddenGenex)
diff --git a/Tests/RunCMake/InstallSbom/SbomNamespaceAmbiguity-install-check.cmake b/Tests/RunCMake/InstallSbom/SbomNamespaceAmbiguity-install-check.cmake
index c35bcc0..580a84e 100644
--- a/Tests/RunCMake/InstallSbom/SbomNamespaceAmbiguity-install-check.cmake
+++ b/Tests/RunCMake/InstallSbom/SbomNamespaceAmbiguity-install-check.cmake
@@ -1,2 +1,2 @@
-file(READ "${RunCMake_TEST_INSTALL_DIR}/bar_sbom.spdx.json" BAR_CONTENT)
+file(READ "${RunCMake_TEST_INSTALL_DIR}/bar_sbom-Debug.spdx.json" BAR_CONTENT)
 include(${CMAKE_CURRENT_LIST_DIR}/../Sbom/SbomNamespaceAmbiguity-install-check.cmake)
diff --git a/Tests/RunCMake/InstallSbom/SbomNamespaceFallback-install-check.cmake b/Tests/RunCMake/InstallSbom/SbomNamespaceFallback-install-check.cmake
index dbbec2d..ee60380 100644
--- a/Tests/RunCMake/InstallSbom/SbomNamespaceFallback-install-check.cmake
+++ b/Tests/RunCMake/InstallSbom/SbomNamespaceFallback-install-check.cmake
@@ -1,3 +1,3 @@
-file(READ "${RunCMake_TEST_INSTALL_DIR}/bar.spdx.json" BAR_CONTENT)
-file(READ "${RunCMake_TEST_INSTALL_DIR}/foo.spdx.json" FOO_CONTENT)
+file(READ "${RunCMake_TEST_INSTALL_DIR}/bar-Debug.spdx.json" BAR_CONTENT)
+file(READ "${RunCMake_TEST_INSTALL_DIR}/foo-Debug.spdx.json" FOO_CONTENT)
 include(${CMAKE_CURRENT_LIST_DIR}/../Sbom/SbomNamespaceFallback-install-check.cmake)
diff --git a/Tests/RunCMake/InstallSbom/SharedTarget-install-check.cmake b/Tests/RunCMake/InstallSbom/SharedTarget-install-check.cmake
index 27fa653..e778cba 100644
--- a/Tests/RunCMake/InstallSbom/SharedTarget-install-check.cmake
+++ b/Tests/RunCMake/InstallSbom/SharedTarget-install-check.cmake
@@ -1,2 +1,2 @@
-file(READ "${RunCMake_TEST_INSTALL_DIR}/shared_targets.spdx.json" content)
+file(READ "${RunCMake_TEST_INSTALL_DIR}/shared_targets-Debug.spdx.json" content)
 include(${CMAKE_CURRENT_LIST_DIR}/../Sbom/SharedTarget-install-check.cmake)
diff --git a/Tests/RunCMake/InstallSbom/TargetInMultipleSets-install-check.cmake b/Tests/RunCMake/InstallSbom/TargetInMultipleSets-install-check.cmake
index 1d04796..063c386 100644
--- a/Tests/RunCMake/InstallSbom/TargetInMultipleSets-install-check.cmake
+++ b/Tests/RunCMake/InstallSbom/TargetInMultipleSets-install-check.cmake
@@ -1,2 +1,2 @@
-file(READ "${RunCMake_TEST_INSTALL_DIR}/mySbom.spdx.json" content)
+file(READ "${RunCMake_TEST_INSTALL_DIR}/mySbom-Debug.spdx.json" content)
 include(${CMAKE_CURRENT_LIST_DIR}/../Sbom/TargetInMultipleSets-install-check.cmake)
diff --git a/Tests/RunCMake/Sbom/Config-check.cmake b/Tests/RunCMake/Sbom/Config-check.cmake
new file mode 100644
index 0000000..f347ff0
--- /dev/null
+++ b/Tests/RunCMake/Sbom/Config-check.cmake
@@ -0,0 +1,15 @@
+include(${CMAKE_CURRENT_LIST_DIR}/Assertions.cmake)
+
+function(check_config VAR_NAME1)
+  if(NOT "${${VAR_NAME1}}" STREQUAL "")
+    set(RunCMake_TEST_FAILED "${ERROR_MSG}" PARENT_SCOPE)
+  endif()
+endfunction()
+
+get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
+if(_isMultiConfig)
+  check_config(DebugSbom)
+  check_config(ReleaseSbom)
+else()
+  check_config(DebugSbom)
+endif()
diff --git a/Tests/RunCMake/Sbom/Config.cmake b/Tests/RunCMake/Sbom/Config.cmake
new file mode 100644
index 0000000..06799d2
--- /dev/null
+++ b/Tests/RunCMake/Sbom/Config.cmake
@@ -0,0 +1,12 @@
+get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
+if(_isMultiConfig)
+  set(CMAKE_CONFIGURATION_TYPES "Debug;Release" CACHE STRING "" FORCE)
+else()
+  if(NOT CMAKE_BUILD_TYPE)
+    set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "" FORCE)
+  endif()
+endif()
+
+project(Config C)
+add_library(foo ${CMAKE_CURRENT_LIST_DIR}/test.c)
+install(TARGETS foo EXPORT foo DESTINATION .)
diff --git a/Tests/RunCMake/Sbom/Empty-install-check.cmake b/Tests/RunCMake/Sbom/Empty-install-check.cmake
new file mode 100644
index 0000000..ffabf80
--- /dev/null
+++ b/Tests/RunCMake/Sbom/Empty-install-check.cmake
@@ -0,0 +1,7 @@
+include(${CMAKE_CURRENT_LIST_DIR}/Assertions.cmake)
+
+set(out_dir "${RunCMake_BINARY_DIR}/EmptyConfig-build")
+
+file(READ "${out_dir}/foo.cps" content)
+
+expect_object("${content}" "components" "foo" "configurations" "noconfig")
diff --git a/Tests/RunCMake/Sbom/Empty.cmake b/Tests/RunCMake/Sbom/Empty.cmake
new file mode 100644
index 0000000..ef1923b
--- /dev/null
+++ b/Tests/RunCMake/Sbom/Empty.cmake
@@ -0,0 +1,9 @@
+project(EmptyConfig CXX)
+
+set(CMAKE_BUILD_TYPE "" CACHE STRING "" FORCE)
+set(CMAKE_CONFIGURATION_TYPES "" CACHE STRING "" FORCE)
+
+add_library(foo foo.cxx)
+
+install(TARGETS foo EXPORT foo)
+install(SBOM foo EXPORT foo)
diff --git a/Tests/RunCMake/Sbom/ForbiddenGenex.cmake b/Tests/RunCMake/Sbom/ForbiddenGenex.cmake
new file mode 100644
index 0000000..bdddfb8
--- /dev/null
+++ b/Tests/RunCMake/Sbom/ForbiddenGenex.cmake
@@ -0,0 +1,14 @@
+project(ForbiddenGenex C)
+
+add_library(foo ${CMAKE_CURRENT_LIST_DIR}/test.c)
+
+find_package(
+  bar 1.3.4 REQUIRED
+  NO_DEFAULT_PATH
+  PATHS ${CMAKE_CURRENT_LIST_DIR}
+)
+
+target_link_libraries(foo INTERFACE
+  $<TARGET_PROPERTY:foo>
+)
+install(TARGETS foo EXPORT foo DESTINATION .)
diff --git a/Tests/RunCMake/Sbom/Genex-check.cmake b/Tests/RunCMake/Sbom/Genex-check.cmake
new file mode 100644
index 0000000..4e584ce
--- /dev/null
+++ b/Tests/RunCMake/Sbom/Genex-check.cmake
@@ -0,0 +1,111 @@
+include(${CMAKE_CURRENT_LIST_DIR}/Assertions.cmake)
+
+set(CREATION_INFO_EXPECTED [=[
+{
+  "@id": "_:Build#CreationInfo",
+  "comment": "This SBOM was generated from the CMakeLists.txt File",
+  "createdBy":
+  [
+    "https://gitlab.kitware.com/cmake/cmake"
+  ],
+  "specVersion": "3.0.1",
+  "type": "CreationInfo"
+}
+]=])
+
+set(SPDX_DOCUMENT_EXPECTED [=[
+{
+  "spdxId" : "urn:interface_targets#SPDXDocument",
+  "name": "interface_targets",
+  "profileConformance" :
+  [
+    "core",
+    "software"
+  ],
+  "creationInfo" : "_:Build#CreationInfo",
+  "type" : "SpdxDocument"
+}
+]=])
+
+set(APPLICATION_EXPECTED [=[
+{
+  "spdxId" : "urn:interface#Package",
+  "name" : "interface",
+  "software_primaryPurpose" : "library",
+  "type" : "software_Package"
+}
+]=])
+
+set(DEPENDENCY_EXPECTED [=[
+{
+  "spdxId" : "urn:bar:bar#Package",
+  "name" : "bar:bar",
+  "originatedBy" :
+  [
+    {
+      "name" : "bar",
+      "type" : "Organization"
+    }
+  ],
+  "software_packageVersion" : "1.3.5",
+  "type" : "software_Package"
+}
+]=])
+
+set(BAR_LINKED_LIBRARIES_EXPECTED [=[
+{
+  "creationInfo" : "_:Build#CreationInfo",
+  "description" : "Linked Libraries",
+  "from" : "urn:interface#Package",
+  "relationshipType" : "dependsOn",
+  "spdxId" : "urn:Static#Relationship",
+  "to" :
+  [
+    "urn:bar:bar#Package"
+  ],
+  "type" : "Relationship"
+}
+]=])
+
+set(BAZ_LINKED_LIBRARIES_EXPECTED [=[
+{
+  "creationInfo" : "_:Build#CreationInfo",
+  "description" : "Required Build-Time Libraries",
+  "from" : "urn:foo#Package",
+  "relationshipType" : "dependsOn",
+  "spdxId" : "urn:Shared#Relationship",
+  "to" :
+  [
+    "urn:baz#Package"
+  ],
+  "type" : "Relationship"
+}
+]=])
+
+
+function(check_config VAR_NAME LIBS)
+  set(content "${${VAR_NAME}}")
+  if("${content}" STREQUAL "")
+    set(RunCMake_TEST_FAILED "Error: Variable '${VAR_NAME}' is empty or not defined." PARENT_SCOPE)
+    return()
+  endif()
+
+  expect_value("${VAR_NAME}" "https://spdx.org/rdf/3.0.1/spdx-context.jsonld" "@context")
+  string(JSON CREATION_INFO GET "${content}" "@graph" "0")
+  expect_object("${CREATION_INFO}" CREATION_INFO_EXPECTED)
+
+  string(JSON SPDX_DOCUMENT GET "${content}" "@graph" "1")
+  expect_object("${SPDX_DOCUMENT}" SPDX_DOCUMENT_EXPECTED)
+  expect_object("${SPDX_DOCUMENT}" APPLICATION_EXPECTED "rootElement")
+  expect_object("${SPDX_DOCUMENT}" DEPENDENCY_EXPECTED "element")
+  string(JSON LINKED_LIBRARIES GET "${content}" "@graph" "2")
+  expect_object("${LINKED_LIBRARIES}" ${LIBS})
+endfunction()
+
+get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
+if(_isMultiConfig)
+  check_config(BarConfig BAR_LINKED_LIBRARIES_EXPECTED)
+  check_config(BazConfig BAZ_LINKED_LIBRARIES_EXPECTED)
+else()
+  check_config(BarConfig BAR_LINKED_LIBRARIES_EXPECTED)
+endif()
diff --git a/Tests/RunCMake/Sbom/Genex.cmake b/Tests/RunCMake/Sbom/Genex.cmake
new file mode 100644
index 0000000..baf5251
--- /dev/null
+++ b/Tests/RunCMake/Sbom/Genex.cmake
@@ -0,0 +1,28 @@
+get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
+if(_isMultiConfig)
+  set(CMAKE_CONFIGURATION_TYPES "BarConfig;BazConfig" CACHE STRING "" FORCE)
+else()
+  if(NOT CMAKE_BUILD_TYPE)
+    set(CMAKE_BUILD_TYPE "BarConfig" CACHE STRING "" FORCE)
+  endif()
+endif()
+
+project(Genex C)
+add_library(foo INTERFACE)
+
+find_package(
+  bar 1.3.4 REQUIRED
+  NO_DEFAULT_PATH
+  PATHS ${CMAKE_CURRENT_LIST_DIR}
+)
+
+find_package(
+  baz 1.3.4 REQUIRED
+  NO_DEFAULT_PATH
+  PATHS ${CMAKE_CURRENT_LIST_DIR}
+)
+
+target_link_libraries(foo INTERFACE $<$<CONFIG:BarConfig>:bar::bar>)
+target_link_libraries(foo INTERFACE $<$<CONFIG:BazConfig>:baz>)
+
+install(TARGETS foo EXPORT foo)
diff --git a/Tests/RunCMake/Swift/CMP0157-OLD-stderr.txt b/Tests/RunCMake/Swift/CMP0157-OLD-stderr.txt
new file mode 100644
index 0000000..2a4c473
--- /dev/null
+++ b/Tests/RunCMake/Swift/CMP0157-OLD-stderr.txt
@@ -0,0 +1,12 @@
+^CMake Warning \(deprecated\) at CMP0157-OLD\.cmake:[0-9]+ \(cmake_policy\):
+  The OLD behavior for policy CMP0157 will be removed from a future version
+  of CMake\.
+
+  The cmake-policies\(7\) manual explains that the OLD behaviors of all
+  policies are deprecated and that a policy should be set to OLD only under
+  specific short-term circumstances\.  Projects should be ported to the NEW
+  behavior and not rely on setting a policy to OLD\.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
+This warning is for project developers\.  Use -Wno-author or -Wno-deprecated
+to suppress it\.
diff --git a/Tests/RunCMake/Swift/CMP0214-NEW-CMP0157-OLD-stderr.txt b/Tests/RunCMake/Swift/CMP0214-NEW-CMP0157-OLD-stderr.txt
new file mode 100644
index 0000000..c027815
--- /dev/null
+++ b/Tests/RunCMake/Swift/CMP0214-NEW-CMP0157-OLD-stderr.txt
@@ -0,0 +1,12 @@
+^CMake Warning \(deprecated\) at CMP0214-NEW-CMP0157-OLD\.cmake:[0-9]+ \(cmake_policy\):
+  The OLD behavior for policy CMP0157 will be removed from a future version
+  of CMake\.
+
+  The cmake-policies\(7\) manual explains that the OLD behaviors of all
+  policies are deprecated and that a policy should be set to OLD only under
+  specific short-term circumstances\.  Projects should be ported to the NEW
+  behavior and not rely on setting a policy to OLD\.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
+This warning is for project developers\.  Use -Wno-author or -Wno-deprecated
+to suppress it\.
diff --git a/Tests/RunCMake/file-STRINGS/CMP0159-OLD-stderr.txt b/Tests/RunCMake/file-STRINGS/CMP0159-OLD-stderr.txt
new file mode 100644
index 0000000..2bf9f37
--- /dev/null
+++ b/Tests/RunCMake/file-STRINGS/CMP0159-OLD-stderr.txt
@@ -0,0 +1,12 @@
+^CMake Warning \(deprecated\) at CMP0159-OLD\.cmake:[0-9]+ \(cmake_policy\):
+  The OLD behavior for policy CMP0159 will be removed from a future version
+  of CMake\.
+
+  The cmake-policies\(7\) manual explains that the OLD behaviors of all
+  policies are deprecated and that a policy should be set to OLD only under
+  specific short-term circumstances\.  Projects should be ported to the NEW
+  behavior and not rely on setting a policy to OLD\.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
+This warning is for project developers\.  Use -Wno-author or -Wno-deprecated
+to suppress it\.
diff --git a/Utilities/Doxygen/CMakeLists.txt b/Utilities/Doxygen/CMakeLists.txt
index 0d29b1c..e53435d 100644
--- a/Utilities/Doxygen/CMakeLists.txt
+++ b/Utilities/Doxygen/CMakeLists.txt
@@ -3,7 +3,7 @@
 
 if(NOT CMake_SOURCE_DIR)
   set(CMakeDeveloperReference_STANDALONE 1)
-  cmake_minimum_required(VERSION 3.13...4.2 FATAL_ERROR)
+  cmake_minimum_required(VERSION 3.13...4.3 FATAL_ERROR)
   get_filename_component(tmp "${CMAKE_CURRENT_SOURCE_DIR}" PATH)
   get_filename_component(CMake_SOURCE_DIR "${tmp}" PATH)
   include(${CMake_SOURCE_DIR}/Modules/CTestUseLaunchers.cmake)
diff --git a/Utilities/Sphinx/CMakeLists.txt b/Utilities/Sphinx/CMakeLists.txt
index ffb46e9..ee6becd 100644
--- a/Utilities/Sphinx/CMakeLists.txt
+++ b/Utilities/Sphinx/CMakeLists.txt
@@ -3,7 +3,7 @@
 
 if(NOT CMake_SOURCE_DIR)
   set(CMakeHelp_STANDALONE 1)
-  cmake_minimum_required(VERSION 3.13...4.2 FATAL_ERROR)
+  cmake_minimum_required(VERSION 3.13...4.3 FATAL_ERROR)
   get_filename_component(tmp "${CMAKE_CURRENT_SOURCE_DIR}" PATH)
   get_filename_component(CMake_SOURCE_DIR "${tmp}" PATH)
   include(${CMake_SOURCE_DIR}/Modules/CTestUseLaunchers.cmake)