How to use c++20 modules with CMake?

后端 未结 4 543
佛祖请我去吃肉
佛祖请我去吃肉 2021-01-03 22:27

Clang and MSVC already supports Modules TS from unfinished C++20 standard. Can I build my modules based project with CMake or other build system and how?

I tried bui

相关标签:
4条回答
  • 2021-01-03 22:49

    This works on Linux Manjaro (same as Arch), but should work on any Unix OS. Of course, you need to build with new clang (tested with clang-10).

    helloworld.cpp:

    export module helloworld;
    import <cstdio>;
    export void hello() { puts("Hello world!"); }
    

    main.cpp:

    import helloworld;  // import declaration
    
    int main() {
        hello();
    }
    

    CMakeLists.txt:

    cmake_minimum_required(VERSION 3.16)
    project(main)
    
    set(CMAKE_CXX_STANDARD 20)
    set(CMAKE_CXX_STANDARD_REQUIRED ON)
    set(CMAKE_CXX_EXTENSIONS OFF)
    set(PREBUILT_MODULE_PATH ${CMAKE_BINARY_DIR}/modules)
    
    function(add_module name)
        file(MAKE_DIRECTORY ${PREBUILT_MODULE_PATH})
        add_custom_target(${name}.pcm
                COMMAND
                    ${CMAKE_CXX_COMPILER}
                    -std=c++20
                    -stdlib=libc++
                    -fmodules
                    -c
                    ${CMAKE_CURRENT_SOURCE_DIR}/${ARGN}
                    -Xclang -emit-module-interface
                    -o ${PREBUILT_MODULE_PATH}/${name}.pcm
    
                )
    endfunction()
    
    
    add_compile_options(-fmodules)
    add_compile_options(-stdlib=libc++)
    add_compile_options(-fbuiltin-module-map)
    add_compile_options(-fimplicit-module-maps)
    add_compile_options(-fprebuilt-module-path=${PREBUILT_MODULE_PATH})
    
    add_module(helloworld helloworld.cpp)
    add_executable(main
            main.cpp
            helloworld.cpp
            )
    add_dependencies(main helloworld.pcm)
    
    
    0 讨论(0)
  • 2021-01-03 22:56

    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. It fundamentally changes how dependencies between source files have to be handled during the build: In a pre-modules world all cpp source files can be built independently in any order. With modules that is no longer true, which has implications not only for CMake itself, but also for the downstream build system.

    Take a look at the CMake Fortran modules paper for the gory details. From a build system's point of view, Fortran's modules behave very similar to the C++20 modules.

    0 讨论(0)
  • 2021-01-03 23:05

    CMake does not currently support C++20 modules like the others have stated. However, module support for Fortran is very similar, and perhaps this could be easily changed to support modules in C++20.

    http://fortranwiki.org/fortran/show/Build+tools

    Now, perhaps there i an easy way to modify this to support C++20 directly. Not sure. It is worth exploring and doing a pull request should you resolve it.

    0 讨论(0)
  • 2021-01-03 23:06

    I was not able to find Cmake support for modules. Here is an example how to use modules using clang. I am using Mac and this example works ok on my system. It took me quite a while to figure this out so unsure how general this is across linux or Windows.

    Source code in file driver.cxx

    import hello;
    int main() { say_hello("Modules"); } 
    

    Source code in file hello.cxx

    #include <iostream>
    module hello;
    void say_hello(const char *n) {
      std::cout << "Hello, " << n << "!" << std::endl;
    }
    

    Source code in file hello.mxx

    export module hello;
    export void say_hello (const char* name);
    

    And to compile the code with above source files, here are command lines on terminal

    clang++ \
      -std=c++2a                        \
      -fmodules-ts                      \
      --precompile                      \
      -x c++-module                     \
      -Xclang -fmodules-embed-all-files \
      -Xclang -fmodules-codegen         \
      -Xclang -fmodules-debuginfo       \
      -o hello.pcm hello.mxx
    
    clang++ -std=c++2a -fmodules-ts -o hello.pcm.o -c hello.pcm
    
    clang++ -std=c++2a -fmodules-ts -x c++ -o hello.o \
      -fmodule-file=hello.pcm -c hello.cxx
    
    clang++ -std=c++2a -fmodules-ts -x c++ -o driver.o \
      -fmodule-file=hello=hello.pcm -c driver.cxx
    
    clang++ -o hello hello.pcm.o driver.o hello.o
    

    and to get clean start on next compile

    rm -f *.o
    rm -f hello
    rm -f hello.pcm
    

    expected output

    ./hello
    Hello, Modules!
    

    Hope this helps, all the best.

    0 讨论(0)
提交回复
热议问题