A feature introduced in C++20 is modules. With C++23, the standard library is now supposed to provide an std
module that can be used instead of all the #include
s that we are used to. This allows code like the following:
import std;
int main() {
std::print("Hello world!\n");
}
While (partial) support for modules is included in GCC since version 11 and Clang since version 8, support for the std
module is currently still lacking in libstdc++ and only included in libc++ since version 17 (see https://en.cppreference.com/w/cpp/compiler_support). But since I have Clang 18 and libc++ installed, I wanted to give it a try.
Simply trying to compile above code, unfortunately leads to an error:
% clang++ -std=c++23 -stdlib=libc++ -o test test.cpp
test.cpp:1:8: fatal error: module 'std' not found
1 | import std;
| ~~~~~~~^~~
1 error generated.
One might be tempted to try Clang’s -fmodules
flag but in fact this does not refer to modules as defined by the C++ standard and using it actually causes more issues:
% clang++ -std=c++23 -stdlib=libc++ -fmodules -o test test.cpp
test.cpp:1:1: error: import of module 'std' imported non C++20 importable modules
1 | import std;
| ^
test.cpp:4:8: error: no member named 'print' in namespace 'std'
4 | std::print("Hello world!\n");
| ~~~~~^
2 errors generated.
Most people experimenting with modules use CMake as build system and this is what is suggested by the libc++ documentation. However, the page also generally describes that we need to generate a BMI (Built Module Interface) file (.pcm) from the module sources (.cppm). A script posted in the LLVM discourse was very helpful in determining the necessary steps. First, the module header needs to be precompiled:
clang++ -std=c++23 -stdlib=libc++ \
-Wno-reserved-identifier -Wno-reserved-module-identifier \
--precompile -o std.pcm /usr/share/libc++/v1/std.cppm
The location of the cppm file may of course differ on different systems. Also, shipping the module source currently must be explicitly activated when building libc++. After precompiling the module, we can compile our program as follows:
clang++ -std=c++23 -stdlib=libc++ \
-fmodule-file=std=std.pcm -o test std.pcm test.cpp
Note that we need to specify where the std
module can be found via -fmodule-file
and also need to specify it as an input file. All of this can of course be automated in a Makefile:
CXX = clang++
CXXFLAGS += -Weverything -Wno-c++98-compat -Wno-pre-c++20-compat
CXXFLAGS += -std=c++23 -stdlib=libc++
test: std.pcm test.cpp
$(CXX) $(CXXFLAGS) -fmodule-file=std=std.pcm -o $@ $^
std.pcm: /usr/share/libc++/v1/std.cppm
$(CXX) $(CXXFLAGS) -Wno-reserved-identifier -Wno-reserved-module-identifier --precompile -o $@ $^
Update (May 25, 2025): If you are using GCC, have a look at Using the C++23 std Module with GCC 15 as well.