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 $@ $^