mirror of
https://github.com/Kitware/CMake.git
synced 2026-05-12 09:08:58 -05:00
VERIFY_INTERFACE_HEADER_SETS: Add property for list of header sets
Add a new property, INTERFACE_HEADER_SETS_TO_VERIFY, which contains a list of header sets that should be verified by VERIFY_INTERFACE_HEADER_SETS. Fixes: #23522
This commit is contained in:
@@ -263,6 +263,7 @@ Properties on Targets
|
|||||||
/prop_tgt/INTERFACE_COMPILE_FEATURES
|
/prop_tgt/INTERFACE_COMPILE_FEATURES
|
||||||
/prop_tgt/INTERFACE_COMPILE_OPTIONS
|
/prop_tgt/INTERFACE_COMPILE_OPTIONS
|
||||||
/prop_tgt/INTERFACE_HEADER_SETS
|
/prop_tgt/INTERFACE_HEADER_SETS
|
||||||
|
/prop_tgt/INTERFACE_HEADER_SETS_TO_VERIFY
|
||||||
/prop_tgt/INTERFACE_INCLUDE_DIRECTORIES
|
/prop_tgt/INTERFACE_INCLUDE_DIRECTORIES
|
||||||
/prop_tgt/INTERFACE_LINK_DEPENDS
|
/prop_tgt/INTERFACE_LINK_DEPENDS
|
||||||
/prop_tgt/INTERFACE_LINK_DIRECTORIES
|
/prop_tgt/INTERFACE_LINK_DIRECTORIES
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
INTERFACE_HEADER_SETS_TO_VERIFY
|
||||||
|
-------------------------------
|
||||||
|
|
||||||
|
.. versionadded:: 3.24
|
||||||
|
|
||||||
|
Used to specify which ``PUBLIC`` and ``INTERFACE`` header sets of a target
|
||||||
|
should be verified.
|
||||||
|
|
||||||
|
This property contains a semicolon-separated list of header sets which
|
||||||
|
should be verified if :prop_tgt:`VERIFY_INTERFACE_HEADER_SETS` is set to
|
||||||
|
``TRUE``. If the list is empty, all ``PUBLIC`` and ``INTERFACE`` header sets
|
||||||
|
are verified. (If the project does not want to verify any header sets on the
|
||||||
|
target, simply set :prop_tgt:`VERIFY_INTERFACE_HEADER_SETS` to ``FALSE``.)
|
||||||
@@ -23,3 +23,6 @@ is used to determine the language with which to compile the header file.
|
|||||||
Otherwise, if the target has any C++ sources, the header is compiled as C++.
|
Otherwise, if the target has any C++ sources, the header is compiled as C++.
|
||||||
Otherwise, if the target has any C sources, the header is compiled as C.
|
Otherwise, if the target has any C sources, the header is compiled as C.
|
||||||
Otherwise, the header file is not compiled.
|
Otherwise, the header file is not compiled.
|
||||||
|
|
||||||
|
If the project wishes to control which header sets are verified by this
|
||||||
|
property, you can set :prop_tgt:`INTERFACE_HEADER_SETS_TO_VERIFY`.
|
||||||
|
|||||||
@@ -7,3 +7,6 @@ verify-interface-header-sets
|
|||||||
* A new :variable:`CMAKE_VERIFY_INTERFACE_HEADER_SETS` variable was added,
|
* A new :variable:`CMAKE_VERIFY_INTERFACE_HEADER_SETS` variable was added,
|
||||||
which is used to initialize the :prop_tgt:`VERIFY_INTERFACE_HEADER_SETS`
|
which is used to initialize the :prop_tgt:`VERIFY_INTERFACE_HEADER_SETS`
|
||||||
target property.
|
target property.
|
||||||
|
* A new :prop_tgt:`INTERFACE_HEADER_SETS_TO_VERIFY` target property was added,
|
||||||
|
which can be used to specify which header sets should be verified by
|
||||||
|
:prop_tgt:`VERIFY_INTERFACE_HEADER_SETS`.
|
||||||
|
|||||||
@@ -8525,19 +8525,37 @@ bool cmGeneratorTarget::AddHeaderSetVerification()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto verifyValue = this->GetProperty("INTERFACE_HEADER_SETS_TO_VERIFY");
|
||||||
|
const bool all = verifyValue.IsEmpty();
|
||||||
|
std::set<std::string> verifySet;
|
||||||
|
if (!all) {
|
||||||
|
auto verifyList = cmExpandedList(verifyValue);
|
||||||
|
verifySet.insert(verifyList.begin(), verifyList.end());
|
||||||
|
}
|
||||||
|
|
||||||
cmTarget* verifyTarget = nullptr;
|
cmTarget* verifyTarget = nullptr;
|
||||||
|
|
||||||
auto interfaceFileSetEntries = this->Target->GetInterfaceHeaderSetsEntries();
|
auto interfaceFileSetEntries = this->Target->GetInterfaceHeaderSetsEntries();
|
||||||
|
|
||||||
std::set<cmFileSet*> fileSets;
|
std::set<cmFileSet*> fileSets;
|
||||||
auto const addFileSets = [&fileSets, this](const cmBTStringRange& entries) {
|
for (auto const& entry : interfaceFileSetEntries) {
|
||||||
for (auto const& entry : entries) {
|
for (auto const& name : cmExpandedList(entry.Value)) {
|
||||||
for (auto const& name : cmExpandedList(entry.Value)) {
|
if (all || verifySet.count(name)) {
|
||||||
fileSets.insert(this->Target->GetFileSet(name));
|
fileSets.insert(this->Target->GetFileSet(name));
|
||||||
|
verifySet.erase(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
addFileSets(interfaceFileSetEntries);
|
if (!verifySet.empty()) {
|
||||||
|
this->Makefile->IssueMessage(
|
||||||
|
MessageType::FATAL_ERROR,
|
||||||
|
cmStrCat("Property INTERFACE_HEADER_SETS_TO_VERIFY of target \"",
|
||||||
|
this->GetName(),
|
||||||
|
"\" contained the following header sets that are nonexistent "
|
||||||
|
"or not INTERFACE:\n ",
|
||||||
|
cmJoin(verifySet, "\n ")));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
cm::optional<std::set<std::string>> languages;
|
cm::optional<std::set<std::string>> languages;
|
||||||
for (auto* fileSet : fileSets) {
|
for (auto* fileSet : fileSets) {
|
||||||
|
|||||||
@@ -40,3 +40,8 @@ endif()
|
|||||||
|
|
||||||
run_cmake_build(VerifyHeaderSets lang_test_c_verify_interface_header_sets)
|
run_cmake_build(VerifyHeaderSets lang_test_c_verify_interface_header_sets)
|
||||||
run_cmake_build(VerifyHeaderSets lang_test_cxx_verify_interface_header_sets)
|
run_cmake_build(VerifyHeaderSets lang_test_cxx_verify_interface_header_sets)
|
||||||
|
run_cmake_build(VerifyHeaderSets list_verify_interface_header_sets)
|
||||||
|
|
||||||
|
set(RunCMake_TEST_OPTIONS -DCMAKE_VERIFY_INTERFACE_HEADER_SETS=ON)
|
||||||
|
run_cmake(VerifyHeaderSetsNonexistent)
|
||||||
|
unset(RunCMake_TEST_OPTIONS)
|
||||||
|
|||||||
@@ -58,3 +58,13 @@ target_sources(lang_test_c INTERFACE FILE_SET HEADERS FILES lang_test.h)
|
|||||||
add_library(lang_test_cxx STATIC lib.c lib.cxx)
|
add_library(lang_test_cxx STATIC lib.c lib.cxx)
|
||||||
target_compile_definitions(lang_test_cxx INTERFACE EXPECT_CXX)
|
target_compile_definitions(lang_test_cxx INTERFACE EXPECT_CXX)
|
||||||
target_sources(lang_test_cxx INTERFACE FILE_SET HEADERS FILES lang_test.h)
|
target_sources(lang_test_cxx INTERFACE FILE_SET HEADERS FILES lang_test.h)
|
||||||
|
|
||||||
|
set_property(SOURCE error.h PROPERTY LANGUAGE C)
|
||||||
|
|
||||||
|
add_library(list STATIC lib.c)
|
||||||
|
target_sources(list INTERFACE
|
||||||
|
FILE_SET a TYPE HEADERS FILES a.h
|
||||||
|
FILE_SET c TYPE HEADERS FILES dir/c.h
|
||||||
|
FILE_SET error TYPE HEADERS FILES error.h
|
||||||
|
)
|
||||||
|
set_property(TARGET list PROPERTY INTERFACE_HEADER_SETS_TO_VERIFY "a;c")
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
1
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
^CMake Error in CMakeLists\.txt:
|
||||||
|
Property INTERFACE_HEADER_SETS_TO_VERIFY of target "nonexistent" contained
|
||||||
|
the following header sets that are nonexistent or not INTERFACE:
|
||||||
|
|
||||||
|
b
|
||||||
|
c
|
||||||
|
|
||||||
|
|
||||||
|
CMake Generate step failed\. Build files cannot be regenerated correctly\.$
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
enable_language(C)
|
||||||
|
|
||||||
|
add_library(nonexistent STATIC lib.c)
|
||||||
|
target_sources(nonexistent INTERFACE FILE_SET a TYPE HEADERS FILES a.h)
|
||||||
|
set_property(TARGET nonexistent PROPERTY INTERFACE_HEADER_SETS_TO_VERIFY "a;c;b")
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
#error "This file should not be included"
|
||||||
|
|
||||||
|
extern void error_h(void);
|
||||||
Reference in New Issue
Block a user