CMake 和 Make 有什么区别?
更新时间:2026-09-20。问题驱动短答页。新手常把二者当二选一,其实它们处在构建链的不同层。命令速查见 开发构建命令:gcc/make/cmake,C 项目手写 Makefile 见 多文件工程。
一句话回答
make 是真正执行编译命令的构建工具,读的是 Makefile;cmake 是「生成构建文件」的元构建工具(meta build),它读 CMakeLists.txt,帮你生成 Makefile(或 Ninja、Visual Studio 工程),最后还是调用 make/ninja/编译器去编译。 二者是上下游,不是替代。
对照
| make(Makefile) | CMake(CMakeLists.txt) | |
|---|---|---|
| 角色 | 构建执行器 | 构建系统生成器 |
| 输入 | Makefile | CMakeLists.txt |
| 产物/动作 | 直接调 gcc 编译链接 | 先生成 Makefile/Ninja/.sln,再构建 |
| 跨平台 | 弱(Windows 上很别扭) | 强,一套配置生成各平台工程 |
| 依赖查找 | 手写规则,费劲 | find_package/target_link_libraries 内建 |
| 适合 | 小项目、教学、单平台脚本 | 中大型 C/C++ 工程、跨平台、第三方库多 |
典型流程
bash
# 纯 make:直接在当前目录读 Makefile
make
make -j8
# CMake:configure + generate,再 build
cmake -S . -B build -G Ninja # 生成阶段:探测编译器/依赖,写 build/
cmake --build build -j8 # 构建阶段:底层调 ninja 或 makeCMake 的三阶段:configure(探测平台/编译器/库)→ generate(按生成器产出 Makefile/Ninja 工程)→ build(实际编译)。-S . -B build 是 out-of-source 构建,产物全部进 build/,污染源码目录的只有这一个文件夹。
怎么选
- 几个
.c、单平台、想彻底搞懂「依赖即目标」:手写 Makefile 足够且直观。 - 跨平台(Linux/macOS/Windows)、引第三方库、工程上规模:用 CMake,行业事实标准(LLVM、KDE、大量 C++ 库)。
- 想要更快的增量构建,CMake 配 Ninja 生成器,比 make 在大工程上明显快。
常见坑
- 以为 cmake 直接编译:它只生成,真正编译是第二步
cmake --build或 make/ninja。 - 在源码目录直接
cmake .:散落一堆缓存文件,规范做法是 out-of-source(-B build)。 - 改了 CMakeLists 不生效:CMakeCache.txt 缓存了旧探测结果,删
build/重新 configure。 - 找不到库:用
find_package需库提供 config 或装了开发包(-dev/-devel),必要时传-DCMAKE_PREFIX_PATH。 - 把生成的 Makefile 当手写维护:它是产物,应改 CMakeLists 而非改生成文件。
编译链接四阶段与静态/动态库见 编译、链接与 ELF。
总结
make 依据 Makefile 直接调度 gcc 完成编译,CMake 则是读 CMakeLists.txt 的元构建系统,先跨平台探测并生成 Makefile/Ninja/VS 工程、再交由 make 或 ninja 实际构建;小项目、单平台用手写 Makefile 简单直接,跨平台、依赖多、规模大的 C/C++ 工程用 CMake,推荐 -S . -B build 做 out-of-source 构建并用 Ninja 提速,遇到配置不生效就删 build 缓存重新 configure。