I have a just running example here GitHub - ClausKlein/cmake-init-modules: C++20 Modules, CMake, And Shared Libraries
The main restrictions are: you must use the most resent tools and the Ninja generator!
# This property setting also needs to be consistent between the
# installed shared library and its consumer, otherwise most
# toolchains will once again reject the consumer's generated BMI.
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_EXTENSIONS ON)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
if(CMAKE_GENERATOR STREQUAL "Ninja")
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 20.0
)
set(ALGO_USE_MODULES TRUE)
string(APPEND CMAKE_CXX_MODULE_MAP_FLAG " -fmodules-reduced-bmi")
# see https://releases.llvm.org/20.0.0/projects/libcxx/docs/ReleaseNotes.html
# Always use libc++
if(APPLE)
execute_process(OUTPUT_VARIABLE LLVM_PREFIX COMMAND brew --prefix llvm@20 COMMAND_ECHO STDOUT)
string(STRIP ${LLVM_PREFIX} LLVM_PREFIX)
file(REAL_PATH ${LLVM_PREFIX} LLVM_ROOT)
set(LLVM_ROOT ${LLVM_ROOT} CACHE PATH "")
message(STATUS "LLVM_ROOT=${LLVM_ROOT}")
add_link_options(-L${LLVM_ROOT}/lib/c++)
include_directories(SYSTEM ${LLVM_ROOT}/include)
endif()
add_compile_options(-stdlib=libc++)
add_link_options(-stdlib=libc++)
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 15.0
)
set(ALGO_USE_MODULES TRUE)
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
set(ALGO_USE_MODULES TRUE)
endif()
endif()
# Tell CMake that we explicitly want `import std`.
# This will initialize the property on all targets declared after this to 1
message(STATUS "CMAKE_CXX_COMPILER_IMPORT_STD=${CMAKE_CXX_COMPILER_IMPORT_STD}")
if(23 IN_LIST CMAKE_CXX_COMPILER_IMPORT_STD)
set(CMAKE_CXX_MODULE_STD ON)
message(STATUS "CMAKE_CXX_MODULE_STD=${CMAKE_CXX_MODULE_STD}")
endif()
message(STATUS "ALGO_USE_MODULES=${ALGO_USE_MODULES}")
message(STATUS "CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES=${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES}")