C++20 Modules
This project uses C++20 modules instead of traditional headers. Here’s what I learned getting them to work with CMake + Clang on MSYS2.
File convention
- Module interface files:
.cppmextension - Regular source files:
.cpp(useimportto consume modules)
Both live under src/.
CMake setup
CMake 3.28+ has native support for C++20 modules via FILE_SET CXX_MODULES:
cmake_minimum_required(VERSION 3.28)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
file(GLOB_RECURSE SOURCE_FILES CONFIGURE_DEPENDS "src/*.cpp")
file(GLOB_RECURSE MODULE_FILES CONFIGURE_DEPENDS "src/*.cppm")
add_executable(${PROJECT_NAME})
target_sources(${PROJECT_NAME} PRIVATE ${SOURCE_FILES})
target_sources(${PROJECT_NAME} PRIVATE FILE_SET CXX_MODULES FILES ${MODULE_FILES})
Ninja is required
MinGW Makefiles does not support C++20 modules. You must use Ninja:
cmake -B build -G Ninja \
-DCMAKE_C_COMPILER=clang \
-DCMAKE_CXX_COMPILER=clang++
If you try -G "MinGW Makefiles", CMake will fail to resolve module dependencies.
Writing a module
A .cppm file looks like this:
module;
// global module fragment — #include traditional headers here
#include <vulkan/vulkan.h>
#include <GLFW/glfw3.h>
export module app;
export class App {
public:
void Run();
private:
void InitWindow();
void InitVulkan();
void MainLoop();
void Cleanup();
};
Key points:
module;starts the global module fragment — put all#includedirectives hereexport module <name>;declares the module nameexportbefore declarations makes them visible to importers
Consuming a module
In a .cpp file:
import app;
int main() {
App app;
app.Run();
return 0;
}
Gotchas
-
Include order matters: All
#includelines must go in the global module fragment (betweenmodule;andexport module). Putting#includeafterexport moduleis a hard error. -
clangd support: clangd needs
compile_commands.json(generated by CMake withCMAKE_EXPORT_COMPILE_COMMANDS ON). Module support in clangd is still evolving — occasional false errors are normal. -
Build order: CMake + Ninja handle module dependency scanning automatically. No manual ordering needed.