cmake不是编译器,而是跨平台构建系统生成器,通过cmakelists.txt生成makefile、vs工程等;cmake_minimum_required必须首行声明版本以强制校验,project()显式指定cxx触发正确初始化,外部构建(mkdir build && cd build && cmake ..)是避免污染源码的铁律。

cmake 不是编译器,也不是构建工具本身,它只负责“生成构建文件”——比如 Linux 下的 Makefile、Windows 下的 Visual Studio 工程、macOS 下的 Xcode 项目。你写一次 CMakeLists.txt,就能在不同平台用各自原生工具完成编译。这是它不可替代的核心价值。
为什么 cmake_minimum_required 必须写在第一行?
它不是建议,而是强制守门员:CMake 解析脚本时,第一件事就是检查版本。如果当前 cmake --version 输出的版本低于你写的 VERSION 3.10,整个配置直接中止,连后续语法错误都不会报。
- 不加
FATAL_ERROR也默认终止(CMake 2.6+ 行为),显式写上反而冗余 - 版本选太低(如
2.8)可能触发过时策略,导致target_include_directories等现代命令行为异常 - 版本选太高(如
3.28)会把 Ubuntu 22.04 用户(自带3.22)挡在门外,实际项目推荐3.16或3.20
project() 后面跟 CXX 有什么实际影响?
它不只是“声明语言”,而是触发 CMake 内部初始化逻辑的关键开关:
- 不写语言标识(如
project(foo)),CMake 默认启用C和CXX,但某些旧发行版的 GCC 可能因缺失libstdc++头而静默失败 - 显式写
project(foo CXX),CMake 会自动设置CMAKE_CXX_STANDARD为98,但你仍需手动设为11或更高 - 若项目纯 C,必须写
project(foo C),否则add_executable可能误调 C++ 链接器,导致undefined reference to 'std::...'
为什么一定要用 mkdir build && cd build && cmake ..?
这是“外部构建”(out-of-source build)的铁律,直接在源码目录运行 cmake . 是新手最常踩的坑:
-
cmake .会在源码目录下生成CMakeCache.txt、CMakeFiles/等数十个临时文件,污染 Git 工作区,git status一片红 - 切换构建类型(Debug/Release)必须先
rm -rf *清空,而外部构建目录可随时删掉重来,不影响源码 - 多个构建目标(如
build-debug、build-release)可并存,cmake -DCMAKE_BUILD_TYPE=Debug ..和cmake -DCMAKE_BUILD_TYPE=Release ..互不干扰
add_executable 的源文件路径是相对谁的?
永远相对于 CMakeLists.txt 所在目录,不是当前终端路径,也不是构建目录:
- 如果
CMakeLists.txt在/proj,而main.cpp在/proj/src/main.cpp,就必须写add_executable(app src/main.cpp) - 用
${PROJECT_SOURCE_DIR}拼路径是错的(它指向源码根目录,但 CMake 不支持变量展开进add_executable参数列表) - 多文件项目别硬凑一行,用
set(SRCS src/a.cpp src/b.cpp)再add_executable(app ${SRCS}),便于维护和条件编译
build/ 目录和显式 CXX 标识,后续加库、加测试、切平台时,就不会被莫名其妙的缓存残留或链接失败卡住。











