Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Build C++ module with CMake's experimental module dependency scanning

CMake has experimental C++20 module dependency scanning (!5562). I try to use CMake 3.20, g++-11, and ninja-1.10 to build a project with module.

// main.cpp
import mod;
int main() { return 0; }
// mod.ixx
export module mod;
export void f() {}

The CMakeLists.txt is an adaptation of https://gitlab.kitware.com/ben.boeckel/cmake/blob/cpp-modules/Modules/Compiler/GNU-CXX.cmake

cmake_minimum_required(VERSION 3.20)
project(simple)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_DEPFILE_FORMAT gcc)
set(CMAKE_CXX_DEPENDS_USE_COMPILER TRUE)

string(CONCAT CMAKE_EXPERIMENTAL_CXX_SCANDEP_SOURCE
        "<CMAKE_CXX_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -E -x c++ <SOURCE>"
        " -MT <DYNDEP_FILE> -MD -MF <DEP_FILE>"
        " -fmodules-ts -fdep-file=<DYNDEP_FILE> -fdep-output=<OBJECT>"
        " -fdep-format=trtbd")

set(CMAKE_EXPERIMENTAL_CXX_MODULE_MAP_FORMAT "gcc")

set(CMAKE_EXPERIMENTAL_CXX_MODULE_MAP_FLAG
        " -fmodules-ts -fmodule-mapper=<MODULE_MAP_FILE>"
        " -fdep-format=trtbd -x c++")

set(CMAKE_CXX_FLAGS "-fmodules-ts")
add_executable(simple main.cpp mod.ixx)

But CMake and ninja don't build the project:

$ mkdir build && cd build
$ cmake -DCMAKE_CXX_COMPILER=<path to g++-11>/g++-11 -G Ninja ..

-- The C compiler identification is GNU 10.3.1
-- The CXX compiler identification is GNU 11.1.0
-- Detecting C compiler ABI info
...
-- Detecting CXX compile features - done
-- Configuring done 
-- Generating done
-- Build files have been written to: <...>

$ ninja

<...>/g++-11 -fmodules-ts -std=gnu++20 -MD -MT <...>/main.cpp.o 
    -MF <...>/main.cpp.o.d -o <...>/main.cpp.o -c ../main.cpp
In module imported at ../main.cpp:1:1:
mod: error: failed to read compiled module: No such file or directory
mod: note: compiled module file is ‘gcm.cache/mod.gcm’
mod: note: imports must be built before being imported
mod: fatal error: returning to the gate for a mechanical issue
compilation terminated.
ninja: build stopped: subcommand failed.

The top rated answer here (from ComicSansMS) says we can use the experimental feature to build C++20 modules: How to use c++20 modules with CMake?

Can CMake automatically scan module dependency and build the project?

like image 786
Qurious Cube Avatar asked May 29 '21 02:05

Qurious Cube


People also ask

Can I use c++20 modules with CMake?

CMake currently does not support C++20 modules. See also the relevant issue in the CMake issue tracker. Note that supporting modules requires far more support from the build system than inserting a new compiler option.

How do I add a C++ module to my project?

To add a module to your project, just right click on any folder and select “Add New Item:” And select the “C++ Module Interface Unit (.ixx)” template in in the “Visual C++” category: If you are using the Targets View, it is even easier. Just click “Add -> New Module…” in the context menu on any target:

How do the tools scan for module dependencies?

The tools use a patched clang-scan-deps to scan for module dependencies and the results are persisted in an LMDB embedded store for incremental builds. Binary installers are available for Windows and Linux.

How do I enable experimental C++ modules in MSVC?

Select the Configuration Properties > C/C++ > Language property page. Modify the Enable C++ Modules (experimental) property, and then choose OK. The MSVC compiler options /O1 and /O2 specify all optimizations for minimum size or maximum speed. The MSVC compiler lets you specify command files that contain command-line options.


1 Answers

GCC + CMake's module system is incredibly experimental at this point and, in my opinion, not worth tampering with right now. I spent about an hour trying to get it to automatically scan but I don't think the docs are complete yet to state how if at all possible. I'll need to look at the github issues for unofficial documentation to see if there is a way at all. As it stands, I don't see a way to do this.

Your best option is to work with Visual C++'s module system as their C++20 implementation is feature complete (sans final ABI implementation). I've worked with it and it was stable enough for my test projects aside from internal compilation errors. Those were due to complex constevals which are mitigated by simplifying them. I'm sure this same issue exists with other complex module code, so be aware to see if it fits your project goals.

like image 172
j__ Avatar answered Oct 19 '22 02:10

j__