Skip to content

Treat '.ixx' and '.cppm' files as C++ sources

I've been experimenting with MSVC implementation of C++20 modules and CMake and found that, since MSBuild already knows how to handle module dependencies, it is relatively easy to force CMake to generate an MSVC solution that contains modules and is built correctly. This relies on MSVC treating files with .ixx and .cppm extensions as module interface units by default.

Unfortunately, CMake does not know about these extensions, and this causes two problems.

First, 'by default' any .ixx/.cppm file added as a source to a target will be explicitly excluded from build (since CMake would be unable to determine its language). Immediately obvious way - setting source-level LANGUAGE property to CXX for .ixx/.cppm files - doesn't work correctly: CMake would stop excluding them from build, however since LANGUAGE for file is now different from 'default' (empty) language determined by file extension, CMake would force /TP option (CompileAs=Cpp) for such files, which is not what we want (we want either to keep a default or set explicit /interface). The simple way to fix that is to add these two extensions to CMAKE_CXX_SOURCE_FILE_EXTENSIONS variable - this is first part of the PR. Note that it's possible to work around this problem without touching CMake code (e.g. by setting variable_watch before project() command and appending ixx;cppm extensions when variable is first assigned, before CMake builds extension->language map), however it's quite hacky. With this change (either fix or hack), it is already possible to compile non-trivial solution with modules using MSBuild!

Second, moving from header/source pair to ixx causes a problem for qt automoc. Conventional way to force moc invocation for cpp files is to add 'include <foo.moc>' string at the end of the source file. However, this doesn't work for .ixx/.cppm files - automoc code simply doesn't consider them to be sources and skips them. The way it does the check is look at hardcoded CLikeSourceFileExtensions variable. Adding two new extensions to this variable is the second part of the PR. Unfortunately, I didn't find any way to work around this without touching CMake code. With this change, it is possible to build a full application that uses Qt and contains widgets in modules!

Topic-rename: cxx-module-extensions

Edited by Brad King

Merge request reports