Merge topic 'find_package-one-more-path'

19366408fe cmFindPackageCommand: Protect overrides of `cmDirectoryListGenerator`
e55c154c5b cmFindPackageCommand: Add one more search path

Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !7542
diff --git a/CompileFlags.cmake b/CompileFlags.cmake
index 5641de4..47c8352 100644
--- a/CompileFlags.cmake
+++ b/CompileFlags.cmake
@@ -23,7 +23,7 @@
 endif()
 
 if(MSVC)
-  set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -stack:10000000")
+  set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${CMAKE_CXX_LINKER_WRAPPER_FLAG}-stack:10000000")
 endif()
 
 # MSVC 14.28 enables C5105, but the Windows SDK 10.0.18362.0 triggers it.
diff --git a/Help/command/FIND_XXX.txt b/Help/command/FIND_XXX.txt
index e5e7496..aa06d49 100644
--- a/Help/command/FIND_XXX.txt
+++ b/Help/command/FIND_XXX.txt
@@ -187,9 +187,9 @@
    * |SYSTEM_ENVIRONMENT_PATH_WINDOWS_XXX|
 
 6. Search cmake variables defined in the Platform files
-   for the current system.  The searching of ``CMAKE_INSTALL_PREFIX` can be
+   for the current system.  The searching of ``CMAKE_INSTALL_PREFIX`` can be
    skipped if ``NO_CMAKE_INSTALL_PREFIX`` is passed or by setting the
-   :variable:`CMAKE_FIND_USE_INSTALL_PREFIX` to ``FALSE. All these locations
+   :variable:`CMAKE_FIND_USE_INSTALL_PREFIX` to ``FALSE``. All these locations
    can be skipped if ``NO_CMAKE_SYSTEM_PATH`` is passed or by setting the
    :variable:`CMAKE_FIND_USE_CMAKE_SYSTEM_PATH` to ``FALSE``.
 
diff --git a/Help/cpack_gen/nuget.rst b/Help/cpack_gen/nuget.rst
index c980dd6..3bc73aa 100644
--- a/Help/cpack_gen/nuget.rst
+++ b/Help/cpack_gen/nuget.rst
@@ -162,6 +162,14 @@
  * Mandatory : NO
  * Default   : -
 
+.. variable:: CPACK_NUGET_PACKAGE_REQUIRE_LICENSE_ACCEPTANCE
+
+ When set to a true value, the user will be prompted to accept the license
+ before installing the package.
+
+ * Mandatory : NO
+ * Default   : -
+
 .. variable:: CPACK_NUGET_PACKAGE_ICON
               CPACK_NUGET_<compName>_PACKAGE_ICON
 
diff --git a/Help/variable/CMAKE_VERIFY_INTERFACE_HEADER_SETS.rst b/Help/variable/CMAKE_VERIFY_INTERFACE_HEADER_SETS.rst
index 6f14e6f..3fb8817 100644
--- a/Help/variable/CMAKE_VERIFY_INTERFACE_HEADER_SETS.rst
+++ b/Help/variable/CMAKE_VERIFY_INTERFACE_HEADER_SETS.rst
@@ -7,11 +7,33 @@
 :prop_tgt:`VERIFY_INTERFACE_HEADER_SETS` property of targets when they are
 created.  Setting it to true enables header set verification.
 
-Projects should not set this variable, it is intended as a developer
+Projects should not normally set this variable, it is intended as a developer
 control to be set on the :manual:`cmake(1)` command line or other
 equivalent methods.  The developer must have the ability to enable or
 disable header set verification according to the capabilities of their own
 machine and compiler.
 
+Verification of a dependency's header sets is not typically of interest
+to developers.  Therefore, :command:`FetchContent_MakeAvailable` explicitly
+sets ``CMAKE_VERIFY_INTERFACE_HEADER_SETS`` to false for the duration of its
+call, but restores its original value before returning.  If a project brings
+a dependency directly into the main build (e.g. calling
+:command:`add_subdirectory` on a vendored project from a git submodule), it
+should also do likewise.  For example:
+
+.. code:: cmake
+
+  # Save original setting so we can restore it later
+  set(want_header_set_verification ${CMAKE_VERIFY_INTERFACE_HEADER_SETS})
+
+  # Include the vendored dependency with header set verification disabled
+  set(CMAKE_VERIFY_INTERFACE_HEADER_SETS OFF)
+  add_subdirectory(...)   # Vendored sources, e.g. from git submodules
+
+  # Add the project's own sources. Restore the developer's original choice
+  # for whether to enable header set verification.
+  set(CMAKE_VERIFY_INTERFACE_HEADER_SETS ${want_header_set_verification})
+  add_subdirectory(src)
+
 By default, this variable is not set, which will result in header set
 verification being disabled.
diff --git a/Modules/Compiler/IntelLLVM-FindBinUtils.cmake b/Modules/Compiler/IntelLLVM-FindBinUtils.cmake
new file mode 100644
index 0000000..c5b1ee6
--- /dev/null
+++ b/Modules/Compiler/IntelLLVM-FindBinUtils.cmake
@@ -0,0 +1,45 @@
+if(NOT DEFINED _CMAKE_PROCESSING_LANGUAGE OR _CMAKE_PROCESSING_LANGUAGE STREQUAL "")
+  message(FATAL_ERROR "Internal error: _CMAKE_PROCESSING_LANGUAGE is not set")
+endif()
+
+# Ubuntu:
+# * /usr/bin/llvm-ar-9
+# * /usr/bin/llvm-ranlib-9
+string(REGEX MATCH "^([0-9]+)" __version_x
+    "${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_VERSION}")
+
+# Debian:
+# * /usr/bin/llvm-ar-4.0
+# * /usr/bin/llvm-ranlib-4.0
+string(REGEX MATCH "^([0-9]+\\.[0-9]+)" __version_x_y
+    "${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_VERSION}")
+
+# Try to find tools in the IntelLLVM Clang tools directory
+get_filename_component(__intel_llvm_hint_1 "${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER}" DIRECTORY)
+get_filename_component(__intel_llvm_hint_1 "${__intel_llvm_hint_1}/../bin-llvm" REALPATH)
+
+get_filename_component(__intel_llvm_hint_2 "${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER}" DIRECTORY)
+
+set(__intel_llvm_hints ${__intel_llvm_hint_1} ${__intel_llvm_hint_2})
+
+# http://manpages.ubuntu.com/manpages/precise/en/man1/llvm-ar.1.html
+find_program(CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_AR NAMES
+    "${_CMAKE_TOOLCHAIN_PREFIX}llvm-ar-${__version_x_y}"
+    "${_CMAKE_TOOLCHAIN_PREFIX}llvm-ar-${__version_x}"
+    "${_CMAKE_TOOLCHAIN_PREFIX}llvm-ar"
+    HINTS ${__intel_llvm_hints}
+    NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH
+    DOC "LLVM archiver"
+)
+mark_as_advanced(CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_AR)
+
+# http://manpages.ubuntu.com/manpages/precise/en/man1/llvm-ranlib.1.html
+find_program(CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_RANLIB NAMES
+    "${_CMAKE_TOOLCHAIN_PREFIX}llvm-ranlib-${__version_x_y}"
+    "${_CMAKE_TOOLCHAIN_PREFIX}llvm-ranlib-${__version_x}"
+    "${_CMAKE_TOOLCHAIN_PREFIX}llvm-ranlib"
+    HINTS ${__intel_llvm_hints}
+    NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH
+    DOC "Generate index for LLVM archive"
+)
+mark_as_advanced(CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_RANLIB)
diff --git a/Modules/Compiler/IntelLLVM.cmake b/Modules/Compiler/IntelLLVM.cmake
index c344f32..3f22efd 100644
--- a/Modules/Compiler/IntelLLVM.cmake
+++ b/Modules/Compiler/IntelLLVM.cmake
@@ -15,6 +15,15 @@
 set(__pch_header_OBJC "objective-c-header")
 set(__pch_header_OBJCXX "objective-c++-header")
 
+# Variables that are common across front-end variants
+macro(__compiler_intel_llvm_common lang)
+  set(_CMAKE_${lang}_IPO_SUPPORTED_BY_CMAKE YES)
+  set(_CMAKE_${lang}_IPO_MAY_BE_SUPPORTED_BY_COMPILER YES)
+  set(CMAKE_${lang}_ARCHIVE_CREATE_IPO "\"${CMAKE_${lang}_COMPILER_AR}\" cr <TARGET> <LINK_FLAGS> <OBJECTS>")
+  set(CMAKE_${lang}_ARCHIVE_APPEND_IPO "\"${CMAKE_${lang}_COMPILER_AR}\" r <TARGET> <LINK_FLAGS> <OBJECTS>")
+  set(CMAKE_${lang}_ARCHIVE_FINISH_IPO "\"${CMAKE_${lang}_COMPILER_RANLIB}\" <TARGET>")
+endmacro()
+
 if(CMAKE_HOST_WIN32)
   # MSVC-like
   macro(__compiler_intel_llvm lang)
@@ -22,6 +31,9 @@
       set(CMAKE_${lang}_COMPILE_OPTIONS_INVALID_PCH -Winvalid-pch)
       set(CMAKE_${lang}_COMPILE_OPTIONS_WARNING_AS_ERROR "-WX")
     endif()
+    __compiler_intel_llvm_common(${lang})
+    set(CMAKE_${lang}_COMPILE_OPTIONS_IPO "-Qipo")
+    set(CMAKE_${lang}_LINK_OPTIONS_IPO "-Qipo")
   endmacro()
 else()
   # GNU-like
@@ -60,12 +72,9 @@
     set(CMAKE_${lang}_LINKER_WRAPPER_FLAG "-Xlinker" " ")
     set(CMAKE_${lang}_LINKER_WRAPPER_FLAG_SEP)
 
-    set(_CMAKE_${lang}_IPO_SUPPORTED_BY_CMAKE YES)
-    set(_CMAKE_${lang}_IPO_MAY_BE_SUPPORTED_BY_COMPILER YES)
-    set(CMAKE_${lang}_COMPILE_OPTIONS_IPO "-flto=thin")
-    set(CMAKE_${lang}_ARCHIVE_CREATE_IPO "\"${CMAKE_${lang}_COMPILER_AR}\" cr <TARGET> <LINK_FLAGS> <OBJECTS>")
-    set(CMAKE_${lang}_ARCHIVE_APPEND_IPO "\"${CMAKE_${lang}_COMPILER_AR}\" r <TARGET> <LINK_FLAGS> <OBJECTS>")
-    set(CMAKE_${lang}_ARCHIVE_FINISH_IPO "\"${CMAKE_${lang}_COMPILER_RANLIB}\" <TARGET>")
+    __compiler_intel_llvm_common(${lang})
+    set(CMAKE_${lang}_COMPILE_OPTIONS_IPO "-ipo")
+    set(CMAKE_${lang}_LINK_OPTIONS_IPO "-ipo")
 
     set(CMAKE_${lang}_CREATE_PREPROCESSED_SOURCE "<CMAKE_${lang}_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
     set(CMAKE_${lang}_CREATE_ASSEMBLY_SOURCE "<CMAKE_${lang}_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
diff --git a/Modules/FetchContent.cmake b/Modules/FetchContent.cmake
index 27070c0..d016fb5 100644
--- a/Modules/FetchContent.cmake
+++ b/Modules/FetchContent.cmake
@@ -364,6 +364,18 @@
     FetchContent_Declare(other ...)
     FetchContent_MakeAvailable(uses_other other)
 
+  Note that :variable:`CMAKE_VERIFY_INTERFACE_HEADER_SETS` is explicitly set
+  to false upon entry to ``FetchContent_MakeAvailable()``, and is restored to
+  its original value before the command returns.  Developers typically only
+  want to verify header sets from the main project, not those from any
+  dependencies.  This local manipulation of the
+  :variable:`CMAKE_VERIFY_INTERFACE_HEADER_SETS` variable provides that
+  intuitive behavior.  You can use variables like
+  :variable:`CMAKE_PROJECT_INCLUDE` or
+  :variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE` to turn verification back
+  on for all or some dependencies.  You can also set the
+  :prop_tgt:`VERIFY_INTERFACE_HEADER_SETS` property of individual targets.
+
 .. command:: FetchContent_Populate
 
   .. note::
@@ -1814,6 +1826,13 @@
 # calls will be available to the caller.
 macro(FetchContent_MakeAvailable)
 
+  # We must append an item, even if the variable is unset, so prefix its value.
+  # We will strip that prefix when we pop the value at the end of the macro.
+  list(APPEND __cmake_fcCurrentVarsStack
+    "__fcprefix__${CMAKE_VERIFY_INTERFACE_HEADER_SETS}"
+  )
+  set(CMAKE_VERIFY_INTERFACE_HEADER_SETS FALSE)
+
   get_property(__cmake_providerCommand GLOBAL PROPERTY
     __FETCHCONTENT_MAKEAVAILABLE_SERIAL_PROVIDER
   )
@@ -1965,10 +1984,18 @@
     endif()
   endforeach()
 
+  # Prefix will be "__fcprefix__"
+  list(POP_BACK __cmake_fcCurrentVarsStack __cmake_original_verify_setting)
+  string(SUBSTRING "${__cmake_original_verify_setting}"
+    12 -1 __cmake_original_verify_setting
+  )
+  set(CMAKE_VERIFY_INTERFACE_HEADER_SETS ${__cmake_original_verify_setting})
+
   # clear local variables to prevent leaking into the caller's scope
   unset(__cmake_contentName)
   unset(__cmake_contentNameLower)
   unset(__cmake_contentNameUpper)
   unset(__cmake_providerCommand)
+  unset(__cmake_original_verify_setting)
 
 endmacro()
diff --git a/Modules/FindLua.cmake b/Modules/FindLua.cmake
index 32642fe..b56a7b1 100644
--- a/Modules/FindLua.cmake
+++ b/Modules/FindLua.cmake
@@ -10,19 +10,22 @@
 .. versionadded:: 3.18
   Support for Lua 5.4.
 
-This module defines::
+This module defines:
 
-::
-
-  LUA_FOUND          - if false, do not try to link to Lua
-  LUA_LIBRARIES      - both lua and lualib
-  LUA_INCLUDE_DIR    - where to find lua.h
-  LUA_VERSION_STRING - the version of Lua found
-  LUA_VERSION_MAJOR  - the major version of Lua
-  LUA_VERSION_MINOR  - the minor version of Lua
-  LUA_VERSION_PATCH  - the patch version of Lua
-
-
+``LUA_FOUND``
+  if false, do not try to link to Lua
+``LUA_LIBRARIES``
+  both lua and lualib
+``LUA_INCLUDE_DIR``
+  where to find lua.h
+``LUA_VERSION_STRING``
+  the version of Lua found
+``LUA_VERSION_MAJOR``
+  the major version of Lua
+``LUA_VERSION_MINOR``
+  the minor version of Lua
+``LUA_VERSION_PATCH``
+  the patch version of Lua
 
 Note that the expected include convention is
 
diff --git a/Modules/FindOpenMP.cmake b/Modules/FindOpenMP.cmake
index 844ceb3..fbd99e8 100644
--- a/Modules/FindOpenMP.cmake
+++ b/Modules/FindOpenMP.cmake
@@ -601,7 +601,8 @@
         separate_arguments(_OpenMP_${LANG}_OPTIONS NATIVE_COMMAND "${OpenMP_${LANG}_FLAGS}")
         set_property(TARGET OpenMP::OpenMP_${LANG} PROPERTY
           INTERFACE_COMPILE_OPTIONS "$<$<COMPILE_LANGUAGE:${LANG}>:${_OpenMP_${LANG}_OPTIONS}>")
-        if(CMAKE_${LANG}_COMPILER_ID STREQUAL "Fujitsu")
+        if(CMAKE_${LANG}_COMPILER_ID STREQUAL "Fujitsu"
+          OR ${CMAKE_${LANG}_COMPILER_ID} STREQUAL "IntelLLVM")
           set_property(TARGET OpenMP::OpenMP_${LANG} PROPERTY
             INTERFACE_LINK_OPTIONS "${OpenMP_${LANG}_FLAGS}")
         endif()
diff --git a/Modules/Platform/Linux-IntelLLVM.cmake b/Modules/Platform/Linux-IntelLLVM.cmake
index 1363b44..992f80e 100644
--- a/Modules/Platform/Linux-IntelLLVM.cmake
+++ b/Modules/Platform/Linux-IntelLLVM.cmake
@@ -8,18 +8,6 @@
 endif()
 set(__LINUX_COMPILER_INTEL_LLVM 1)
 
-if(NOT XIAR)
-  set(_intel_xiar_hints)
-  foreach(lang C CXX Fortran)
-    if(IS_ABSOLUTE "${CMAKE_${lang}_COMPILER}")
-      get_filename_component(_hint "${CMAKE_${lang}_COMPILER}" PATH)
-      list(APPEND _intel_xiar_hints ${_hint})
-    endif()
-  endforeach()
-  find_program(XIAR NAMES xiar HINTS ${_intel_xiar_hints})
-  mark_as_advanced(XIAR)
-endif()
-
 macro(__linux_compiler_intel_llvm lang)
   set(CMAKE_${lang}_COMPILE_OPTIONS_PIC "-fPIC")
   set(CMAKE_${lang}_COMPILE_OPTIONS_PIE "-fPIE")
@@ -37,19 +25,5 @@
   set(CMAKE_${lang}_LINKER_WRAPPER_FLAG "-Wl,")
   set(CMAKE_${lang}_LINKER_WRAPPER_FLAG_SEP ",")
 
-  set(_CMAKE_${lang}_IPO_SUPPORTED_BY_CMAKE YES)
-
-  if(XIAR)
-    # INTERPROCEDURAL_OPTIMIZATION
-    set(CMAKE_${lang}_COMPILE_OPTIONS_IPO -ipo)
-    set(CMAKE_${lang}_CREATE_STATIC_LIBRARY_IPO
-      "${XIAR} cr <TARGET> <LINK_FLAGS> <OBJECTS> "
-      "${XIAR} -s <TARGET> ")
-    set(_CMAKE_${lang}_IPO_MAY_BE_SUPPORTED_BY_COMPILER YES)
-    set(_CMAKE_${lang}_IPO_LEGACY_BEHAVIOR YES)
-  else()
-    set(_CMAKE_${lang}_IPO_MAY_BE_SUPPORTED_BY_COMPILER NO)
-  endif()
-
   set(CMAKE_${lang}_COMPILE_OPTIONS_VISIBILITY "-fvisibility=")
 endmacro()
diff --git a/Modules/Platform/Windows-IntelLLVM.cmake b/Modules/Platform/Windows-IntelLLVM.cmake
index f24dcdb..43f5874 100644
--- a/Modules/Platform/Windows-IntelLLVM.cmake
+++ b/Modules/Platform/Windows-IntelLLVM.cmake
@@ -3,26 +3,61 @@
 
 
 # This module is shared by multiple languages; use include blocker.
-if(__WINDOWS_INTEL)
+if(__WINDOWS_INTEL_LLVM)
   return()
 endif()
-set(__WINDOWS_INTEL 1)
+set(__WINDOWS_INTEL_LLVM 1)
 
+# Platform/Windows-MSVC adds some linking options icx/ifx do not understand,
+# but that need to be passed to the linker.  Wrap all the linking options from
+# Platform/Windows-MSVC so that the compiler will hand them off to the linker
+# without interpreting them.
+
+# Save original CMAKE_${t}_LINKER_FLAGS_INIT
+foreach(t EXE SHARED MODULE STATIC)
+  set(_saved_cmake_${t}_linker_flags_init ${CMAKE_${t}_LINKER_FLAGS_INIT})
+  set(CMAKE_${t}_LINKER_FLAGS_INIT "")
+endforeach()
 include(Platform/Windows-MSVC)
+# Wrap linker flags from Windows-MSVC
+set(_IntelLLVM_LINKER_WRAPPER_FLAG "/Qoption,link,")
+set(_IntelLLVM_LINKER_WRAPPER_FLAG_SEP ",")
+foreach(t EXE SHARED MODULE STATIC)
+  set(_wrapped_linker_flags "")
+  foreach(flag ${CMAKE_${t}_LINKER_FLAGS_INIT})
+    string(STRIP ${flag} flag)
+    list(APPEND _wrapped_linker_flags "${_IntelLLVM_LINKER_WRAPPER_FLAG}${flag}")
+  endforeach()
+  set(CMAKE_${t}_LINKER_FLAGS_INIT "")
+  list(APPEND CMAKE_${t}_LINKER_FLAGS_INIT
+    ${_saved_cmake_${t}_linker_flags_init} ${_wrapped_linker_flags})
+endforeach()
+
 macro(__windows_compiler_intel lang)
   __windows_compiler_msvc(${lang})
 
-  # For DPCPP other offload cases, some link flags need to go to the compiler
-  # driver and others need to go to the linker.  Pass the compiler linking flags
-  # in CMAKE_${lang}_LINK_FLAGS and linker flags in LINK_FLAGS
+  set(CMAKE_${lang}_LINKER_WRAPPER_FLAG "${_IntelLLVM_LINKER_WRAPPER_FLAG}")
+  set(CMAKE_${lang}_LINKER_WRAPPER_FLAG_SEP "${_IntelLLVM_LINKER_WRAPPER_FLAG_SEP}")
+  set(CMAKE_${lang}_CREATE_WIN32_EXE "${CMAKE_${lang}_LINKER_WRAPPER_FLAG}/subsystem:windows")
+  set(CMAKE_${lang}_CREATE_CONSOLE_EXE "${CMAKE_${lang}_LINKER_WRAPPER_FLAG}/subsystem:console")
+  set(CMAKE_LINK_DEF_FILE_FLAG "${CMAKE_${lang}_LINKER_WRAPPER_FLAG}/DEF:")
+  set(CMAKE_LIBRARY_PATH_FLAG "${CMAKE_${lang}_LINKER_WRAPPER_FLAG}/LIBPATH:")
+
+  # Features for LINK_LIBRARY generator expression
+  if(MSVC_VERSION GREATER "1900")
+    ## WHOLE_ARCHIVE: Force loading all members of an archive
+    set(CMAKE_LINK_LIBRARY_USING_WHOLE_ARCHIVE "LINKER:/WHOLEARCHIVE:<LIBRARY>")
+    set(CMAKE_LINK_LIBRARY_USING_WHOLE_ARCHIVE_SUPPORTED TRUE)
+  endif()
+
   set(CMAKE_${lang}_LINK_EXECUTABLE
-    "${_CMAKE_VS_LINK_EXE}<CMAKE_${lang}_COMPILER> ${CMAKE_CL_NOLOGO} <CMAKE_${lang}_LINK_FLAGS> <OBJECTS> ${CMAKE_START_TEMP_FILE} /link /out:<TARGET> /implib:<TARGET_IMPLIB> /pdb:<TARGET_PDB> /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR>${_PLATFORM_LINK_FLAGS} <LINK_FLAGS> <LINK_LIBRARIES>${CMAKE_END_TEMP_FILE}")
+    "${_CMAKE_VS_LINK_EXE}<CMAKE_${lang}_COMPILER> ${CMAKE_CL_NOLOGO} <CMAKE_${lang}_LINK_FLAGS> <OBJECTS> ${CMAKE_START_TEMP_FILE} <LINK_FLAGS> <LINK_LIBRARIES> /link /out:<TARGET> /implib:<TARGET_IMPLIB> /pdb:<TARGET_PDB> /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR>${_PLATFORM_LINK_FLAGS} ${CMAKE_END_TEMP_FILE}")
   set(CMAKE_${lang}_CREATE_SHARED_LIBRARY
-    "${_CMAKE_VS_LINK_DLL}<CMAKE_${lang}_COMPILER> ${CMAKE_CL_NOLOGO} <CMAKE_${lang}_LINK_FLAGS> <OBJECTS> ${CMAKE_START_TEMP_FILE} -LD -link /out:<TARGET> /implib:<TARGET_IMPLIB> /pdb:<TARGET_PDB> /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR>${_PLATFORM_LINK_FLAGS} <LINK_FLAGS> <LINK_LIBRARIES> ${CMAKE_END_TEMP_FILE}")
+    "${_CMAKE_VS_LINK_DLL}<CMAKE_${lang}_COMPILER> ${CMAKE_CL_NOLOGO} <CMAKE_${lang}_LINK_FLAGS> <OBJECTS> ${CMAKE_START_TEMP_FILE} -LD <LINK_FLAGS> <LINK_LIBRARIES> -link /out:<TARGET> /implib:<TARGET_IMPLIB> /pdb:<TARGET_PDB> /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR>${_PLATFORM_LINK_FLAGS} ${CMAKE_END_TEMP_FILE}")
   if (NOT "${lang}" STREQUAL "Fortran" OR CMAKE_${lang}_COMPILER_VERSION VERSION_GREATER_EQUAL 2022.1)
     # The Fortran driver does not support -fuse-ld=llvm-lib before compiler version 2022.1
     set(CMAKE_${lang}_CREATE_STATIC_LIBRARY
-      "<CMAKE_${lang}_COMPILER> ${CMAKE_CL_NOLOGO} <CMAKE_${lang}_LINK_FLAGS> <OBJECTS> ${CMAKE_START_TEMP_FILE} -fuse-ld=llvm-lib -o <TARGET> -link <LINK_FLAGS> <LINK_LIBRARIES> ${CMAKE_END_TEMP_FILE}")
+      "<CMAKE_${lang}_COMPILER> ${CMAKE_CL_NOLOGO} <CMAKE_${lang}_LINK_FLAGS> <OBJECTS> ${CMAKE_START_TEMP_FILE} -fuse-ld=llvm-lib -o <TARGET> <LINK_FLAGS> <LINK_LIBRARIES> ${CMAKE_END_TEMP_FILE}")
   endif()
 
   set(CMAKE_DEPFILE_FLAGS_${lang} "-QMD -QMT <DEP_TARGET> -QMF <DEP_FILE>")
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 5190ab1..089b279 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,7 +1,7 @@
 # CMake version number components.
 set(CMake_VERSION_MAJOR 3)
 set(CMake_VERSION_MINOR 24)
-set(CMake_VERSION_PATCH 20220803)
+set(CMake_VERSION_PATCH 20220805)
 #set(CMake_VERSION_RC 0)
 set(CMake_VERSION_IS_DIRTY 0)
 
diff --git a/Source/cmCMakePresetsGraph.cxx b/Source/cmCMakePresetsGraph.cxx
index b737c1f..dba79d5 100644
--- a/Source/cmCMakePresetsGraph.cxx
+++ b/Source/cmCMakePresetsGraph.cxx
@@ -901,8 +901,9 @@
   std::string filename = GetUserFilename(this->SourceDir);
   std::vector<File*> inProgressFiles;
   if (cmSystemTools::FileExists(filename)) {
-    auto result = this->ReadJSONFile(filename, RootType::User,
-                                     ReadReason::Root, inProgressFiles, file);
+    auto result =
+      this->ReadJSONFile(filename, RootType::User, ReadReason::Root,
+                         inProgressFiles, file, this->errors);
     if (result != ReadFileResult::READ_OK) {
       return result;
     }
@@ -910,8 +911,9 @@
   } else {
     filename = GetFilename(this->SourceDir);
     if (cmSystemTools::FileExists(filename)) {
-      auto result = this->ReadJSONFile(
-        filename, RootType::Project, ReadReason::Root, inProgressFiles, file);
+      auto result =
+        this->ReadJSONFile(filename, RootType::Project, ReadReason::Root,
+                           inProgressFiles, file, this->errors);
       if (result != ReadFileResult::READ_OK) {
         return result;
       }
diff --git a/Source/cmCMakePresetsGraph.h b/Source/cmCMakePresetsGraph.h
index f1f8662..4f3e108 100644
--- a/Source/cmCMakePresetsGraph.h
+++ b/Source/cmCMakePresetsGraph.h
@@ -52,6 +52,7 @@
     TEST_OUTPUT_TRUNCATION_UNSUPPORTED,
   };
 
+  std::string errors;
   enum class ArchToolsetStrategy
   {
     Set,
@@ -407,7 +408,7 @@
   ReadFileResult ReadProjectPresetsInternal(bool allowNoFiles);
   ReadFileResult ReadJSONFile(const std::string& filename, RootType rootType,
                               ReadReason readReason,
-                              std::vector<File*>& inProgressFiles,
-                              File*& file);
+                              std::vector<File*>& inProgressFiles, File*& file,
+                              std::string& errMsg);
   void ClearPresets();
 };
diff --git a/Source/cmCMakePresetsGraphReadJSON.cxx b/Source/cmCMakePresetsGraphReadJSON.cxx
index d11e839..d68af22 100644
--- a/Source/cmCMakePresetsGraphReadJSON.cxx
+++ b/Source/cmCMakePresetsGraphReadJSON.cxx
@@ -411,7 +411,7 @@
 
 cmCMakePresetsGraph::ReadFileResult cmCMakePresetsGraph::ReadJSONFile(
   const std::string& filename, RootType rootType, ReadReason readReason,
-  std::vector<File*>& inProgressFiles, File*& file)
+  std::vector<File*>& inProgressFiles, File*& file, std::string& errMsg)
 {
   ReadFileResult result;
 
@@ -430,6 +430,7 @@
 
   cmsys::ifstream fin(filename.c_str());
   if (!fin) {
+    errMsg = cmStrCat(filename, ": Failed to read file\n", errMsg);
     return ReadFileResult::FILE_NOT_FOUND;
   }
   // If there's a BOM, toss it.
@@ -438,7 +439,8 @@
   Json::Value root;
   Json::CharReaderBuilder builder;
   Json::CharReaderBuilder::strictMode(&builder.settings_);
-  if (!Json::parseFromStream(builder, fin, &root, nullptr)) {
+  if (!Json::parseFromStream(builder, fin, &root, &errMsg)) {
+    errMsg = cmStrCat(filename, ":\n", errMsg);
     return ReadFileResult::JSON_PARSE_ERROR;
   }
 
@@ -490,6 +492,8 @@
   for (auto& preset : presets.ConfigurePresets) {
     preset.OriginFile = file;
     if (preset.Name.empty()) {
+      errMsg += R"(\n\t)";
+      errMsg += filename;
       return ReadFileResult::INVALID_PRESET;
     }
 
@@ -523,6 +527,8 @@
   for (auto& preset : presets.BuildPresets) {
     preset.OriginFile = file;
     if (preset.Name.empty()) {
+      errMsg += R"(\n\t)";
+      errMsg += filename;
       return ReadFileResult::INVALID_PRESET;
     }
 
@@ -569,12 +575,13 @@
 
   auto const includeFile = [this, &inProgressFiles, file](
                              const std::string& include, RootType rootType2,
-                             ReadReason readReason2) -> ReadFileResult {
+                             ReadReason readReason2,
+                             std::string& FailureMessage) -> ReadFileResult {
     ReadFileResult r;
     File* includedFile;
     if ((r = this->ReadJSONFile(include, rootType2, readReason2,
-                                inProgressFiles, includedFile)) !=
-        ReadFileResult::READ_OK) {
+                                inProgressFiles, includedFile,
+                                FailureMessage)) != ReadFileResult::READ_OK) {
       return r;
     }
 
@@ -589,8 +596,8 @@
       include = cmStrCat(directory, '/', include);
     }
 
-    if ((result = includeFile(include, rootType, ReadReason::Included)) !=
-        ReadFileResult::READ_OK) {
+    if ((result = includeFile(include, rootType, ReadReason::Included,
+                              errMsg)) != ReadFileResult::READ_OK) {
       return result;
     }
   }
@@ -599,7 +606,7 @@
     auto cmakePresetsFilename = GetFilename(this->SourceDir);
     if (cmSystemTools::FileExists(cmakePresetsFilename)) {
       if ((result = includeFile(cmakePresetsFilename, RootType::Project,
-                                ReadReason::Root)) !=
+                                ReadReason::Root, errMsg)) !=
           ReadFileResult::READ_OK) {
         return result;
       }
diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx
index ab9ca50..21aa89c 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.cxx
+++ b/Source/cmGlobalUnixMakefileGenerator3.cxx
@@ -181,12 +181,12 @@
     return;
   }
 
-  // get a local generator for some useful methods
-  auto& lg = cm::static_reference_cast<cmLocalUnixMakefileGenerator3>(
+  // The global dependency graph is expressed via the root local generator.
+  auto& rootLG = cm::static_reference_cast<cmLocalUnixMakefileGenerator3>(
     this->LocalGenerators[0]);
 
   // Write the do not edit header.
-  lg.WriteDisclaimer(makefileStream);
+  rootLG.WriteDisclaimer(makefileStream);
 
   // Write the main entry point target.  This must be the VERY first
   // target so that make with no arguments will run it.
@@ -196,10 +196,10 @@
   depends.emplace_back("all");
 
   // Write the rule.
-  lg.WriteMakeRule(makefileStream,
-                   "Default target executed when no arguments are "
-                   "given to make.",
-                   "default_target", depends, no_commands, true);
+  rootLG.WriteMakeRule(makefileStream,
+                       "Default target executed when no arguments are "
+                       "given to make.",
+                       "default_target", depends, no_commands, true);
 
   depends.clear();
 
@@ -210,22 +210,22 @@
   }
 
   // Write out the "special" stuff
-  lg.WriteSpecialTargetsTop(makefileStream);
+  rootLG.WriteSpecialTargetsTop(makefileStream);
 
   // Write the directory level rules.
   for (auto const& it : this->ComputeDirectoryTargets()) {
-    this->WriteDirectoryRules2(makefileStream, it.second);
+    this->WriteDirectoryRules2(makefileStream, rootLG, it.second);
   }
 
   // Write the target convenience rules
   for (const auto& localGen : this->LocalGenerators) {
     this->WriteConvenienceRules2(
-      makefileStream,
+      makefileStream, rootLG,
       cm::static_reference_cast<cmLocalUnixMakefileGenerator3>(localGen));
   }
 
   // Write special bottom targets
-  lg.WriteSpecialTargetsBottom(makefileStream);
+  rootLG.WriteSpecialTargetsBottom(makefileStream);
 }
 
 void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile()
@@ -359,8 +359,9 @@
 }
 
 void cmGlobalUnixMakefileGenerator3::WriteDirectoryRule2(
-  std::ostream& ruleFileStream, DirectoryTarget const& dt, const char* pass,
-  bool check_all, bool check_relink, std::vector<std::string> const& commands)
+  std::ostream& ruleFileStream, cmLocalUnixMakefileGenerator3& rootLG,
+  DirectoryTarget const& dt, const char* pass, bool check_all,
+  bool check_relink, std::vector<std::string> const& commands)
 {
   auto* lg = static_cast<cmLocalUnixMakefileGenerator3*>(dt.LG);
   std::string makeTarget =
@@ -406,19 +407,21 @@
   } else {
     doc = cmStrCat("Recursive \"", pass, "\" directory target.");
   }
-  lg->WriteMakeRule(ruleFileStream, doc.c_str(), makeTarget, depends, commands,
-                    true);
+
+  rootLG.WriteMakeRule(ruleFileStream, doc.c_str(), makeTarget, depends,
+                       commands, true);
 }
 
 void cmGlobalUnixMakefileGenerator3::WriteDirectoryRules2(
-  std::ostream& ruleFileStream, DirectoryTarget const& dt)
+  std::ostream& ruleFileStream, cmLocalUnixMakefileGenerator3& rootLG,
+  DirectoryTarget const& dt)
 {
   auto* lg = static_cast<cmLocalUnixMakefileGenerator3*>(dt.LG);
   // Begin the directory-level rules section.
   {
     std::string dir = cmSystemTools::ConvertToOutputPath(
-      lg->MaybeRelativeToTopBinDir(lg->GetCurrentBinaryDirectory()));
-    lg->WriteDivider(ruleFileStream);
+      rootLG.MaybeRelativeToTopBinDir(lg->GetCurrentBinaryDirectory()));
+    rootLG.WriteDivider(ruleFileStream);
     if (lg->IsRootMakefile()) {
       ruleFileStream << "# Directory level rules for the build root directory";
     } else {
@@ -428,16 +431,18 @@
   }
 
   // Write directory-level rules for "all".
-  this->WriteDirectoryRule2(ruleFileStream, dt, "all", true, false);
+  this->WriteDirectoryRule2(ruleFileStream, rootLG, dt, "all", true, false);
 
   // Write directory-level rules for "preinstall".
-  this->WriteDirectoryRule2(ruleFileStream, dt, "preinstall", true, true);
+  this->WriteDirectoryRule2(ruleFileStream, rootLG, dt, "preinstall", true,
+                            true);
 
   // Write directory-level rules for "clean".
   {
     std::vector<std::string> cmds;
     lg->AppendDirectoryCleanCommand(cmds);
-    this->WriteDirectoryRule2(ruleFileStream, dt, "clean", false, false, cmds);
+    this->WriteDirectoryRule2(ruleFileStream, rootLG, dt, "clean", false,
+                              false, cmds);
   }
 }
 
@@ -632,7 +637,8 @@
 }
 
 void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules2(
-  std::ostream& ruleFileStream, cmLocalUnixMakefileGenerator3& lg)
+  std::ostream& ruleFileStream, cmLocalUnixMakefileGenerator3& rootLG,
+  cmLocalUnixMakefileGenerator3& lg)
 {
   std::vector<std::string> depends;
   std::vector<std::string> commands;
@@ -696,8 +702,8 @@
       }
 
       this->AppendGlobalTargetDepends(depends, gtarget.get());
-      lg.WriteMakeRule(ruleFileStream, "All Build rule for target.", localName,
-                       depends, commands, true);
+      rootLG.WriteMakeRule(ruleFileStream, "All Build rule for target.",
+                           localName, depends, commands, true);
 
       // Write the rule.
       commands.clear();
@@ -731,16 +737,16 @@
       }
       localName =
         cmStrCat(lg.GetRelativeTargetDirectory(gtarget.get()), "/rule");
-      lg.WriteMakeRule(ruleFileStream,
-                       "Build rule for subdir invocation for target.",
-                       localName, depends, commands, true);
+      rootLG.WriteMakeRule(ruleFileStream,
+                           "Build rule for subdir invocation for target.",
+                           localName, depends, commands, true);
 
       // Add a target with the canonical name (no prefix, suffix or path).
       commands.clear();
       depends.clear();
       depends.push_back(localName);
-      lg.WriteMakeRule(ruleFileStream, "Convenience name for target.", name,
-                       depends, commands, true);
+      rootLG.WriteMakeRule(ruleFileStream, "Convenience name for target.",
+                           name, depends, commands, true);
 
       // Add rules to prepare the target for installation.
       if (gtarget->NeedRelinkBeforeInstall(lg.GetConfigName())) {
@@ -749,8 +755,9 @@
         depends.clear();
         commands.clear();
         commands.push_back(lg.GetRecursiveMakeCall(makefileName, localName));
-        lg.WriteMakeRule(ruleFileStream, "Pre-install relink rule for target.",
-                         localName, depends, commands, true);
+        rootLG.WriteMakeRule(ruleFileStream,
+                             "Pre-install relink rule for target.", localName,
+                             depends, commands, true);
       }
 
       // add the clean rule
@@ -760,8 +767,8 @@
       commands.clear();
       commands.push_back(
         lg.GetRecursiveMakeCall(makefileName, makeTargetName));
-      lg.WriteMakeRule(ruleFileStream, "clean rule for target.",
-                       makeTargetName, depends, commands, true);
+      rootLG.WriteMakeRule(ruleFileStream, "clean rule for target.",
+                           makeTargetName, depends, commands, true);
       commands.clear();
     }
   }
diff --git a/Source/cmGlobalUnixMakefileGenerator3.h b/Source/cmGlobalUnixMakefileGenerator3.h
index 5157826..b9d333e 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.h
+++ b/Source/cmGlobalUnixMakefileGenerator3.h
@@ -200,13 +200,16 @@
   void WriteMainCMakefile();
 
   void WriteConvenienceRules2(std::ostream& ruleFileStream,
-                              cmLocalUnixMakefileGenerator3&);
+                              cmLocalUnixMakefileGenerator3& rootLG,
+                              cmLocalUnixMakefileGenerator3& lg);
 
   void WriteDirectoryRule2(std::ostream& ruleFileStream,
+                           cmLocalUnixMakefileGenerator3& rootLG,
                            DirectoryTarget const& dt, const char* pass,
                            bool check_all, bool check_relink,
                            std::vector<std::string> const& commands = {});
   void WriteDirectoryRules2(std::ostream& ruleFileStream,
+                            cmLocalUnixMakefileGenerator3& rootLG,
                             DirectoryTarget const& dt);
 
   void AppendGlobalTargetDepends(std::vector<std::string>& depends,
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index 12d42b2..9b2b119 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -1283,9 +1283,13 @@
     cmCMakePresetsGraph presetsGraph;
     auto result = presetsGraph.ReadProjectPresets(this->GetHomeDirectory());
     if (result != cmCMakePresetsGraph::ReadFileResult::READ_OK) {
-      cmSystemTools::Error(
+      std::string errorMsg =
         cmStrCat("Could not read presets from ", this->GetHomeDirectory(),
-                 ": ", cmCMakePresetsGraph::ResultToString(result)));
+                 ": ", cmCMakePresetsGraph::ResultToString(result));
+      if (!presetsGraph.errors.empty()) {
+        errorMsg = cmStrCat(errorMsg, "\nErrors:\n", presetsGraph.errors);
+      }
+      cmSystemTools::Error(errorMsg);
       return;
     }
 
diff --git a/Tests/ModuleDefinition/CMakeLists.txt b/Tests/ModuleDefinition/CMakeLists.txt
index 567fb4b..483bd8b 100644
--- a/Tests/ModuleDefinition/CMakeLists.txt
+++ b/Tests/ModuleDefinition/CMakeLists.txt
@@ -15,7 +15,17 @@
 add_library(example_dll_gen SHARED example_dll_gen.c example_dll_gen.def)
 
 # Test /DEF:<file> flag recognition for VS.
-if(MSVC OR CMAKE_C_COMPILER_ID STREQUAL "Intel")
+if(MSVC AND CMAKE_C_COMPILER_ID STREQUAL "IntelLLVM")
+  # IntelLLVM for MSVC frontend variant needs the /DEF flag wrapped to be sent
+  # to the linker, which happens automatically when the DEF file is added
+  # to the sources.
+  add_library(example_dll_2 SHARED
+    example_dll_2.c
+    "${ModuleDefinition_SOURCE_DIR}/example_dll_2.def"
+    )
+  set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS EXAMPLE_DLL_2)
+  set(example_dll_2 example_dll_2)
+elseif(MSVC OR CMAKE_C_COMPILER_ID STREQUAL "Intel")
   add_library(example_dll_2 SHARED example_dll_2.c)
   set_property(TARGET example_dll_2 PROPERTY LINK_FLAGS
     /DEF:"${ModuleDefinition_SOURCE_DIR}/example_dll_2.def")
diff --git a/Tests/OutOfSource/CMakeLists.txt b/Tests/OutOfSource/CMakeLists.txt
index 4687882..c82d077 100644
--- a/Tests/OutOfSource/CMakeLists.txt
+++ b/Tests/OutOfSource/CMakeLists.txt
@@ -16,3 +16,6 @@
   )
 
 set(KEN 1)
+
+configure_file(SubInBuildCMakeLists.cmake ${CMAKE_CURRENT_BINARY_DIR}/SubInBuild/CMakeLists.txt COPYONLY)
+add_subdirectory(${CMAKE_CURRENT_BINARY_DIR}/SubInBuild ${CMAKE_CURRENT_BINARY_DIR}/SubInBuild/Build)
diff --git a/Tests/OutOfSource/SubInBuildCMakeLists.cmake b/Tests/OutOfSource/SubInBuildCMakeLists.cmake
new file mode 100644
index 0000000..c2e2942
--- /dev/null
+++ b/Tests/OutOfSource/SubInBuildCMakeLists.cmake
@@ -0,0 +1 @@
+add_custom_target(SubInBuildCustom ALL)
diff --git a/Tests/RunCMake/CMakePresets/Comment-stderr.txt b/Tests/RunCMake/CMakePresets/Comment-stderr.txt
index 2f404bc..b3b6b66 100644
--- a/Tests/RunCMake/CMakePresets/Comment-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/Comment-stderr.txt
@@ -1,2 +1,9 @@
 ^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/Comment: JSON parse error$
+]*/Tests/RunCMake/CMakePresets/Comment: JSON parse error
+Errors:
+[^
+]*Comment\/CMakePresets.json:
+\* Line 1, Column 1
+  Syntax error: value, object or array expected\.
+\* Line 2, Column 1
+  Extra non-whitespace after JSON value\.$
diff --git a/Tests/RunCMake/CMakePresets/EmptyPresetName-stderr.txt b/Tests/RunCMake/CMakePresets/EmptyPresetName-stderr.txt
index 6970674..0d3c500 100644
--- a/Tests/RunCMake/CMakePresets/EmptyPresetName-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/EmptyPresetName-stderr.txt
@@ -1,2 +1,5 @@
 ^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/EmptyPresetName: Invalid preset$
+]*/Tests/RunCMake/CMakePresets/EmptyPresetName: Invalid preset
+Errors:
+[^
+]*/EmptyPresetName/CMakePresets.json$
diff --git a/Tests/RunCMake/CMakePresets/IncludeNotFound-stderr.txt b/Tests/RunCMake/CMakePresets/IncludeNotFound-stderr.txt
index 7ccabab..85a2d78 100644
--- a/Tests/RunCMake/CMakePresets/IncludeNotFound-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/IncludeNotFound-stderr.txt
@@ -1,2 +1,5 @@
 ^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/IncludeNotFound: File not found$
+]*/Tests/RunCMake/CMakePresets/IncludeNotFound: File not found
+Errors:
+[^
+]*/IncludeNotFound/NotFound.json: Failed to read file$
diff --git a/Tests/RunCMake/CMakePresets/JSONParseError-stderr.txt b/Tests/RunCMake/CMakePresets/JSONParseError-stderr.txt
index a43bf77..89eff9f 100644
--- a/Tests/RunCMake/CMakePresets/JSONParseError-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/JSONParseError-stderr.txt
@@ -1,2 +1,9 @@
 ^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/JSONParseError: JSON parse error$
+]*/Tests/RunCMake/CMakePresets/JSONParseError: JSON parse error
+Errors:
+[^
+]*JSONParseError/CMakePresets.json:
+\* Line 1, Column 1
+  Syntax error: value, object or array expected\.
+\* Line 1, Column 1
+  A valid JSON document must be either an array or an object value\.$
diff --git a/Tests/RunCMake/FetchContent/RunCMakeTest.cmake b/Tests/RunCMake/FetchContent/RunCMakeTest.cmake
index e83c45e..a7ccf83 100644
--- a/Tests/RunCMake/FetchContent/RunCMakeTest.cmake
+++ b/Tests/RunCMake/FetchContent/RunCMakeTest.cmake
@@ -15,6 +15,7 @@
 run_cmake(MakeAvailable)
 run_cmake(MakeAvailableTwice)
 run_cmake(MakeAvailableUndeclared)
+run_cmake(VerifyHeaderSet)
 
 run_cmake_with_options(ManualSourceDirectory
   -D "FETCHCONTENT_SOURCE_DIR_WITHPROJECT=${CMAKE_CURRENT_LIST_DIR}/WithProject"
diff --git a/Tests/RunCMake/FetchContent/VerifyHeaderSet-stdout.txt b/Tests/RunCMake/FetchContent/VerifyHeaderSet-stdout.txt
new file mode 100644
index 0000000..354529d
--- /dev/null
+++ b/Tests/RunCMake/FetchContent/VerifyHeaderSet-stdout.txt
@@ -0,0 +1,4 @@
+-- Before subproject, var = 'TRUE'
+-- Inside subproject, var = 'FALSE'
+-- After subproject, var = 'TRUE'
+-- Subproject target property VERIFY_INTERFACE_HEADER_SETS='FALSE'
diff --git a/Tests/RunCMake/FetchContent/VerifyHeaderSet.cmake b/Tests/RunCMake/FetchContent/VerifyHeaderSet.cmake
new file mode 100644
index 0000000..8adfcea
--- /dev/null
+++ b/Tests/RunCMake/FetchContent/VerifyHeaderSet.cmake
@@ -0,0 +1,16 @@
+enable_language(C)
+
+set(CMAKE_VERIFY_INTERFACE_HEADER_SETS TRUE)
+
+include(FetchContent)
+FetchContent_Declare(verify_subproj
+  SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/VerifyHeaderSet
+)
+message(STATUS "Before subproject, var = '${CMAKE_VERIFY_INTERFACE_HEADER_SETS}'")
+FetchContent_MakeAvailable(verify_subproj)
+
+# Provide a way to verify the variable was reset back to its original value
+message(STATUS "After subproject, var = '${CMAKE_VERIFY_INTERFACE_HEADER_SETS}'")
+
+get_property(verify TARGET Blah PROPERTY VERIFY_INTERFACE_HEADER_SETS)
+message(STATUS "Subproject target property VERIFY_INTERFACE_HEADER_SETS='${verify}'")
diff --git a/Tests/RunCMake/FetchContent/VerifyHeaderSet/CMakeLists.txt b/Tests/RunCMake/FetchContent/VerifyHeaderSet/CMakeLists.txt
new file mode 100644
index 0000000..c6ba37e
--- /dev/null
+++ b/Tests/RunCMake/FetchContent/VerifyHeaderSet/CMakeLists.txt
@@ -0,0 +1,9 @@
+cmake_minimum_required(VERSION 3.24)
+project(VerifyHeaderSet LANGUAGES C)
+
+message(STATUS "Inside subproject, var = '${CMAKE_VERIFY_INTERFACE_HEADER_SETS}'")
+
+add_library(Blah INTERFACE)
+target_sources(Blah
+  INTERFACE FILE_SET HEADERS FILES blah.h
+)
diff --git a/Tests/RunCMake/FetchContent/VerifyHeaderSet/blah.h b/Tests/RunCMake/FetchContent/VerifyHeaderSet/blah.h
new file mode 100644
index 0000000..5b47e14
--- /dev/null
+++ b/Tests/RunCMake/FetchContent/VerifyHeaderSet/blah.h
@@ -0,0 +1 @@
+#error Header was used