CMake 和 Makefile 是两个在软件开发过程中常用的构建工具,尽管它们处理的任务有些类似,但它们的用途和工作方式有所不同。
Makefile
Makefile
是 make
工具使用的脚本文件。make
是一个构建自动化工具,广泛用于 Unix/Linux 环境中。Makefile
通常包含一系列规则,用于指定如何编译和链接程序。其基本语法结构如下:
target: dependencies
command
这里是一个基本的示例:
# 变量定义
CC = g++
CFLAGS = -Wall -std=c++11
# 目标和依赖关系
all: myprogram
myprogram: main.o foo.o bar.o
$(CC) $(CFLAGS) -o myprogram main.o foo.o bar.o
main.o: main.cpp
$(CC) $(CFLAGS) -c main.cpp
foo.o: foo.cpp
$(CC) $(CFLAGS) -c foo.cpp
bar.o: bar.cpp
$(CC) $(CFLAGS) -c bar.cpp
# 清理目标
clean:
rm -f myprogram main.o foo.o bar.o
在这个例子中,Makefile
定义了如何编译和链接一个叫做 myprogram
的可执行文件。all
是一个伪目标,它表示 make
在没有指定目标时默认执行的任务。
CMake
CMake
是一个跨平台的自动化构建工具,它生成特定于平台的构建系统文件,如 Unix/Linux 的 Makefile
、Windows 的 Visual Studio
项目文件等。在这种情况下,CMake 更像是一个“生成工具的生成工具”。
CMake 使用 CMakeLists.txt
文件描述项目的构建过程。以下是一个基本示例,与上面的 Makefile 示例做对应:
项目结构:
MyProject
├── CMakeLists.txt
├── main.cpp
├── foo.cpp
└── bar.cpp
CMakeLists.txt:
cmake_minimum_required(VERSION 3.10)
project(MyProject)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)
add_executable(myprogram main.cpp foo.cpp bar.cpp)
通过运行以下命令,CMake 将生成平台特定的构建文件,例如在 Unix/Linux 上生成 Makefile
:
mkdir build
cd build
cmake ..
然后可以使用 make
命令来编译项目:
make
CMake 和 Makefile 的关系
-
生成方式不同:
Makefile
手动编写并定义所有构建规则。CMakeLists.txt
描述项目的构建配置,CMake 将其转换为特定平台的构建文件(包括Makefile
)。
-
跨平台性:
Makefile
主要用于 Unix/Linux 环境,尽管也有 Windows 版本的make
工具。CMake
是跨平台的,可以生成不同平台(Unix, Windows, macOS 等)的构建文件,例如 Unix 上的Makefile
、Windows 上的Visual Studio
项目文件。
-
复杂项目管理:
Makefile
在处理复杂的项目(例如有很多子目录和多种依赖关系的项目)时会显得繁琐,需要手动管理依赖关系。CMake
提供了更高级的功能,例如自动处理依赖关系、导入外部库等,简化了复杂项目的管理。
-
可扩展性:
Makefile
是一个比较底层的工具,可扩展性较差,需要手动实现许多功能。CMake
提供了许多内置的模块和功能,可以很方便地扩展和定制。
-
生成过程:
- 使用
Makefile
,所有构建规则都要在文件中明确指定,一旦项目变大,管理会变得复杂。 - 使用
CMake
,构建规则通过 CMake 脚本定义,CMake 可以自动生成对应的Makefile
或其他构建系统文件,这大大简化了项目的管理和依赖关系处理。
- 使用
示例对比
Makefile 示例:
CC = g++
CFLAGS = -Wall -std=c++11
TARGET = myprogram
all: $(TARGET)
$(TARGET): main.o foo.o bar.o
$(CC) $(CFLAGS) -o $(TARGET) main.o foo.o bar.o
main.o: main.cpp
$(CC) $(CFLAGS) -c main.cpp
foo.o: foo.cpp
$(CC) $(CFLAGS) -c foo.cpp
bar.o: bar.cpp
$(CC) $(CFLAGS) -c bar.cpp
clean:
rm -f $(TARGET) main.o foo.o bar.o
CMakeLists.txt 示例:
cmake_minimum_required(VERSION 3.10)
project(MyProject)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)
add_executable(myprogram main.cpp foo.cpp bar.cpp)
总结
Makefile
是make
工具的输入文件,定义了如何构建项目。它适用于手动编写简单项目的构建规则,但在处理复杂项目时可能较为繁琐。CMake
是一个更高级的构建系统生成工具,通过CMakeLists.txt
文件描述项目的构建过程,再生成特定平台的构建文件(包括Makefile
)。它提供了更多的高级功能和更好的跨平台支持。
简而言之,CMake
可以被看作是一个更强大、跨平台的项目构建和管理工具,它能够生成 Makefile
,同时还能够生成其他类型的构建文件,简化复杂项目的构建和管理。
下一篇文章讲解 CMake如何生成makefile文件。