From aadaac7f6dff05c90b61079d70e304d157ea9bab Mon Sep 17 00:00:00 2001 From: Kyle Edwards Date: Wed, 25 May 2022 14:33:38 -0400 Subject: 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 --- Help/manual/cmake-properties.7.rst | 1 + Help/prop_tgt/INTERFACE_HEADER_SETS_TO_VERIFY.rst | 13 ++++++++++ Help/prop_tgt/VERIFY_INTERFACE_HEADER_SETS.rst | 3 +++ Help/release/dev/verify-interface-header-sets.rst | 3 +++ Source/cmGeneratorTarget.cxx | 28 ++++++++++++++++++---- Tests/RunCMake/VerifyHeaderSets/RunCMakeTest.cmake | 5 ++++ .../VerifyHeaderSets/VerifyHeaderSets.cmake | 10 ++++++++ .../VerifyHeaderSetsNonexistent-result.txt | 1 + .../VerifyHeaderSetsNonexistent-stderr.txt | 9 +++++++ .../VerifyHeaderSetsNonexistent.cmake | 5 ++++ Tests/RunCMake/VerifyHeaderSets/error.h | 3 +++ 11 files changed, 76 insertions(+), 5 deletions(-) create mode 100644 Help/prop_tgt/INTERFACE_HEADER_SETS_TO_VERIFY.rst create mode 100644 Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSetsNonexistent-result.txt create mode 100644 Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSetsNonexistent-stderr.txt create mode 100644 Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSetsNonexistent.cmake create mode 100644 Tests/RunCMake/VerifyHeaderSets/error.h diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst index 7935ca3..d88322c 100644 --- a/Help/manual/cmake-properties.7.rst +++ b/Help/manual/cmake-properties.7.rst @@ -263,6 +263,7 @@ Properties on Targets /prop_tgt/INTERFACE_COMPILE_FEATURES /prop_tgt/INTERFACE_COMPILE_OPTIONS /prop_tgt/INTERFACE_HEADER_SETS + /prop_tgt/INTERFACE_HEADER_SETS_TO_VERIFY /prop_tgt/INTERFACE_INCLUDE_DIRECTORIES /prop_tgt/INTERFACE_LINK_DEPENDS /prop_tgt/INTERFACE_LINK_DIRECTORIES diff --git a/Help/prop_tgt/INTERFACE_HEADER_SETS_TO_VERIFY.rst b/Help/prop_tgt/INTERFACE_HEADER_SETS_TO_VERIFY.rst new file mode 100644 index 0000000..b0d63f3 --- /dev/null +++ b/Help/prop_tgt/INTERFACE_HEADER_SETS_TO_VERIFY.rst @@ -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``.) diff --git a/Help/prop_tgt/VERIFY_INTERFACE_HEADER_SETS.rst b/Help/prop_tgt/VERIFY_INTERFACE_HEADER_SETS.rst index d8045c6..30c02f5 100644 --- a/Help/prop_tgt/VERIFY_INTERFACE_HEADER_SETS.rst +++ b/Help/prop_tgt/VERIFY_INTERFACE_HEADER_SETS.rst @@ -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, 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`. diff --git a/Help/release/dev/verify-interface-header-sets.rst b/Help/release/dev/verify-interface-header-sets.rst index fcccb62..9e6856d 100644 --- a/Help/release/dev/verify-interface-header-sets.rst +++ b/Help/release/dev/verify-interface-header-sets.rst @@ -7,3 +7,6 @@ verify-interface-header-sets * A new :variable:`CMAKE_VERIFY_INTERFACE_HEADER_SETS` variable was added, which is used to initialize the :prop_tgt:`VERIFY_INTERFACE_HEADER_SETS` 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`. diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 8ed7f10..ff148a2 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -8525,19 +8525,37 @@ bool cmGeneratorTarget::AddHeaderSetVerification() return true; } + auto verifyValue = this->GetProperty("INTERFACE_HEADER_SETS_TO_VERIFY"); + const bool all = verifyValue.IsEmpty(); + std::set verifySet; + if (!all) { + auto verifyList = cmExpandedList(verifyValue); + verifySet.insert(verifyList.begin(), verifyList.end()); + } + cmTarget* verifyTarget = nullptr; auto interfaceFileSetEntries = this->Target->GetInterfaceHeaderSetsEntries(); std::set fileSets; - auto const addFileSets = [&fileSets, this](const cmBTStringRange& entries) { - for (auto const& entry : entries) { - for (auto const& name : cmExpandedList(entry.Value)) { + for (auto const& entry : interfaceFileSetEntries) { + for (auto const& name : cmExpandedList(entry.Value)) { + if (all || verifySet.count(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> languages; for (auto* fileSet : fileSets) { diff --git a/Tests/RunCMake/VerifyHeaderSets/RunCMakeTest.cmake b/Tests/RunCMake/VerifyHeaderSets/RunCMakeTest.cmake index edc655b..f022a43 100644 --- a/Tests/RunCMake/VerifyHeaderSets/RunCMakeTest.cmake +++ b/Tests/RunCMake/VerifyHeaderSets/RunCMakeTest.cmake @@ -40,3 +40,8 @@ endif() 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 list_verify_interface_header_sets) + +set(RunCMake_TEST_OPTIONS -DCMAKE_VERIFY_INTERFACE_HEADER_SETS=ON) +run_cmake(VerifyHeaderSetsNonexistent) +unset(RunCMake_TEST_OPTIONS) diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets.cmake b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets.cmake index 24298df..82ed935 100644 --- a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets.cmake +++ b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets.cmake @@ -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) target_compile_definitions(lang_test_cxx INTERFACE EXPECT_CXX) 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") diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSetsNonexistent-result.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSetsNonexistent-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSetsNonexistent-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSetsNonexistent-stderr.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSetsNonexistent-stderr.txt new file mode 100644 index 0000000..76c2f94 --- /dev/null +++ b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSetsNonexistent-stderr.txt @@ -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\.$ diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSetsNonexistent.cmake b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSetsNonexistent.cmake new file mode 100644 index 0000000..b269b73 --- /dev/null +++ b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSetsNonexistent.cmake @@ -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") diff --git a/Tests/RunCMake/VerifyHeaderSets/error.h b/Tests/RunCMake/VerifyHeaderSets/error.h new file mode 100644 index 0000000..cbba5ae --- /dev/null +++ b/Tests/RunCMake/VerifyHeaderSets/error.h @@ -0,0 +1,3 @@ +#error "This file should not be included" + +extern void error_h(void); -- cgit v0.12