Command lines for compiling and using C++20 modules from both clang and MSVC.
Example files
Here are some example files that are used in the command lines below.
A C++ module interface unit with both interface and implementation
Here is a C++ module interface unit, greetings.cpp. Despite the name, a module interface unit can contain both interface and implementation.
export module greetings;
export
{
const char* greet();
}
const char* greet()
{
return "Hello.";
}
A C++ module interface unit with an interface only
Here is a C++ module interface unit, hello.cpp. This example contains an interface, but it does not contain an implementation.
export module hello;
export const char* hello_world();
A C++ module implementation unit
Here is a C++ module implementation unit, hello_impl.cpp. It contains the implementation for the interface defined in hello.cpp.
module hello;
const char* hello_world()
{
return "Hello, world!";
}
Programs that import modules
Here is greet.cpp. This imports the greetings module.
import greetings;
#include <iostream>
int main()
{
std::cout << greet() << '\n';
}
And here’s say_hello.cpp. This imports the hello module.
import hello;
#include <iostream>
int main()
{
std::cout << hello_world() << '\n';
}
Command lines for compiling modules with clang
Compiling a module interface unit with clang
This compiles greetings.cpp and generates a .pcm file which is a binary representation of the module. It does not generate a .o file.
$ clang -c --std=c++20 greetings.cpp -Xclang -emit-module-interface -o greetings.pcm
Compiling a module implementation unit with clang
First, compile the module interface unit. This compiles hello.cpp and generates a .pcm file.
$ clang -c --std=c++20 hello.cpp -Xclang -emit-module-interface -o hello.pcm
Then compile the module implementation unit. This compiles hello_impl.cpp. It needs to be told about the .pcm file with -fmodule-file.
It generates a .o file.
$ clang -c --std=c++20 hello_impl.cpp -fmodule-file=hello.pcm
Using a pre-compiled module with clang
When importing a module, the compiler needs to know how to find module binaries. Use -fprebuilt-module-path to provide a search path.
This example uses the greetings module which combined both interface and implementation.
$ clang --std=c++20 -fprebuilt-module-path=. greet.cpp greetings.pcm -o greet
If the imported module name differs from the .pcm then use -fmodule-file to specify the mapping.
$ mv greetings.pcm test.pcm
$ clang --std=c++20 -fmodule-file=greetings=test.pcm greet.cpp test.pcm -o greet
This example uses the hello module, which was split into interface and implementation.
clang --std=c++20 -fprebuilt-module-path=. say_hello.cpp hello.pcm hello_impl.o -o say_hello
Command lines for compiling modules with MSVC
Compiling a module interface unit with MSVC
This compiles greetings.cpp and generates an .ifc file and an .obj file. The .ifc file is a binary representation of the module’s interface.
C:> cl /c /std:c++20 /interface /TP greetings.cpp
By default, MSVC expects module interfaces to have an .ixx extension. The /interface and /TP options allow us to use a .cpp file.
Compiling a module implementation unit with MSVC
First, compile the module interface unit. This compiles hello.cpp and generates an .ifc file.
C:> cl /c /std:c++20 /interface /TP hello.cpp
Then compile the module implementation unit. This compiles hello_impl.cpp. The .ifc file for the module must exist. It generates a .obj file.
C:> cl /c /std:c++20 hello_impl.cpp
Using a pre-compiled module with MSVC
When importing a module, the compiler needs to know how to find module binaries. It implicitly searches in the current directory.
This example uses the greetings module which combined both interface and implementation.
C:> cl /std:c++20 greet.cpp greetings.obj
If the module’s .ifc file isn’t in the current directory then use /ifcSearchDir to add to the search path.
C:> cl /std:c++20 greet.cpp greetings.obj /ifcSearchDir C:/modules
This example uses the hello module, which was split into interface and implementation.
C:> cl /std:c++20 say_hello.cpp hello.obj hello_impl.obj
Further reading
For more information, follow these links.