cmake . 表示在当前目录执行内部构建,所有生成文件污染源码目录;cmake .. 表示在独立构建目录中执行外部构建,所有中间产物隔离存放,是现代CMake标准做法。

cmake . 和 cmake .. 的区别在哪
直接在源码目录执行 cmake . 是「内部构建」,所有生成文件(CMakeCache.txt、Makefile、CMakeFiles/)全堆在源码根目录里,污染项目结构,git 提交时容易误提交,协作时也难清理。
cmake .. 必须配合新建的独立构建目录(比如 build/),是「外部构建」——这是现代 CMake 的标准做法。
- 执行顺序固定:
mkdir build && cd build && cmake .. -
..指向上级目录的CMakeLists.txt,CMake 读取它,但所有中间产物只留在当前build/目录内 - 想换编译器或配置?删掉整个
build/重来就行,源码目录干干净净 - Windows 上用 Visual Studio 生成器时,
cmake -G "Visual Studio 17 2022" ..也必须在空构建目录中运行
cmake_minimum_required 版本写太低会怎样
写 cmake_minimum_required(VERSION 2.8) 看似兼容老系统,实际埋雷:很多现代语法和安全机制根本不可用,比如 target_compile_features()、find_package(... CONFIG REQUIRED) 在 3.10 以下不支持,第三方库(如 spdlog、fmt)的官方 CMake 配置也普遍要求 3.14+。
当前(2026 年)建议最低写 cmake_minimum_required(VERSION 3.18),理由很实在:
- Ubuntu 22.04+/Debian 12+、macOS Homebrew 默认 CMake ≥ 3.22
- VS2022 自带 CMake 工具链默认 3.25+
- 能用
add_subdirectory()安全包含子模块,避免include_directories()全局污染 - 支持
FetchContent_Declare()替代手动 git clone + 子模块,依赖管理更可控
add_executable() 里传路径还是文件名
add_executable() 第二个参数只接受「相对于当前 CMakeLists.txt 所在目录的路径」,不是绝对路径,也不能带通配符(*.cpp)。
常见错误包括:
- 写成
add_executable(app /home/user/proj/src/main.cpp)→ 报错:File /home/user/proj/src/main.cpp does not exist - 写成
add_executable(app src/*.cpp)→ 不展开,当成字面字符串,找不到文件 - 源文件在子目录,但没写对相对路径:
add_executable(app sub/main.cpp)才对,而不是add_executable(app main.cpp)
正确做法是:把 CMakeLists.txt 放在源码同级或上层,用明确路径引用;多文件就列全,或用 set() 分组:
set(SRC_LIST
src/main.cpp
src/utils.cpp
src/core/log.cpp
)
add_executable(app ${SRC_LIST})
project() 命令后面加语言列表有必要吗
写 project(myapp CXX) 或 project(myapp C CXX) 不是可有可无的装饰——它直接影响 CMake 对编译器的探测逻辑和默认标准。
不写语言列表时,CMake 会尝试启用所有已知语言(C、CXX、ASM),哪怕你只用 C++,也会额外检查 C 编译器是否存在,慢且可能触发意外警告;而显式声明后:
-
project(myapp CXX)→ 只找 C++ 编译器(g++、clang++、cl),跳过 C 探测 -
project(myapp C)→ 只启用 C 标准(CMAKE_C_STANDARD),CMAKE_CXX_STANDARD不生效 - 后续调用
enable_language(CXX)才能补开 C++ 支持,但不如一开始就写清楚
真实项目中,99% 的 C++ 项目应写 project(myapp CXX);混用 C 和 C++ 的(如嵌入式驱动+应用层),才写 project(myapp C CXX)。
cmake 配置阶段直接失败,报错信息常藏在 CMakeCache.txt 或终端最后几行,别只盯着 make 阶段。


















