cmake不是编译器或构建工具,而是跨平台构建系统生成器,通过解析cmakelists.txt生成makefile、.vcxproj等构建文件;报错多源于路径错误(如未在cmakelists.txt同级目录执行cmake ..)、源文件路径相对项目根目录不正确、set(cmake_cxx_standard)位置不当或缓存未更新。

直接说结论:CMake 不是编译器,也不是构建工具本身,它只负责生成构建工具能读懂的配置文件(比如 Makefile 或 Visual Studio 的 .vcxproj)。你写错 CMakeLists.txt,或者跳过「外部构建目录」这步,90% 的报错都源于此。
cmake .. 报错 “CMakeLists.txt not found”
这不是路径问题,而是你没在正确的目录里执行命令。CMake 默认只在当前目录找 CMakeLists.txt,且必须是该目录下 —— 不能靠相对路径“猜”。
- 错误做法:
cd src && cmake ..(假设CMakeLists.txt在上层目录),但 CMake 会去src/..即项目根目录找,没错;但如果误建了build目录在别处,或CMakeLists.txt实际放在project/而你进了project/src再执行cmake ..,就可能因拼写/大小写/隐藏文件导致失败 - 正确做法:先确认
CMakeLists.txt存在且名字完全匹配(注意大小写,Linux/macOS 区分),然后cd到它的**同级目录**,再mkdir build && cd build && cmake .. - 验证方式:运行
ls -la看当前目录是否有CMakeLists.txt;没有?那就不是“上一级”,而是你 cd 错了
add_executable 编译失败:找不到源文件
add_executable 中列出的源文件路径是相对于 CMakeLists.txt 所在目录的,不是相对于构建目录,也不是相对于当前 shell 路径。
- 常见错误:目录结构是
project/CMakeLists.txt、project/src/main.cpp,但你在CMakeLists.txt里写了add_executable(app src/main.cpp)—— 这是对的;但如果误写成add_executable(app ./src/main.cpp)或add_executable(app ../src/main.cpp),CMake 会报Cannot find source file - 路径必须是“项目内相对路径”,不支持通配符(如
*.cpp)直接展开,需用file(GLOB ...)显式收集(但不推荐用于生产,因新增文件不会自动触发重配置) - 如果源文件带空格或特殊字符,必须用引号包裹:
add_executable(app "src/my file.cpp")
set(CMAKE_CXX_STANDARD 17) 不生效
这条命令必须出现在 project() 之后、add_executable() 或 add_library() 之前,否则对后续目标无效。
- 典型失效场景:
project(MyApp)→add_executable(app main.cpp)→set(CMAKE_CXX_STANDARD 17);此时app仍按默认标准(通常是 C++98 或 C++14)编译 - 更可靠的做法是直接设目标属性:
set_property(TARGET app PROPERTY CXX_STANDARD 17),这样精准绑定到具体 target - 若用
target_compile_features(app PRIVATE cxx_std_17),还能让 CMake 自动检查编译器是否支持,并在不支持时报错,比单纯设标准更健壮
构建后找不到可执行文件或库文件
默认输出路径由 CMake 内置变量控制,不是当前目录,也不是 build/ 根目录,而是在 build/ 下的子目录中,比如 build/bin/ 或 build/lib/ —— 除非你显式指定。
- 执行
cmake --build .后,先看build/CMakeFiles/下有没有compile_commands.json,有说明构建成功;再查build/下是否存在bin/、lib/或直接平铺的可执行文件名 - 最稳妥的方式是用
cmake -DCMAKE_RUNTIME_OUTPUT_DIRECTORY=../bin -DCMAKE_LIBRARY_OUTPUT_DIRECTORY=../lib ..配置阶段就指定输出位置 - 如果用了
install()命令,那最终产物在build/install/(默认前缀),而不是build/里
真正容易被忽略的是:CMake 的缓存机制。一旦 build/ 目录里生成了 CMakeCache.txt,改了 CMakeLists.txt 里的 set 或 project,不删缓存或不重新 cmake ..,旧值就会一直生效 —— 这比语法错误更难排查。











