diff --git a/Help/prop_tgt/VERIFY_INTERFACE_HEADER_SETS.rst b/Help/prop_tgt/VERIFY_INTERFACE_HEADER_SETS.rst index 0c7c70809b..59cd1048cd 100644 --- a/Help/prop_tgt/VERIFY_INTERFACE_HEADER_SETS.rst +++ b/Help/prop_tgt/VERIFY_INTERFACE_HEADER_SETS.rst @@ -10,13 +10,20 @@ VERIFY_INTERFACE_HEADER_SETS Used to verify that all headers in a target's ``PUBLIC`` and ``INTERFACE`` header sets can be included on their own. +.. versionchanged:: 4.4 + Previously, the verification target was only created when the target had + at least one matching header. Now it is always created when the property + is enabled. + When this property is set to true, and the target is an object library, static library, shared library, interface library, or executable (subject to policy -:policy:`CMP0209`) and the target has one or more ``PUBLIC`` or ``INTERFACE`` -header sets, an object library target named +:policy:`CMP0209`), an object library target named ``_verify_interface_header_sets`` is created. This verification -target has one source file per header in the ``PUBLIC`` and ``INTERFACE`` -header sets. Each source file only includes its associated header file. +target has one source file per header in the target's ``PUBLIC`` and +``INTERFACE`` header sets. Each source file only includes its associated +header file. If the target has no matching header sets, a utility target is +created instead so that the target name always exists for build system +dependencies. The verification target links against the original target to get all of its usage requirements. diff --git a/Help/prop_tgt/VERIFY_PRIVATE_HEADER_SETS.rst b/Help/prop_tgt/VERIFY_PRIVATE_HEADER_SETS.rst index c7f578ee42..889a2074e4 100644 --- a/Help/prop_tgt/VERIFY_PRIVATE_HEADER_SETS.rst +++ b/Help/prop_tgt/VERIFY_PRIVATE_HEADER_SETS.rst @@ -10,13 +10,19 @@ VERIFY_PRIVATE_HEADER_SETS Used to verify that all headers in a target's ``PUBLIC`` and ``PRIVATE`` header sets can be included on their own. +.. versionchanged:: 4.4 + Previously, the verification target was only created when the target had + at least one matching header. Now it is always created when the property + is enabled. + When this property is set to true, and the target is an object library, static -library, shared library, module library, interface library, or executable, and -the target has one or more ``PUBLIC`` or ``PRIVATE`` header sets, an object -library target named ``_verify_private_header_sets`` is created. -This verification target has one source file per header in the ``PUBLIC`` and -``PRIVATE`` header sets. Each source file only includes its associated header -file. +library, shared library, module library, interface library, or executable, an +object library target named ``_verify_private_header_sets`` is +created. This verification target has one source file per header in the +target's ``PUBLIC`` and ``PRIVATE`` header sets. Each source file only +includes its associated header file. If the target has no matching header +sets, a utility target is created instead so that the target name always +exists for build system dependencies. Properties affecting compilation are copied from the original target to the verification target so that the headers will be interpreted the same way by diff --git a/Help/prop_tgt/include/VERIFY_XXX_HEADER_SETS.rst b/Help/prop_tgt/include/VERIFY_XXX_HEADER_SETS.rst index 71e34cd4c7..b8e8d07ec3 100644 --- a/Help/prop_tgt/include/VERIFY_XXX_HEADER_SETS.rst +++ b/Help/prop_tgt/include/VERIFY_XXX_HEADER_SETS.rst @@ -26,11 +26,10 @@ conditions. The compiler flags used for private and interface contexts can be different, leading to the compiler interpreting the contents of the header differently. -If any |xxx| file set verification targets are created, a top-level target -called |THIS_ALL_TARGET| is created which depends on all |xxx| verification -targets. Another target called ``all_verify_header_sets`` is also created -which depends on |THIS_ALL_TARGET|, and on |COMPLEMENTARY_ALL_TARGET| if it -exists (see |COMPLEMENTARY_PROPERTY|). +A top-level target called |THIS_ALL_TARGET| is created which depends on all +|xxx| verification targets. Another target called ``all_verify_header_sets`` +is also created which depends on |THIS_ALL_TARGET|, and on +|COMPLEMENTARY_ALL_TARGET| if it exists (see |COMPLEMENTARY_PROPERTY|). This property is initialized by the value of the |INIT_VARIABLE| variable if it is set when a target is created. diff --git a/Help/release/dev/always-create-all-verify-targets.rst b/Help/release/dev/always-create-all-verify-targets.rst new file mode 100644 index 0000000000..a634265094 --- /dev/null +++ b/Help/release/dev/always-create-all-verify-targets.rst @@ -0,0 +1,9 @@ +always-create-all-verify-targets +--------------------------------- + +* The :prop_tgt:`VERIFY_INTERFACE_HEADER_SETS` and + :prop_tgt:`VERIFY_PRIVATE_HEADER_SETS` target properties now always + create the per-target verification target and the aggregate + ``all_verify_interface_header_sets``, ``all_verify_private_header_sets``, + and ``all_verify_header_sets`` targets when the property is enabled, + even if the target has no matching header sets. diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 327fef8d64..79a2aae522 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -5925,7 +5925,15 @@ bool cmGeneratorTarget::AddHeaderSetVerification() } } - if (!stubSources.empty()) { + if (stubSources.empty()) { + // No headers to verify. Create a utility target so the target + // name always exists (e.g. for build system dependencies) without + // needing a placeholder source. This avoids warnings from tools + // like Xcode's libtool about empty static libraries. + verifyTarget = + this->Makefile->AddNewUtilityTarget(verifyTargetName, true); + } else { + // Create an OBJECT library to compile the verification stubs. { cmMakefile::PolicyPushPop polScope(this->Makefile); this->Makefile->SetPolicy(cmPolicies::CMP0119, cmPolicies::NEW); diff --git a/Tests/RunCMake/VerifyHeaderSets/RunCMakeTest.cmake b/Tests/RunCMake/VerifyHeaderSets/RunCMakeTest.cmake index 26fc8cb9b1..e9a5747825 100644 --- a/Tests/RunCMake/VerifyHeaderSets/RunCMakeTest.cmake +++ b/Tests/RunCMake/VerifyHeaderSets/RunCMakeTest.cmake @@ -125,3 +125,21 @@ run_cmake_build(AllVerifyPrivateHeaderSets private all) set(RunCMake_TEST_OPTIONS -DCMAKE_VERIFY_PRIVATE_HEADER_SETS=ON) run_cmake(VerifyPrivateHeaderSetsNonexistent) unset(RunCMake_TEST_OPTIONS) + +# Test that verify targets are always created even with no headers +if(NOT RunCMake_GENERATOR_IS_MULTI_CONFIG) + set(RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Debug) +endif() +run_cmake(VerifyEmptyHeaderSets) +unset(RunCMake_TEST_OPTIONS) + +run_cmake_build(VerifyEmptyHeaderSets interface empty_iface) +run_cmake_build(VerifyEmptyHeaderSets private empty_priv) +run_cmake_build(VerifyEmptyHeaderSets interface all) +run_cmake_build(VerifyEmptyHeaderSets private all) + +set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/VerifyEmptyHeaderSets-build) +set(RunCMake_TEST_NO_CLEAN 1) +run_cmake_command(VerifyEmptyHeaderSets-all_verify_header_sets-Debug-build + ${CMAKE_COMMAND} --build . --config Debug --target all_verify_header_sets +) diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyEmptyHeaderSets.cmake b/Tests/RunCMake/VerifyHeaderSets/VerifyEmptyHeaderSets.cmake new file mode 100644 index 0000000000..d1aeacacb8 --- /dev/null +++ b/Tests/RunCMake/VerifyHeaderSets/VerifyEmptyHeaderSets.cmake @@ -0,0 +1,9 @@ +enable_language(C) + +# Target with VERIFY_INTERFACE_HEADER_SETS ON but no interface file sets +add_library(empty_iface STATIC lib.c) +set_property(TARGET empty_iface PROPERTY VERIFY_INTERFACE_HEADER_SETS ON) + +# Target with VERIFY_PRIVATE_HEADER_SETS ON but no private file sets +add_library(empty_priv STATIC lib.c) +set_property(TARGET empty_priv PROPERTY VERIFY_PRIVATE_HEADER_SETS ON) diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyInterfaceHeaderSets-none-Debug-build-result.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyInterfaceHeaderSets-none-Debug-build-result.txt deleted file mode 100644 index d197c913c2..0000000000 --- a/Tests/RunCMake/VerifyHeaderSets/VerifyInterfaceHeaderSets-none-Debug-build-result.txt +++ /dev/null @@ -1 +0,0 @@ -[^0] diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyInterfaceHeaderSets-none-Debug-build-stderr.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyInterfaceHeaderSets-none-Debug-build-stderr.txt deleted file mode 100644 index 8d98f9debd..0000000000 --- a/Tests/RunCMake/VerifyHeaderSets/VerifyInterfaceHeaderSets-none-Debug-build-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -.* diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyInterfaceHeaderSets-private-Debug-build-result.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyInterfaceHeaderSets-private-Debug-build-result.txt deleted file mode 100644 index d197c913c2..0000000000 --- a/Tests/RunCMake/VerifyHeaderSets/VerifyInterfaceHeaderSets-private-Debug-build-result.txt +++ /dev/null @@ -1 +0,0 @@ -[^0] diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyInterfaceHeaderSets-private-Debug-build-stderr.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyInterfaceHeaderSets-private-Debug-build-stderr.txt deleted file mode 100644 index 8d98f9debd..0000000000 --- a/Tests/RunCMake/VerifyHeaderSets/VerifyInterfaceHeaderSets-private-Debug-build-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -.* diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyPrivateHeaderSets-iface_lang_cxx-Debug-build-result.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyPrivateHeaderSets-iface_lang_cxx-Debug-build-result.txt deleted file mode 100644 index d197c913c2..0000000000 --- a/Tests/RunCMake/VerifyHeaderSets/VerifyPrivateHeaderSets-iface_lang_cxx-Debug-build-result.txt +++ /dev/null @@ -1 +0,0 @@ -[^0] diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyPrivateHeaderSets-iface_lang_cxx-Debug-build-stderr.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyPrivateHeaderSets-iface_lang_cxx-Debug-build-stderr.txt deleted file mode 100644 index 8d98f9debd..0000000000 --- a/Tests/RunCMake/VerifyHeaderSets/VerifyPrivateHeaderSets-iface_lang_cxx-Debug-build-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -.* diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyPrivateHeaderSets-interface-Debug-build-result.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyPrivateHeaderSets-interface-Debug-build-result.txt deleted file mode 100644 index d197c913c2..0000000000 --- a/Tests/RunCMake/VerifyHeaderSets/VerifyPrivateHeaderSets-interface-Debug-build-result.txt +++ /dev/null @@ -1 +0,0 @@ -[^0] diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyPrivateHeaderSets-interface-Debug-build-stderr.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyPrivateHeaderSets-interface-Debug-build-stderr.txt deleted file mode 100644 index 8d98f9debd..0000000000 --- a/Tests/RunCMake/VerifyHeaderSets/VerifyPrivateHeaderSets-interface-Debug-build-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -.* diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyPrivateHeaderSets-none-Debug-build-result.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyPrivateHeaderSets-none-Debug-build-result.txt deleted file mode 100644 index d197c913c2..0000000000 --- a/Tests/RunCMake/VerifyHeaderSets/VerifyPrivateHeaderSets-none-Debug-build-result.txt +++ /dev/null @@ -1 +0,0 @@ -[^0] diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyPrivateHeaderSets-none-Debug-build-stderr.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyPrivateHeaderSets-none-Debug-build-stderr.txt deleted file mode 100644 index 8d98f9debd..0000000000 --- a/Tests/RunCMake/VerifyHeaderSets/VerifyPrivateHeaderSets-none-Debug-build-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -.*