C++20 Modules

This tutorial implies you have some knowledge about C++20 modules. If not, see Overview of modules in C++ for introduction.

Named Modules

Using C++20 modules with Qbs is pretty straightforward. Let's suppose you have a module file that exports a single function printHello:

// hello.cppm
module;

#include <iostream>
#include <string_view>

export module hello;

export namespace Hello {

void printHello(std::string_view name)
{
    std::cout << "Hello, " << name << '!' << std::endl;
}

} // namespace Hello

Note: Currently, Clang only recognizes .cppm files as modules, however, for GCC and MSVC Qbs also recognizes .ixx files as C++ modules. Qbs assigns the "cppm" file tag to these files. You can assign this tag manually to module files with different extensions.

This function is later used in the main.cpp file as follows:

// main.cpp

import hello;

int main()
{
    Hello::printHello("World");
}

The project file simply lists files and sets the cpp.forceUseCxxModules property to true.

// myproject.qbs
CppApplication {
    consoleApplication: true
    install: true
    files: ["hello.cppm", "main.cpp"]
    cpp.cxxLanguageVersion: "c++20"
    cpp.forceUseCxxModules: true
}

Now, you can build the project by simply calling qbs, assuming that your compiler supports C++20 modules.

Module Partitions

Module partitions are treated as regular modules and should also have the same extension or assigned the "cppm" tag manually. See this example on how to use both interface module and partitions.

Modules and Libraries

Using modules in dynamic libraries requires using the same export/import macros as it was shown in the Dynamic Library section:

// lib/hello.cppm
module;

#include "lib_global.h"
#include <iostream>
#include <string_view>

export module hello;

export namespace Hello {

void MYLIB_EXPORT printHello(std::string_view name)
{
    std::cout << "Hello, " << name << '!' << std::endl;
}

} // namespace Hello

As shown in that section, the library .qbs file should also define the MYLIB_LIBRARY macro in order to mark symbols as exported:

// lib/lib.qbs
DynamicLibrary {
    name: "mylib"
    files: ["hello.cppm", "lib_global.h"]
    version: "1.0.0"
    install: true

    Depends { name: "cpp" }
    cpp.defines: "MYLIB_LIBRARY"
    cpp.cxxLanguageVersion: "c++20"
    cpp.forceUseCxxModules: true
    // ...
}

For more details, see the complete example.

© 2022 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.