Target_compile_features must not used?

from beman_standard

[cmake.passive_targets]

Requirement: External targets must not modify compilation flags of dependents.

Therefore, target_compile_features (e.g., cxx_std_20) must not be used because it modifies the compilation environment of dependent targets. Compiler support for required features should be determined at CMake configuration time using check_cxx_source_compiles.

Furthermore, target_compile_definitions with PUBLIC or INTERFACE visibility must not be used, as these definitions are also propagated to dependent targets. Preprocessor definitions intended for external use should be generated into a config.hpp file at CMake configuration time. This config.hpp should then be included by public headers.

This seems to be a problem if working with CXX_MODULES!

i.e: from boost::any

# -----------------------------------------------------------------------------
# Boost.Any CMake
# Handles: no modules, modules, modules + import std;
# -----------------------------------------------------------------------------
# Copyright 2019 Mike Dev
# Distributed under the Boost Software License, Version 1.0.
# -----------------------------------------------------------------------------

cmake_minimum_required(VERSION 3.21...4.2)

project(boost_any VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX)

if(PROJECT_IS_TOP_LEVEL)
    find_package(Boost 1.90.0 CONFIG)
endif()

# -----------------------------------------------------------------------------
# User option: enable C++ modules, still experimental!
# -----------------------------------------------------------------------------
option(BOOST_USE_MODULES "Build Boost using C++ modules" OFF)

# -----------------------------------------------------------------------------
# Determine target type and sources
# -----------------------------------------------------------------------------
if(BOOST_USE_MODULES)

    # Ensure CMAKE_CXX_STANDARD is set for module detection
    if(NOT DEFINED CMAKE_CXX_STANDARD)
        set(CMAKE_CXX_STANDARD 20)
    endif()

    add_library(boost_any)

    target_sources(
        boost_any
        PUBLIC
            FILE_SET modules_public
                TYPE CXX_MODULES
                FILES modules/boost_any.cppm
    )

    # Require C++20 for modules
    target_compile_features(boost_any PUBLIC cxx_std_20)

    # Define macro indicating modules usage
    target_compile_definitions(boost_any PUBLIC BOOST_USE_MODULES)

    # Check if import std; is available for the current standard
    if(${CMAKE_CXX_STANDARD} IN_LIST CMAKE_CXX_COMPILER_IMPORT_STD)
        target_compile_definitions(boost_any PRIVATE BOOST_ANY_USE_STD_MODULE)
        message(STATUS "Boost.Any: Using `import std;`")
    else()
        message(WARNING "Boost.Any: `import std;` is not available for C++${CMAKE_CXX_STANDARD}")
    endif()

    set(__scope PUBLIC)

else()

    # Modules disabled -> INTERFACE library
    add_library(boost_any INTERFACE)

    # Verify interface headers only at top level
    if(PROJECT_IS_TOP_LEVEL)
        set(CMAKE_VERIFY_INTERFACE_HEADER_SETS ON)
    endif()

    set(__scope INTERFACE)

endif()

# -----------------------------------------------------------------------------
# Include headers
# -----------------------------------------------------------------------------
if(CMAKE_VERSION VERSION_LESS 3.23)
    target_include_directories(boost_any ${__scope} include)
else()
    target_sources(
        boost_any
        ${__scope}
        FILE_SET headers_public
        TYPE HEADERS
        BASE_DIRS include
        FILES
            include/boost/any/bad_any_cast.hpp
            include/boost/any/basic_any.hpp
            include/boost/any/fwd.hpp
            include/boost/any/unique_any.hpp
            include/boost/any/detail/config.hpp
            include/boost/any/detail/placeholder.hpp
    )

    # If modules are disabled, require C++17 for headers
    if(NOT BOOST_USE_MODULES)
        target_compile_features(boost_any ${__scope} cxx_std_17)
    endif()
endif()

# -----------------------------------------------------------------------------
# Link dependencies
# -----------------------------------------------------------------------------
if(PROJECT_IS_TOP_LEVEL)
    target_link_libraries(boost_any ${__scope} Boost::headers)
else()
    target_link_libraries(boost_any ${__scope}
        Boost::config
        Boost::throw_exception
        Boost::type_index
    )
endif()

# Alias for convenient import
add_library(Boost::any ALIAS boost_any)

# -----------------------------------------------------------------------------
# Testing
# -----------------------------------------------------------------------------
if(BUILD_TESTING)
    add_subdirectory(test)
endif()


And I wondering, the error occurs later while importing the installed package:

bash-5.3$ ctest --rerun-failed --output-on-failure --verbose
UpdateCTestConfiguration  from :/Users/clausklein/Workspace/cpp/beman-project/exemplar/build/gcc-release/DartConfiguration.tcl
Test project /Users/clausklein/Workspace/cpp/beman-project/exemplar/build/gcc-release
Constructing a list of tests
Done constructing a list of tests
Updating test list for fixtures
Added 0 tests to meet fixture requirements
Checking test dependency graph...
Checking test dependency graph end
test 6
    Start 6: find-package-test

6: Test command: /Users/clausklein/.direnv/python-3.14/lib/python3.14/site-packages/cmake/data/bin/ctest "--output-on-failure" "-C" "RelWithDebInfo" "--build-and-test" "/Users/clausklein/Workspace/cpp/beman-project/exemplar/examples" "/Users/clausklein/Workspace/cpp/beman-project/exemplar/build/gcc-release/tests/beman/exemplar/find-package-test" "--build-generator" "Ninja" "--build-makeprogram" "/Users/clausklein/.local/bin/ninja" "--build-options" "-DCMAKE_CXX_COMPILER=/usr/local/bin/g++" "-DCMAKE_CXX_STANDARD=20" "-DCMAKE_CXX_EXTENSIONS=TRUE" "-DCMAKE_CXX_MODULE_STD=" "-DCMAKE_CXX_SCAN_FOR_MODULES=TRUE" "-DCMAKE_BUILD_TYPE=RelWithDebInfo" "-DCMAKE_PREFIX_PATH=/Users/clausklein/Workspace/cpp/beman-project/exemplar/build/gcc-release/stagedir"
6: Working Directory: /Users/clausklein/Workspace/cpp/beman-project/exemplar/build/gcc-release/tests/beman/exemplar
6: Test timeout computed to be: 10000000
6: Internal cmake changing into directory: /Users/clausklein/Workspace/cpp/beman-project/exemplar/build/gcc-release/tests/beman/exemplar/find-package-test
6: ======== CMake output     ======
6: Examples to be built: identity_direct_usage;identity_module_usage;identity_as_default_projection
6: Configuring done (0.1s)
6: CMake Error in CMakeLists.txt:
6:   The target named "beman__exemplar@synth_a0ccecfbf4b4" has C++ sources that
6:   use modules, but does not include "cxx_std_20" (or newer) among its
6:   `target_compile_features`; no C++ standard found.
6: 
6: 
6: Generating done (0.0s)
6: CMake Generate step failed.  Build files cannot be regenerated correctly.
6: ======== End CMake output ======
6: Error: cmake execution failed
1/1 Test #6: find-package-test ................***Failed    0.14 sec
Internal cmake changing into directory: /Users/clausklein/Workspace/cpp/beman-project/exemplar/build/gcc-release/tests/beman/exemplar/find-package-test
======== CMake output     ======
Examples to be built: identity_direct_usage;identity_module_usage;identity_as_default_projection
Configuring done (0.1s)
CMake Error in CMakeLists.txt:
  The target named "beman__exemplar@synth_a0ccecfbf4b4" has C++ sources that
  use modules, but does not include "cxx_std_20" (or newer) among its
  `target_compile_features`; no C++ standard found.


Generating done (0.0s)
CMake Generate step failed.  Build files cannot be regenerated correctly.
======== End CMake output ======
Error: cmake execution failed


0% tests passed, 1 tests failed out of 1

Total Test time (real) =   0.14 sec

The following tests FAILED:
	  6 - find-package-test (Failed)
Errors while running CTest
bash-5.3$

A working prototype my be found