make
和 cmake
的关系在于它们在软件构建中具有互补性,但目的不同:
make
是一个构建工具,负责执行Makefile
中指定的编译和构建任务。cmake
是一个构建生成工具,负责根据CMakeLists.txt
生成适合平台的构建文件(例如Makefile
或 Visual Studio 项目文件)。cmake
生成Makefile
后,仍然需要使用make
去实际执行构建。
名称来源
make
:make
这个名字来源于“制作”的含义,代表它可以帮助“制作”或构建项目。1977年发布的make
是最早的自动化构建工具之一。cmake
:cmake
是 "Cross-platform Make" 的缩写,表示它可以跨平台生成构建文件。
make
和 cmake
是两种常用的构建工具,它们各有不同的用途和侧重点。以下是它们的主要区别:
1. 定位和功能
- make:
make
是一个构建自动化工具,通过解析Makefile
来执行项目的构建、编译和链接等步骤。它并不负责生成Makefile
,而是依赖于现有的Makefile
文件。 - cmake:
cmake
是一个跨平台的构建系统生成工具,用于生成适配不同平台的构建文件(如Makefile
、Visual Studio 项目文件等)。它的主要任务是解析CMakeLists.txt
文件,将项目配置为特定平台的构建文件,然后由make
等工具执行编译。
2. 文件类型
- make:依赖
Makefile
,直接通过该文件中的规则进行构建。Makefile
是一种较底层、需要手动编写的文件,开发者需要显式定义每一步的依赖关系和命令。 - cmake:使用
CMakeLists.txt
配置文件,自动生成适合平台的Makefile
或项目文件,降低了手动配置构建文件的复杂性。cmake
允许跨平台构建,能够自动根据系统环境设置构建参数。
3. 跨平台支持
- make:主要用于 UNIX 系统(Linux、macOS 等),Windows 下使用较少。在 Windows 下使用
make
时通常需要依赖 Cygwin、MSYS2 等工具。 - cmake:天然跨平台,支持生成适用于多种平台的构建文件,包括 Unix 系统的
Makefile
、Windows 系统的 Visual Studio 项目文件、macOS 的 Xcode 项目文件等。开发者可以在多个平台上使用同一套CMakeLists.txt
文件,而不需要针对不同操作系统分别编写构建文件。
4. 灵活性和复杂性
- make:直接读取
Makefile
,非常灵活。对于简单项目,make
文件内容较少,直接指定编译命令和依赖关系即可。对于复杂项目,Makefile
可能变得难以维护,尤其是依赖关系复杂或跨平台的项目。 - cmake:简化了复杂项目的构建过程,自动管理依赖关系。对于多平台支持、第三方库的引入、复杂的依赖关系等,
cmake
可以简化配置,自动识别平台差异并做适配。
5. 依赖管理
- make:
make
不会自动检测依赖项,需要手动指定源文件间的依赖关系。若依赖关系未设置正确,可能导致文件更新时未自动重新编译。 - cmake:自动检测依赖项,能够在
CMakeLists.txt
中自动生成依赖关系。当文件发生更改时,cmake
会重新生成构建文件,确保依赖关系正确。
使用对比示例
假设有一个简单的 C++ 项目,其中包含 main.cpp
和 utils.cpp
,使用 make
和 cmake
分别配置该项目的构建方式:
使用 make
:
# Makefile
CC = g++
CFLAGS = -Wall -g
TARGET = myapp
all: $(TARGET)
$(TARGET): main.o utils.o
$(CC) -o $(TARGET) main.o utils.o
main.o: main.cpp
$(CC) $(CFLAGS) -c main.cpp
utils.o: utils.cpp
$(CC) $(CFLAGS) -c utils.cpp
clean:
rm -f $(TARGET) *.o
使用 cmake
:
# CMakeLists.txt
cmake_minimum_required(VERSION 3.0)
project(myapp)
# 设置 C++ 标准
set(CMAKE_CXX_STANDARD 11)
# 添加源文件
add_executable(myapp main.cpp utils.cpp)
在 cmake
中,简单的配置可以让 CMake 自动管理依赖,并根据平台自动生成对应的 Makefile
或项目文件。而 make
文件需要显式地列出每个依赖项,并指定编译命令。
总结
特性 | make | cmake |
---|---|---|
作用 | 执行 Makefile 指定的构建规则 | 生成适配平台的构建文件(如 Makefile ) |
配置文件 | Makefile | CMakeLists.txt |
跨平台支持 | 较弱 | 强,支持多平台 |
依赖管理 | 手动管理 | 自动管理 |
适用场景 | 小型项目,简单构建过程 | 跨平台,大型项目,复杂构建需求 |
对于简单项目或仅在 Unix 系统上的构建,make
可能更直观。而对于跨平台的中大型项目,cmake
更适合,能自动生成各平台的构建文件并管理复杂依赖关系。