文章目錄
- 1. 為什麼使用 Modules
- 2. 項目搭建
- 2.1 工程結構
- 2.2 代碼編寫
- 3. cmakelist.txt 配置
- 3.1 查看 CMAKE_EXPERIMENTAL_CXX_IMPORT_STD 值
- 3.2 Cmakelist.txt 編寫
- 3.3 項目編譯配置
- 4. 編譯運行測試
- 5. 代碼
1. 為什麼使用 Modules
模塊(Modules)是 C++20 引入了一個重要的新特性,解決頭文件(如編譯速度慢、宏污染、重複包含、依賴管理混亂等問題。使用體驗上更現代,和其他語言類似。所以使用modules一是為了體驗新特性的使用,學習c++ 新標準,也是為了以後項目遷移做準備。
2. 項目搭建
2.1 工程結構
2.2 代碼編寫
io.cppm :
export module io;
export void print_result(const char* label, int value);
io_impl.cpp:
module; // 開啓全局模塊段
#include <iostream> // 實現中使用標準庫也需要前置包含
module io; // 指定所屬模塊
void print_result(const char* label, int value) {
std::cout << label << value << std::endl;
}
這裏 module 用於開啓全局模塊段, 在兼容導入原始頭文件時使用,在實現中使用標準庫也需要前置包含。module io, 用於指定所屬模塊。
math.cppm:
export module math; // 聲明並導出模塊
export int add(int a, int b); // 導出函數聲明
export int multiply(int a, int b); // 另一個導出函數
math_impl.cpp:
module math; // 指定所屬模塊
int add(int a, int b) {
return a + b;
}
int multiply(int a, int b) {
return a * b;
}
main.cpp:
import std;
import io; // 導入IO模塊
import math; // 導入數學模塊
int main() {
std::println("Use std module on {}", "hello");
int sum = add(3, 4); // 使用模塊導出函數
int product = multiply(3, 4);
print_result("Sum: ", sum);
print_result("Product:", product);
return 0;
}
import std, 是c++ 23提供的modules 標準庫模塊。 std::println(“Use std module on {}”, “hello”); 是c++ 23 提供的插值表達式。
3. cmakelist.txt 配置
要使用c++ 23 import std 支持需要比較新的編譯器和cmke版本支持,構建工具使用ninja, make 目前不支持。環境搭建和工具安裝參考前面章節。
3.1 查看 CMAKE_EXPERIMENTAL_CXX_IMPORT_STD 值
地址:https://github.com/Kitware/CMake/blob/v4.2.0/Help/dev/experimental.rst 根據自己cmake版本來查詢對應的版本, 此提供很多支持。
|
類別
|
特性
|
核心用途
|
|
C++ 語言特性
|
C++ import std support
|
啓用 C++23 標準庫模塊導入。
|
|
包管理
|
Export Package Dependencies
|
自動導出包的依賴關係,方便下游使用。
|
|
包管理
|
Export CPS Package Information
|
以標準化的 CPS 格式導出包元數據。
|
|
包管理
|
Find/Import CPS Packages
|
支持查找符合 CPS 規範的包。
|
|
構建工具集成
|
Build database support
|
導出構建信息數據庫,供 IDE 和分析工具使用。
|
|
高級構建分析
|
Instrumentation
|
在構建過程中插入自定義邏輯,收集額外數據。
|
如果只使用 import std 只需要引入對應的就行,這裏為了方便,直接導入全部。
3.2 Cmakelist.txt 編寫
cmake_minimum_required(VERSION 4.2.0)
set(CMAKE_CXX_MODULE_STD ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED YES)
set(CMAKE_CXX_EXTENSIONS ON)
# 啓用 C++23 標準庫模塊導入
set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD "d0edc3af-4c50-42ea-a356-e2862fe7a444")
# 自動導出包的依賴關係,方便下游使用
set(CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_DEPENDENCIES "1942b4fa-b2c5-4546-9385-83f254070067")
# 以標準化的 CPS 格式導出包元數據
set(CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO "b80be207-778e-46ba-8080-b23bba22639e")
# 支持查找符合 CPS 規範的包
set(CMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES "e82e467b-f997-4464-8ace-b00808fff261")
# 導出構建信息數據庫,供 IDE 和分析工具使用
set(CMAKE_EXPERIMENTAL_EXPORT_BUILD_DATABASE "73194a1d-c0b5-41b9-9190-a4512925e192")
# 在構建過程中插入自定義邏輯,收集額外數據
set(CMAKE_EXPERIMENTAL_INSTRUMENTATION "ec7aa2dc-b87f-45a3-8022-fe01c5f59984")
project(app LANGUAGES CXX)
# 生成 compile_command.json
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(TARGET app)
############## 模塊配置 ##############################################
# 創建數學模塊庫
add_library(math_mod)
target_sources(math_mod
PUBLIC
# 模塊接口文件集
FILE_SET cxx_modules TYPE CXX_MODULES
BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/src/math
FILES src/math/math.cppm
PRIVATE
# 實現文件
src/math/math_impl.cpp
)
# io 模塊
add_library(io_mod)
target_sources(io_mod
PUBLIC
# 模塊接口文件集
FILE_SET cxx_modules TYPE CXX_MODULES
BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/src/io
FILES src/io/io.cppm
PRIVATE
# 實現文件
src/io/io_impl.cpp
)
############## 三方庫配置 #############################################
############### 項目配置 ##############################################
# 頭文件
include_directories(${CMAKE_SOURCE_DIR}/include)
# 源文件
file(GLOB SRC_FILES
${CMAKE_SOURCE_DIR}/src/*.cpp
)
# 創建主程序
add_executable(${TARGET} src/app/main.cpp)
target_link_libraries(${TARGET} PRIVATE math_mod io_mod)
3.3 項目編譯配置
這裏使用llvm-mingw, 使用mingw 測試編譯有問題, 編譯器下載及環境安裝參考之前章節。
- 項目配置: .vscode/settings.json
{
"cmake.generator": "Ninja",
"clangd.path": "C:/software/llvm-mingw-20251118-ucrt-x86_64/bin/clangd.exe",
"clangd.arguments": [
"--compile-commands-dir=${workspaceFolder}/build",
"--query-driver=C:/software/llvm-mingw-20251118-ucrt-x86_64/bin/g++.exe",
"--log=verbose",
"--pretty",
"--all-scopes-completion",
"--completion-style=bundled",
"--cross-file-rename",
"--header-insertion=never",
"--background-index",
"--clang-tidy",
"--clang-tidy-checks=cppcoreguidelines-*,performance-*,bugprone-*,portability-*,modernize-*,google-*",
"-j=2",
"--pch-storage=disk",
"--function-arg-placeholders=false",
"--experimental-modules-support"
]
}
上述項目配置會有些提示,忽略就可以:
4. 編譯運行測試
選擇編譯器:
ctrl + shift + p 後選擇 CMake: Select a Kit
選擇之前安裝的最新版llvm-mingw:
點擊左下角編譯運行:
- 測試結果:
- 如果出現編譯通過, vscode 代碼提示 import 未找到或者不能識別的問題,檢查clangd插件環境,嘗試重啓vscode, 重新編譯來解決。