跳转到内容

C++ Modules 使用与示例

基础介绍

Xmake 采用 .mpp 作为默认的模块扩展名,同时也支持 .ixx.cppm.mxx 等。已完整支持 gcc11/clang/msvc 的 C++20 Modules 构建,并能自动分析模块间依赖,实现最大化并行编译。

基础示例

EXPLORER
src
hello.mpp
main.cpp
xmake.lua
Lua xmake.lua
123456
add_rules("mode.release", "mode.debug")
set_languages("c++20")

target("hello")
    set_kind("binary")
    add_files("src/*.cpp", "src/*.mpp")

模块类导出示例

在模块中导出类:

EXPLORER
src
main.cpp
math.mpp
xmake.lua
Lua xmake.lua
12345678
add_rules("mode.debug", "mode.release")

set_languages("c++20")

target("class_test")
    set_kind("binary")
    add_files("src/*.cpp")
    add_files("src/*.mpp")

模块分区示例

使用模块分区(Module Partitions):

EXPLORER
src
hello_say.mpp
hello.mpp
main.cpp
xmake.lua
Lua xmake.lua
12345678
add_rules("mode.debug", "mode.release")

set_languages("c++20")

target("partition_test")
    set_kind("binary")
    add_files("src/*.cpp")
    add_files("src/*.mpp")

动态库模块示例

创建带有模块的动态库:

EXPLORER
src
foo.mpp
main.cpp
xmake.lua
Lua xmake.lua
123456789101112
add_rules("mode.debug", "mode.release")

set_languages("c++20")

target("foo")
    set_kind("shared")
    add_files("src/foo.mpp")

target("test")
    set_kind("binary")
    add_deps("foo")
    add_files("src/main.cpp")

跨目标依赖示例

Target 之间的模块依赖:

EXPLORER
src
bar.mpp
main.cpp
xmake.lua
Lua xmake.lua
123456789101112
add_rules("mode.debug", "mode.release")

set_languages("c++20")

target("bar")
    set_kind("static")
    add_files("src/bar.mpp")

target("app")
    set_kind("binary")
    add_deps("bar")
    add_files("src/main.cpp")

模块私有片段示例

使用模块私有片段(Private Module Fragment)隐藏实现细节:

EXPLORER
src
box.mpp
main.cpp
xmake.lua
Lua xmake.lua
12345678
add_rules("mode.debug", "mode.release")

set_languages("c++20")

target("box")
    set_kind("binary")
    add_files("src/*.cpp")
    add_files("src/*.mpp")

模块实现单元示例

分离模块接口和实现(Module Implementation Unit):

EXPLORER
src
implementation.cpp
interface.mpp
main.cpp
xmake.lua
Lua xmake.lua
12345678
add_rules("mode.debug", "mode.release")

set_languages("c++20")

target("app")
    set_kind("binary")
    add_files("src/*.cpp")
    add_files("src/*.mpp")

模块聚合示例

使用 export import 聚合子模块:

EXPLORER
src
circle.mpp
main.cpp
rect.mpp
shape.mpp
xmake.lua
Lua xmake.lua
12345678
add_rules("mode.debug", "mode.release")

set_languages("c++20")

target("app")
    set_kind("binary")
    add_files("src/*.cpp")
    add_files("src/*.mpp")

仅 Cpp 工程启用 Modules

v2.7.1 起支持 Headerunits,可在模块中引入 STL 和用户头文件模块。通常需至少有一个 .mpp 文件才会启用 modules 编译,但也可通过配置强制启用:

EXPLORER
src
main.cpp
xmake.lua
Lua xmake.lua
123456789
add_rules("mode.debug", "mode.release")

set_languages("c++latest")

target("stdmodules_cpp_only")
    set_kind("binary")
    add_files("src/*.cpp")
    set_policy("build.c++.modules", true)

Headerunits 示例

如何将 STL 或自定义头文件作为 headerunit 引入模块,见下面的示例:

EXPLORER
src
hello.mpp
main.cpp
xmake.lua
Lua xmake.lua
1234567
add_rules("mode.release", "mode.debug")
set_languages("c++20")

target("stl_headerunit")
    set_kind("binary")
    add_files("src/*.cpp", "src/*.mpp")

C++23 标准库模块

支持 C++23 标准库模块(stdmodules):

EXPLORER
src
my_module.cpp
my_module.mpp
test
test.cpp
xmake.lua
Lua xmake.lua
123456789101112
add_rules("mode.debug", "mode.release")
set_languages("c++latest")

target("mod")
    set_kind("static")
    add_files("src/*.cpp")
    add_files("src/*.mpp", {public = true})

target("stdmodules")
    set_kind("binary")
    add_files("test/*.cpp")
    add_deps("mod")

模块包分发

定义和分发 C++ Modules 包:

EXPLORER
src
foo.cpp
foo.mpp
main.cpp
xmake.lua
xmake.lua
Lua xmake.lua
12345678910
add_rules("mode.release", "mode.debug")
set_languages("c++20")

target("foo")
    set_kind("static")
    add_files("*.cpp")
    add_files("*.mpp", {
        defines = "FOO_EXPORT", 
        public = true
    })

模块包集成

通过 add_requires("foo") 快速集成:

EXPLORER
src
main.cpp
xmake.lua
Lua xmake.lua
1234567891011
add_rules("mode.release", "mode.debug")
set_languages("c++20")

add_repositories("my-repo repo") 
add_requires("foo")

target("app")
    set_kind("binary")
    add_packages("foo")
    add_files("src/*.cpp")
    set_policy("build.c++.modules", true)

更多官方示例见:C++ Modules 示例集