summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Help/variable/CMAKE_VERIFY_INTERFACE_HEADER_SETS.rst24
-rw-r--r--Modules/FetchContent.cmake27
-rw-r--r--Tests/RunCMake/FetchContent/RunCMakeTest.cmake1
-rw-r--r--Tests/RunCMake/FetchContent/VerifyHeaderSet-stdout.txt4
-rw-r--r--Tests/RunCMake/FetchContent/VerifyHeaderSet.cmake16
-rw-r--r--Tests/RunCMake/FetchContent/VerifyHeaderSet/CMakeLists.txt9
-rw-r--r--Tests/RunCMake/FetchContent/VerifyHeaderSet/blah.h1
7 files changed, 81 insertions, 1 deletions
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 @@ This variable is used to initialize the
: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/FetchContent.cmake b/Modules/FetchContent.cmake
index 27070c0..d016fb5 100644
--- a/Modules/FetchContent.cmake
+++ b/Modules/FetchContent.cmake
@@ -364,6 +364,18 @@ Commands
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 @@ endfunction()
# 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 @@ macro(FetchContent_MakeAvailable)
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/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(UsesTerminalOverride)
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