Header-only libraries and C++20 modules

When installing a header-only library with a C++20 module interface, with something like:

        FILE_SET CXX_MODULES FILES mylib.cppm
        FILE_SET HEADERS FILES mylib.h
install(TARGETS mylib
    EXPORT mylib-targets
        DESTINATION lib/cmake/mylib/module

CMake will build and install a static or shared library, which seems just unnecessary, as the modules will be built again by the consumer. I’ve tried building an INTERFACE library, instead, but target_sources refuses to add a CXX_MODULES fileset with INTERFACE scope.

Is there a way to do this cleanly?


Modules have module initializer symbols that need to be provided once to be reliable (the ODR applies here). Providing it in a library is the reliable way to do this.

The BMIs will be built again, but not object files.

Sorry if it’s a dumb question, but what is a “module initializer symbol”? I can’t find any reference to the term in clang/MSVC docs or in the standard.

The new rule is that all global initializers required by module A will be called before those of module B if B contains import A. This is implemented by making a symbol for export module M; that is called for any import M; statement.