Modules in Clang 11
source link: https://mariusbancila.ro/blog/2020/05/15/modules-in-clang-11/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Modules in Clang 11
In my previous post, I wrote about the support for C++20 modules in Visual Studio 2019 16.5. VC++ is not the only major compiler that has experimental support for modules. Clang has its own implementation, although only partial. In this post, I will discuss the support available in Clang 11. You can check the current status here.
Disclaimer: My experience with Clang is limited to compiling various snippets of code. Although documentation may exist in some inner circle of trust, it is not easily found using search engines. The content of this article was put together from several bits of information found online and large amounts of trial and error. Therefore, the information I present below may not be complete (although I hope it is correct). If you find anything that needs to be complemented or corrected, please leave a comment and I will update accordingly.
A first example
Let’s start again with the typical hello world application in C++ that looks as follows:
To compile this with Clang you need to run the following command:
Noticed that I specified -std=c++2a to indicate support for C++20, although any other version would have worked. However, this switch is required to enable modules support, which used to be available only by specifying -fmodules-ts. This is now no longer necessarily when compiling with -std=c++2a.
This program can be modified to use modules instead by replacing the #include preprocessor directive with an import directive, as follows:
Compiling this program requires some changes to the command we executed previously.
So, what do these additional arguments represent?
- -fimplicit-modules tells the compiler to use implicit modules, which is a feature that automatically translates #include directives into import statements (i.e. headers into modules).
- -fimplicit-module-maps tells the compiler to implicitly search the file system for module map files. A module map file is a file containing the mapping between existing headers and the logical structure of a module. You can learn more about these from here.
Writing a module
The next step is to write a module that exports a function, called get_greeting_text() in this example, that returns the text that will be printed to the console in the main program. The following snippet shows the content of the module from a file called greetings.cpp.
The changes to the main program are simple: import the greetings module and call the get_greeting_text() function.
Compiling the module and the main program this time gets a bit more complicated. The following commands must be executed:
The first command, compiles the module and generates a file called greetings.pcm. PCM here stands for “precompiled module”. This file is the Binary Module Interface (BMI) file and is the equivalent of the IFC file generated by the VC++ compiler. GCC is using yet another term, “Compiled Module Interfaces” and the extension CMI. The second command, compiles the main program. You will notice in the arguments, a new switch called -fprebuilt-module-path. This tells the compiler what is the path of the folder containing the prebuilt modules (the .pcm files).
In this example, the module file had the extension .cpp. However, Clang supports other extensions, including .cppm and even .ixx. However, when using different extensions, the commands for building the module change.
These are the commands to build the same sample if the greetings module was available in a file called greetings.cppm.
These are the commands to build the same sample if the greetings module was available in a file called greetings.ixx.
We can add more exports to the module, just as we did in the previous article. In the following example, the greeter class returns a random text every time its call operator is invoked.
This new class can be used as shown below. If you run this program multiple times, you should see the second line changing randomly.
The commands required to build this program are the following:
Templates can also be exported from a module. In the next example, a module called foo, available in a file foo.cpp exports a class template foo and a function template called make_foo.
The exports from this module can be used as follows in main.cpp:
To build this program, we must run the following commands:
As I mentioned in the beginning, Clang only supports C++20 modules partially. Unfortunately, this features is not available yet.
You can learn more about Clang support for modules from the following articles:
Aggregate valuable and interesting links.
Joyk means Joy of geeK