能跑通的cmakelists.txt核心三行是:cmake_minimum_required(version 3.10)、project(hello cxx)、add_executable(hello main.cpp),且前两行顺序不可颠倒,否则解析报错;项目名须无空格,源文件路径需写全,构建必须采用out-of-source方式。

直接写一个能跑通的 CMakeLists.txt,核心就三行:最低版本、项目名、可执行目标。其他都是可选但容易踩坑的细节。
cmake_minimum_required 和 project 顺序不能错
这两行必须出现在文件最开头,且 cmake_minimum_required 要在 project 之前。CMake 解析时会先检查版本兼容性,再初始化项目上下文。如果颠倒,会报错:
Parse error in CMakeLists.txt: project command must be before add_executable
-
cmake_minimum_required(VERSION 3.10)是安全下限;低于 3.10 的版本不推荐用于新项目(比如target_include_directories在 3.10+ 才稳定) -
project(hello CXX)中显式声明CXX表示启用 C++ 支持,避免某些旧环境默认只开 C - 项目名不要用空格或特殊字符,否则后续生成的 target 名、缓存变量名可能出问题
add_executable 里别硬写源文件路径
新手常把所有 .cpp 文件名逐个列在 add_executable 后面,看似简单,实则难维护。更可靠的做法是用变量聚合:
set(SOURCES main.cpp utils.cpp)
add_executable(hello ${SOURCES})
- 变量名
SOURCES是惯例,不是关键字;但用它能被 IDE(如 CLion)和工具链更好识别 - 避免用
aux_source_directory自动收文件——它不递归子目录,且顺序不可控,链接失败时难以排查 - 如果源文件在子目录(如
src/),路径要写全:src/main.cpp,否则 CMake 找不到
头文件找不到?优先用 target_include_directories
老教程常用 include_directories 全局加路径,但这是反模式。它会让所有 target 都“看到”这些头文件,破坏封装,还可能引发隐式依赖。
正确做法是绑定到具体 target:
add_executable(hello main.cpp)
target_include_directories(hello PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include)
-
PRIVATE表示该路径只对hello有效,不传递给依赖它的其他 target -
${CMAKE_CURRENT_SOURCE_DIR}比${PROJECT_SOURCE_DIR}更精准——前者是当前CMakeLists.txt所在目录,后者是顶层项目根目录 - 如果头文件在
include/下,且你写了#include "utils.h",那路径就得是include/,不是include/utils.h
构建时一定要 out-of-source
别在源码目录下直接 cmake .。临时文件(CMakeCache.txt、CMakeFiles/、Makefile)混进源码树,不仅污染 Git,还可能触发 IDE 误索引或编译器缓存异常。
- 固定流程:
mkdir build && cd build && cmake .. && make - CLion 默认用
cmake-build-debug,VS Code + CMake Tools 插件也默认开独立构建目录 - 如果改了
CMakeLists.txt又想重来,直接删掉整个build/目录比手动清理安全得多
最容易被忽略的是:CMake 不会自动重载你改过的 CMakeLists.txt。哪怕只改了一行 set,也得重新运行 cmake ..(不是 make)才能生效——这点和 Makefile 完全不同。











