We are excited to announce that support for C++20 modules in Compilation Database mode is now available on SonarCloud! Even more exciting, this feature will soon be available on SonarQube 10.8. Please note that it is not yet supported in SonarLint or Automatic Analysis mode.
Setting it up.
Although this feature is still in its experimental phase, we’ve put the control in your hands. To enable it, simply set the sonar.cfamily.enableModules
scanner property to true, and the rest will be handled automatically.
To help you get started, you can find an example configuration for a small project using modules here.
What happens under the hood?
In contrast to a textual header, when a module is used (imported), a pre-compiled module file (BMI) must be made available for compilation. The format of these files is not portable and is highly dependent on the build configuration. Such files are not only incompatible between compilers (GCC uses gcm
files, clang uses pcm
, and MSVC uses ifc
), but also between different versions of the same compiler, or even when invoked with different compilation flags.
As the CFamily analyzer uses a C++ frontend, we need to supply pre-compiled module files in a format that is compatible with it. When the support is enabled, the analyzer will act as the build system and:
- scan the source files for the module dependencies (imported and exported)
- build BMIs that are required for analyzed files.
There is one limitation, however, the compile command file provided for analysis (for example, generated using the build-wrapper
), needs to contain commands used to build BMIs for modules, even if the files are not analyzed. In other words, it needs to reflect a full build, including all dependencies.
Are std
and std.compat
modules supported?
Yes, and any other named module for which you have source files. You need to make sure that the steps to produce the BMIs for them are included in the provided Compilation Database.
What about header units?
The C++20 standard, in addition to named modules, introduces support for header units. By writing the import “myHeader.h”
or import <systemHeader>
, you can import a BMI corresponding to the header. This can be seen as a standard way of using precompiled headers.
The CFamily analyzer currently does not support using header units due to the lack of (cmake) or experimental (clang) support for them in the compiler and build tools space and the lack of publicly accessible projects using them. We plan to revisit them when their support becomes more mature and we are able to test them on real-world projects.
I encountered a false positive or false negative when using modules.
Despite the in-depth test of our implementation on multiple projects using it, we still consider the support for C++20 modules as experimental. With a language as complex and feature-rich as C++, it is impossible for us to test every possible scenario for each rule we provide. So, despite our best efforts, we recognize that you may encounter some false negatives or false positives on your project.
If you encounter any issues when analyzing your project that uses C++20 modules, please let us know by creating a separate thread on this forum. It would be best if you could include a reproducer in the report so we can more easily recreate the setup.