cmake . 会将构建产物混入源码目录污染工作区,而 cmake -s . -b build 明确分离源码与构建目录,支持开箱即用的源外构建,是 cmake 3.13+ 官方推荐的现代写法。

cmake . 和 cmake -S . -B build 有什么区别?
直接在源码目录下运行 cmake . 是最简方式,但它会把所有构建产物(CMakeCache.txt、Makefile、CMakeFiles/ 等)混在源码目录里,污染工作区,后续 git status 会看到一堆未跟踪文件。
推荐用 cmake -S . -B build:明确分离源码(-S .)和构建目录(-B build),build 目录可随时删掉重来,不影响源码。这是 CMake 3.13+ 的现代写法,也是官方文档默认推荐的模式。
- 如果 CMake 版本低于 3.13,
-S/-B不可用,只能退回到mkdir build && cd build && cmake .. -
cmake .在某些旧项目或 CI 脚本里还能见到,但新项目别再用 - 执行后必须进
build/目录再运行make,否则会报错“no Makefile in current directory”
make 命令为什么找不到目标?
常见现象是执行 make 后提示 make: *** No targets specified and no makefile found.,本质就两个原因:
-
cmake没成功运行完——检查终端有没有报错,比如Could not find a package configuration file或CMAKE_MINIMUM_REQUIRED version too low - 当前目录不是构建目录——比如你用了
cmake -S . -B build,却在源码根目录下敲make,正确做法是cd build && make - 生成器没选对——CMake 默认可能选了 Ninja(尤其在 Windows 上装了 VS 后),这时生成的是
build.ninja而非Makefile,得用ninja命令而不是make
编译失败时怎么快速定位问题?
不要只盯着最后一行红色错误。CMake 构建失败通常分两层:
- 第一层是
cmake阶段失败:比如add_executable()引用的源文件路径不存在、find_package(OpenCV)找不到库、project()里语言声明和实际文件不匹配(如写了LANGUAGES CXX却只有.c文件) - 第二层是
make阶段失败:比如 C++ 语法错误、头文件未target_include_directories()、链接时缺符号(undefined reference to 'xxx') - 加
make VERBOSE=1可看到真实调用的g++命令,方便验证 include 路径、宏定义、链接顺序是否符合预期
修改源码后要不要重新运行 cmake?
绝大多数情况下不用。CMake 生成的 Makefile 已包含依赖关系,改了 .c 或 .cpp 文件后,直接 make 就会自动重编对应目标。
但以下情况必须重新运行 cmake:
- 改了
CMakeLists.txt本身(比如增删add_executable()、调整set(CMAKE_CXX_STANDARD 20)) - 新增或删除源文件,且没用
file(GLOB ...)动态收集(不推荐这种写法,GLOB 不触发自动重配置) - 切换构建类型(如从
Debug改为Release),需用cmake -DCMAKE_BUILD_TYPE=Release -S . -B build
注意:cmake 命令本身不清理旧缓存,若怀疑配置残留,可删掉整个 build/ 目录再重来——这是最干净的重置方式。











