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.