Verifying header sets not supported for header-only interface libraries

Reading the docs for the VERIFY_INTERFACE_HEADER_SETS property (which seems to be the main place the feature is discussed), it appears that it can’t be used on interface libraries. That seems unexpected, since header-only libraries will often be implemented as an interface library, and these seem to be strong candidates for wanting to use this verification functionality. Was this intentional or an oversight? It seems odd to not support it.

@brad.king @kyle.edwards @bbrown105

I would say it’s an oversight.

My codebase doesn’t really use header-only libraries all that much, mostly because they don’t really add much value once you start packaging the library, shipping accurate package metadata alongside, etc.

I’m not opposed to it, though. Assuming there are no objections, I expect an issue is warranted.

Do the docs need work? Possibly we should have another issue to draft a new guide for this? Given the improvements in ergonomics and the developing C++ module support, I’m hoping FILE_SET becomes the new “modern CMake” way of describing a library to CMake.

I believe this is a relic from the time when it was VERIFY_HEADER_SETS rather than VERIFY_INTERFACE_HEADER_SETS. I will look at updating it.

The code and tests suggest that VERIFY_INTERFACE_HEADER_SETS do indeed support interface libraries, which I think I added during the review process but forgot to document. I will fix the documentation.

Please see cmake!7507.

Follow-up issue 23774 discusses a deficiency in the current behavior (as of 3.24.0-rc4).

The docs definitely need work. I found material on this feature to be quite fragmented, and there’s no clear place with a complete example for how to use it. I don’t know that I’d go so far as a separate guide though, that takes us down the path of many guides for individual features. I don’t think that’s a structure that best suits users.

… and a working example would help too!

if(PROJECT_IS_TOP_LEVEL)
  include(GNUInstallDirs) # for CMAKE_INSTALL_INCLUDEDIR
  set(CMAKE_VERIFY_INTERFACE_HEADER_SETS ON)
endif()

# ---- Declare library ----

file(GLOB headers "include/asio/*.hpp")

add_library(asio INTERFACE ${headers})
add_library(asio::asio ALIAS asio)

set_target_properties(asio PROPERTIES INTERFACE_HEADER_SETS_TO_VERIFY ${headers} )
# TODO(CK): this results in this cmake error!
#   following header sets that are nonexistent or not INTERFACE:
#
#   /Users/clausklein/Workspace/cpp/asio/asio/include/asio/any_io_executor.hpp
#

OK, this works:

# ---- Declare library ----

file(GLOB headers "include/asio/*.hpp")
file(GLOB_RECURSE implementation "include/asio/*/*.hpp" "include/asio/*.ipp")

add_library(asio INTERFACE ${implementation})
add_library(asio::asio ALIAS asio)

target_sources(asio INTERFACE FILE_SET HEADERS
                         BASE_DIRS include
                         FILES ${headers}
)

target_include_directories(
  asio # NO! SYSTEM # XXX ${warning_guard}
  INTERFACE "$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>" #
            "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
)

target_compile_definitions(asio INTERFACE ASIO_NO_DEPRECATED)
target_compile_features(asio INTERFACE cxx_std_17)

I use cmake 3.24.1 and tried VERIFY_INTERFACE_HEADER_SETS with a header-only library. Because of the issues I observed I found this discussion. I think the support is still incomplete.

target_compile_features(asio INTERFACE cxx_std_17)
Is it really using -std=c++17 when compiling the verification files?
I tried the same with cxx_std_20 and building <target_name>_verify_interface_header_sets failed because it did not pass -std=c++20 and my headers use features that are not available in older standards. The only workaround was to set CMAKE_CXX_STANDARD.
Setting the CXX_STANDARD target property on an INTERFACE library is not allowed and trying to set it on <target_name>_verify_interface_header_sets also resulted in an error.

@Jan_Krause If you can provide a minimal example project which demonstrates the problem you describe, please open a new issue in the issue tracker and attach that example project.

I can’t see any problem with my project https://github.com/ClausKlein/asio/pull/3

bash-3.2$ git status
     # On branch feature/use-cmake-init
   cd asio/asio
   cmake -G Ninja -S . -B build
   cd build/
   ninja -nv all_verify_interface_header_sets 

bash-3.2$ ninja -nv all_verify_interface_header_sets | tail 2>&1       
[246/255] /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ -DASIO_NO_DEPRECATED -I/Users/clausklein/Workspace/cpp/asio/asio/include -x c++  -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.3.sdk -std=gnu++17 -MD -MT CMakeFiles/asio_verify_interface_header_sets.dir/asio_verify_interface_header_sets/asio/ts/timer.hpp.cxx.o -MF CMakeFiles/asio_verify_interface_header_sets.dir/asio_verify_interface_header_sets/asio/ts/timer.hpp.cxx.o.d -o CMakeFiles/asio_verify_interface_header_sets.dir/asio_verify_interface_header_sets/asio/ts/timer.hpp.cxx.o -c /Users/clausklein/Workspace/cpp/asio/asio/build/asio_verify_interface_header_sets/asio/ts/timer.hpp.cxx
[247/255] /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ -DASIO_NO_DEPRECATED -I/Users/clausklein/Workspace/cpp/asio/asio/include -x c++  -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.3.sdk -std=gnu++17 -MD -MT CMakeFiles/asio_verify_interface_header_sets.dir/asio_verify_interface_header_sets/asio/windows/basic_object_handle.hpp.cxx.o -MF CMakeFiles/asio_verify_interface_header_sets.dir/asio_verify_interface_header_sets/asio/windows/basic_object_handle.hpp.cxx.o.d -o CMakeFiles/asio_verify_interface_header_sets.dir/asio_verify_interface_header_sets/asio/windows/basic_object_handle.hpp.cxx.o -c /Users/clausklein/Workspace/cpp/asio/asio/build/asio_verify_interface_header_sets/asio/windows/basic_object_handle.hpp.cxx
[248/255] /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ -DASIO_NO_DEPRECATED -I/Users/clausklein/Workspace/cpp/asio/asio/include -x c++  -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.3.sdk -std=gnu++17 -MD -MT CMakeFiles/asio_verify_interface_header_sets.dir/asio_verify_interface_header_sets/asio/windows/basic_overlapped_handle.hpp.cxx.o -MF CMakeFiles/asio_verify_interface_header_sets.dir/asio_verify_interface_header_sets/asio/windows/basic_overlapped_handle.hpp.cxx.o.d -o CMakeFiles/asio_verify_interface_header_sets.dir/asio_verify_interface_header_sets/asio/windows/basic_overlapped_handle.hpp.cxx.o -c /Users/clausklein/Workspace/cpp/asio/asio/build/asio_verify_interface_header_sets/asio/windows/basic_overlapped_handle.hpp.cxx
[249/255] /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ -DASIO_NO_DEPRECATED -I/Users/clausklein/Workspace/cpp/asio/asio/include -x c++  -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.3.sdk -std=gnu++17 -MD -MT CMakeFiles/asio_verify_interface_header_sets.dir/asio_verify_interface_header_sets/asio/windows/basic_random_access_handle.hpp.cxx.o -MF CMakeFiles/asio_verify_interface_header_sets.dir/asio_verify_interface_header_sets/asio/windows/basic_random_access_handle.hpp.cxx.o.d -o CMakeFiles/asio_verify_interface_header_sets.dir/asio_verify_interface_header_sets/asio/windows/basic_random_access_handle.hpp.cxx.o -c /Users/clausklein/Workspace/cpp/asio/asio/build/asio_verify_interface_header_sets/asio/windows/basic_random_access_handle.hpp.cxx
[250/255] /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ -DASIO_NO_DEPRECATED -I/Users/clausklein/Workspace/cpp/asio/asio/include -x c++  -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.3.sdk -std=gnu++17 -MD -MT CMakeFiles/asio_verify_interface_header_sets.dir/asio_verify_interface_header_sets/asio/windows/basic_stream_handle.hpp.cxx.o -MF CMakeFiles/asio_verify_interface_header_sets.dir/asio_verify_interface_header_sets/asio/windows/basic_stream_handle.hpp.cxx.o.d -o CMakeFiles/asio_verify_interface_header_sets.dir/asio_verify_interface_header_sets/asio/windows/basic_stream_handle.hpp.cxx.o -c /Users/clausklein/Workspace/cpp/asio/asio/build/asio_verify_interface_header_sets/asio/windows/basic_stream_handle.hpp.cxx
[251/255] /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ -DASIO_NO_DEPRECATED -I/Users/clausklein/Workspace/cpp/asio/asio/include -x c++  -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.3.sdk -std=gnu++17 -MD -MT CMakeFiles/asio_verify_interface_header_sets.dir/asio_verify_interface_header_sets/asio/windows/object_handle.hpp.cxx.o -MF CMakeFiles/asio_verify_interface_header_sets.dir/asio_verify_interface_header_sets/asio/windows/object_handle.hpp.cxx.o.d -o CMakeFiles/asio_verify_interface_header_sets.dir/asio_verify_interface_header_sets/asio/windows/object_handle.hpp.cxx.o -c /Users/clausklein/Workspace/cpp/asio/asio/build/asio_verify_interface_header_sets/asio/windows/object_handle.hpp.cxx
[252/255] /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ -DASIO_NO_DEPRECATED -I/Users/clausklein/Workspace/cpp/asio/asio/include -x c++  -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.3.sdk -std=gnu++17 -MD -MT CMakeFiles/asio_verify_interface_header_sets.dir/asio_verify_interface_header_sets/asio/windows/overlapped_handle.hpp.cxx.o -MF CMakeFiles/asio_verify_interface_header_sets.dir/asio_verify_interface_header_sets/asio/windows/overlapped_handle.hpp.cxx.o.d -o CMakeFiles/asio_verify_interface_header_sets.dir/asio_verify_interface_header_sets/asio/windows/overlapped_handle.hpp.cxx.o -c /Users/clausklein/Workspace/cpp/asio/asio/build/asio_verify_interface_header_sets/asio/windows/overlapped_handle.hpp.cxx
[253/255] /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ -DASIO_NO_DEPRECATED -I/Users/clausklein/Workspace/cpp/asio/asio/include -x c++  -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.3.sdk -std=gnu++17 -MD -MT CMakeFiles/asio_verify_interface_header_sets.dir/asio_verify_interface_header_sets/asio/windows/overlapped_ptr.hpp.cxx.o -MF CMakeFiles/asio_verify_interface_header_sets.dir/asio_verify_interface_header_sets/asio/windows/overlapped_ptr.hpp.cxx.o.d -o CMakeFiles/asio_verify_interface_header_sets.dir/asio_verify_interface_header_sets/asio/windows/overlapped_ptr.hpp.cxx.o -c /Users/clausklein/Workspace/cpp/asio/asio/build/asio_verify_interface_header_sets/asio/windows/overlapped_ptr.hpp.cxx
[254/255] /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ -DASIO_NO_DEPRECATED -I/Users/clausklein/Workspace/cpp/asio/asio/include -x c++  -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.3.sdk -std=gnu++17 -MD -MT CMakeFiles/asio_verify_interface_header_sets.dir/asio_verify_interface_header_sets/asio/windows/random_access_handle.hpp.cxx.o -MF CMakeFiles/asio_verify_interface_header_sets.dir/asio_verify_interface_header_sets/asio/windows/random_access_handle.hpp.cxx.o.d -o CMakeFiles/asio_verify_interface_header_sets.dir/asio_verify_interface_header_sets/asio/windows/random_access_handle.hpp.cxx.o -c /Users/clausklein/Workspace/cpp/asio/asio/build/asio_verify_interface_header_sets/asio/windows/random_access_handle.hpp.cxx
[255/255] /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ -DASIO_NO_DEPRECATED -I/Users/clausklein/Workspace/cpp/asio/asio/include -x c++  -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.3.sdk -std=gnu++17 -MD -MT CMakeFiles/asio_verify_interface_header_sets.dir/asio_verify_interface_header_sets/asio/windows/stream_handle.hpp.cxx.o -MF CMakeFiles/asio_verify_interface_header_sets.dir/asio_verify_interface_header_sets/asio/windows/stream_handle.hpp.cxx.o.d -o CMakeFiles/asio_verify_interface_header_sets.dir/asio_verify_interface_header_sets/asio/windows/stream_handle.hpp.cxx.o -c /Users/clausklein/Workspace/cpp/asio/asio/build/asio_verify_interface_header_sets/asio/windows/stream_handle.hpp.cxx
bash-3.2$ 

@craig.scott @ClausKlein
When testing a minimal example project everything worked as expected / documented, so no issue in CMake.
The original issue that I had happened in a zephyr project. They abuse CMake quite a bit and a lot of things do not work as they should.
https://github.com/zephyrproject-rtos/zephyr/issues/31193