Makefile和Cmake
makefile工具可以看成是一个智能的批处理工具,它本身并没有编译和链接的功能,而是用类似于批处理的方式—通过调用makefile文件中用户指定的命令来进行编译和链接的。
CMake允许开发者编写一种平台无关的 CMakeList.txt 文件来定制整个编译流程,然后再根据目标用户的平台进一步生成所需的本地化 Makefile 和工程文件,如 Unix 的 Makefile 或 Windows 的 Visual Studio 工程。从而做到“Write once, run everywhere”。显然,CMake 是一个比上述几种 make 更高级的编译配置工具。一些使用 CMake 作为项目架构系统的知名开源项目有 VTK、ITK、KDE、OpenCV、OSG 等。
项目规模:对于小型项目,使用Makefile可能更加简单和方便。 但是对于大型项目,使用CMake可以更好地组织和管理代码。 自动化构建:如果您需要自动化构建过程,则CMake是更好的选择,因为它可以自动生成Makefile并自动化构建过程。
一、Makefile
先举一个例子:
all:test@echo "hello all"
在这个简单的实例里面,包含了Makefile三要素:
目标:all
依赖:test
命令:@echo "hello all"
那么,如果我们要编译多个c/cpp文件,该如何做?
.PHONY:main clean
simple:main.o foo.ogcc -o simple main.o foo.o
main.o:main.cgcc -o main.o -c main.c
foo.o:foo.cgcc -o foo.o -c foo.c
clean:rm simple main.o foo.o
如上所示:
我们的目标是生成.PHONY文件,就需要先编译.c文件生成对应的.o文件,.o文件生成
对应的可执行文件。
.PHONY: all clean
:声明all
和clean
是伪目标。即使有同名文件存在,make
仍会执行这些目标的命令。
simple: main.o foo.o
:定义simple
目标,它依赖于main.o
和foo.o
。当这两个对象文件都存在时,会执行后面的命令。
main.o: main.c
和foo.o: foo.c
:分别定义main.o
和foo.o
的依赖关系,表示这两个目标依赖于各自的源文件。
clean:
定义clean
目标,用于清理构建过程中生成的文件。
makefile工作原理
Makefile进阶:
.PHONY: all cleanMKDIR = mkdir
RM = rm
RMFLAGS = -fr
CC = gcc
EXE = complicated
DIRS = objs exes
SRCS = $(wildcard *.c)
OBJS = $(SRCS:.c=.o)all: $(DIRS) $(EXE)
$(DIRS):$(MKDIR) $@
$(EXE): $(OBJS)$(CC) -o $@ $^
%.o: %.c$(CC) -o $@ -c $^
clean:$(RM) $(RMFLAGS) $(DIRS) $(EXE) $(OBJS)
伪目标
.PHONY: all clean
:声明all
和clean
是伪目标,不会与文件名冲突。变量定义
MKDIR = mkdir
:定义创建目录的命令。
RM = rm
:定义删除文件的命令。
RMFLAGS = -fr
:定义删除时的选项,-f
表示强制删除,-r
表示递归删除。
CC = gcc
:定义使用的编译器为 GCC。
EXE = complicated
:定义最终生成的可执行文件名。
DIRS = objs exes
:定义需要创建的目录。
SRCS = $(wildcard *.c)
:获取当前目录下所有的.c
源文件。
OBJS = $(SRCS:.c=.o)
:将源文件列表中的.c
后缀替换为.o
,得到目标文件列表。规则
all: $(DIRS) $(EXE)
:构建目标为all
,依赖于DIRS
和EXE
。
$(DIRS):
:对于每个目录,在构建时创建这些目录。
$(MKDIR) $@
:命令为创建目录,$@
是当前目标(即objs
和exes
)。
$(EXE): $(OBJS)
:生成可执行文件的规则,依赖于所有目标文件。
$(CC) -o $@ $^
:用 GCC 编译所有目标文件生成可执行文件,$@
是目标文件名,$^
是所有依赖文件。
%.o: %.c
:模式规则,表示如何从.c
文件生成.o
文件。
$(CC) -o $@ -c $^
:使用 GCC 编译.c
文件为.o
文件,-c
表示只编译而不链接。清理规则
clean:
:用于清除生成的文件和目录的规则。
$(RM) $(RMFLAGS) $(DIRS) $(EXE) $(OBJS)
:执行删除命令,删除指定的目录、可执行文件和目标文件。
Make和Makefile_make,makefile-CSDN博客进一步了解可以看看这篇博客,讲的很清楚。
二、CMake
我们用Cmake实现makefile相同功能。
# Cmake最低版本号
cmake_minimum_required(VERSION 3.10)# 设置项目名称
project(SimpleProject)# 添加可执行文件
add_executable(simple main.c foo.c)# 清理目标(可选)
set_property(DIRECTORY PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "simple")
进入构建目录并运行 CMake:
mkdir build
cd build
cmake ..
make