Uses xmake to build c++20 modules


c++ modules have been officially included in the c++20 draft, and msvc and clang have been basically implemented on modules-ts Support, as c++20’s footsteps are getting closer and closer to us, xmake has also begun to support c++modules in advance.

At present xmake has fully supported the implementation of the modules-ts of msvc/clang. For gcc, since its cxx-modules branch is still under development, it has not officially entered the master. I have read the changelog inside, and the related flags are still in the process. Constantly changing, I feel that it has not stabilized, so I have not supported it yet.

For more information about xmake’s progress on c++modules: https://github.com/xmake-io/xmake/pull/569

Hello Module

I will not talk about the introduction of c++modules. This is mainly about how to build a c++modules project under xmake. Let’s look at a simple example:

    add_files("src/*.cpp", "src/*.mpp")

The above is a description of the xmake.lua that supports building c++modules files, where hello.mpp is the module file:

#include <cstdio>
export module hello;
using namespace std;

export namespace hello {
    void say(const char* str) {
        printf("%s\n", str);

Main.cpp is the main program that uses the hello module:

import hello;

int main() {
    hello::say("hello module!");
    return 0;

Next we execute xmake to build this program:

ruki:hello ruki$ xmake
[0%]: ccache compiling.release src/hello.mpp
[50%]: ccache compiling.release src/main.cpp
[100%]: linking.release hello
build ok!

xmake will handle all the details logic internally, for developers, just add the module file *.mpp as the source file.

Module Interface File

The above mentioned *.mpp is the module interface file name recommended by xmake. In fact, the default suffix names of the compiler files are not uniform. clang is *.cppm, while msvc is *.ixx, which is very unfriendly for writing a unified module project across compilers. Therefore, reference is made to the recommendation method in build2, and the unified *.mpp suffix is used to standardize the command of the module project interface under xmake.

Of course, this also supports xmake’s recommended naming scheme. For suffixes such as *.ixx and *.cppm, xmake is also fully compatible and can be added directly to add_files.

Compile parameter processing


Let’s first look at how to handle module construction under clang. We only need to add -v to execute xmake build, we can see all the details parameters:

ruki:hello ruki$ xmake -v
[0%]: ccache compiling.release src/hello.mpp
/usr/local/bin/ccache /usr/bin/xcrun -sdk macosx clang -c -fmodules-ts --precompile -x c++-module -Qunused-arguments -arch x86_64 -fpascal-strings -fmessage-length=0 - Mmacosx-version-min=10.14 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk -o build/.objs/hello/macosx/x86_64/release/ Src/hello.mpp.o.pcm src/hello.mpp
/usr/local/bin/ccache /usr/bin/xcrun -sdk macosx clang -c -fmodules-ts -Qunused-arguments -arch x86_64 -fpascal-strings -fmessage-length=0 -mmacosx-version-min=10.14 - Isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk -o build/.objs/hello/macosx/x86_64/release/src/hello.mpp.o build /.objs/hello/macosx/x86_64/release/src/hello.mpp.o.pcm
[ 50%]: ccache compiling.release src/main.cpp
/usr/local/bin/ccache /usr/bin/xcrun -sdk macosx clang -c -fmodules-ts -fmodule-file=build/.objs/hello/macosx/x86_64/release/src/hello.mpp.o. Pcm -Qunused-arguments -arch x86_64 -fpascal-strings -fmessage-length=0 -mmacosx-version-min=10.14 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10 .14.sdk -o build/.objs/hello/macosx/x86_64/release/src/main.cpp.o src/main.cpp
[100%]: linking.release hello
"/usr/bin/xcrun -sdk macosx clang++" -o build/macosx/x86_64/release/hello build/.objs/hello/macosx/x86_64/release/src/hello.mpp.o build/.objs/hello/ Macosx/x86_64/release/src/main.cpp.o -arch x86_64 -mmacosx-version-min=10.14 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14 .sdk -stdlib=libc++ -lz
build ok!

We simplify it as follows:

clang -c -fmodules-ts --precompile -x c++-module -o hello.mpp.o.pcm src/hello.mpp
clang -c -fmodules-ts -o hello.mpp.o hello.mpp.o.pcm
clang -c -fmodules-ts -fmodule-file=hello.mpp.o.pcm -o main.cpp.o src/main.cpp
clang++ -o hello hello.mpp.o main.cpp.o

-fmodules-ts is used to enable the c++-modules module standard, --precompile is used to precompile the module interface file. Since *.mpp is not the default module interface file name of the compiler, xmake is added. -x c++-module to force compilation as a module interface file.

Compile the *.mpp module interface file, and finally generate the *.pcm module file and finally tell the clang compiler by -fmodule-file. We define the hello module in main.cpp where we compile, avoid compiling main. A compiler error undefined by the hello module occurs at .cpp.

Finally, clang++ links all object files, including the object files generated by hello.mpp, into the target program.


For the processing under msvc, I will not elaborate, in fact, the whole logic is similar, I will directly paste the execution of the command process:

Cl.exe -c /experimental:module /module:interface /module:output hello.mpp.obj.pcm /TP -nologo -Fohello.mpp.obj src\\hello.mpp
Cl.exe -c /experimental:module /module:reference hello.mpp.obj.pcm -nologo -Fomain.cpp.obj src\\main.cpp
Link.exe -nologo -dynamicbase -nxcompat -machine:x64 -out:hello.exe hello.mpp.obj main.cpp.obj


Originally, I wanted to add gcc to it. Later, I found that gcc support for c++modules is still maintained in an independent branch. I have not yet entered the master. If I want to use it, I have to check the cxx-modules branch code separately. To compile a gcc toolchains that supports c++modules.

And the use of flags inside is often changing, I feel that it has not been completely stabilized, so I am lazy to toss here, when to support the official version of gcc.

For more information on the implementation of gcc’s modules-ts implementation, please refer to: https://gcc.gnu.org/wiki/cxx-modules

Other examples

There are also a lot of engineering examples related to c++modules built into the xmake project. Interested students can refer to the following: c++module examples


Similar Posts