CMake 本身不依赖 C++ 标准库或特定编译器,但配置 C++ 项目时必须显式声明 C++ 标准(如 set(CMAKE_CXX_STANDARD 17) 和 set(CMAKE_CXX_STANDARD_REQUIRED ON)),否则跨平台默认行为不一致会导致构建失败;Windows 下 find_package(Threads REQUIRED) 易因运行时库不匹配出错,推荐改用 target_link_libraries(myapp PRIVATE Threads::Threads)。

直接说结论:CMake 本身不依赖 C++ 标准库或特定编译器,但配置 C++ 项目时,CMakeLists.txt 必须显式声明 C++ 标准、编译器选项和目标属性,否则不同平台/编译器会默认不同行为(比如 macOS Clang 默认 C++98,Windows MSVC 可能用 C++14),导致构建失败或行为不一致。
怎么让 CMake 正确识别并使用 C++17(或更高)
很多项目在 Linux 能编译,放到 Windows 就报 std::optional 找不到——根本原因是没强制指定标准版本。CMake 不会自动升级标准,必须手动设。
-
set(CMAKE_CXX_STANDARD 17)是基础,但仅影响新 target;已有 target 需单独调用set_property(TARGET xxx PROPERTY CXX_STANDARD 17) - 推荐写法:
set(CMAKE_CXX_STANDARD 17)+set(CMAKE_CXX_STANDARD_REQUIRED ON),后者确保不支持该标准时立即报错,而不是静默降级 - 若用 GCC/Clang,加
set(CMAKE_CXX_EXTENSIONS OFF)可禁用 GNU 扩展,提升跨平台可移植性
为什么 find_package(Threads REQUIRED) 在 Windows 上常出问题
Windows 没有 POSIX 线程 API,Threads 模块在 MSVC 下实际链接的是 legacy_stdio_definitions.lib 和运行时线程支持,但容易因运行时库不匹配(MD/MT)失败。
- 检查当前运行时:用
get_property(_rtu TARGET ${PROJECT_NAME} PROPERTY VS_DEBUGGER_ENVIRONMENT)不靠谱,应改用set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$:Debug>") - 更稳妥的做法是避免隐式依赖
Threads,改用target_link_libraries(myapp PRIVATE Threads::Threads)—— 这会触发 CMake 内置逻辑适配各平台 - MinGW-w64 用户注意:
Threads::Threads在旧版 CMake(target_link_libraries(... PRIVATE pthread)
生成器(Generator)选错会导致整个构建失败
不是所有 CMake 命令都能通用。比如 cmake -G "Unix Makefiles" 在 Windows 上能跑,但生成的 Makefile 依赖 sh 和 GNU 工具链,若没装 MSYS2 或 WSL 就会卡在 fork: Resource temporarily unavailable。
立即学习“C++免费学习笔记(深入)”;
- Windows 推荐:
cmake -G "Visual Studio 17 2022" -A x64(VS2022)或cmake -G "Ninja"(需提前装 Ninja) - macOS 注意:
Xcode生成器会生成 .xcodeproj,但调试时可能找不到libc++.dylib,需在CMakeLists.txt中加set(CMAKE_MACOSX_RPATH ON) - Linux 上若用
Ninja却没装,错误信息是Unknown generator "Ninja",不是“command not found”,容易误判
最易被忽略的一点:CMake 缓存(CMakeCache.txt)一旦生成,CMAKE_CXX_STANDARD 等变量就不会被重新读取,即使你改了 CMakeLists.txt。每次调大标准版本或换编译器,务必删掉 build 目录重来,否则看似配置了 C++20,实际还是按缓存里的 C++14 构建。










