Featured image of post Makefile

Makefile

Makefile

Makefile实现项目自动化构建


核心概念

为了提高项目的开发效率,所以GNU组织就在Linux系统中集成了Make工具,而Makefile就属于Make工具的一部分。

Makefile是自动化构建脚本,配合make指令使用,解决多文件编译繁琐问题,核心功能:编译源码、链接可执行文件、清理中间文件。

执行方式

安装:sudo apt install make

执行:输入make指令时,会执行当前目录下的Makefile

make是一个shell命令,执行时依次查找GNUmakefile makefile Makefile

基本规则

1
2
目标 :先决条件(依赖)
	命令

目标是需要生成的程序的名称,可能一开始不存在

先决条件也是文件,用于生成目标用的

一个目标可能依赖多个文件,则每个文件中间使用空格

只有需要执行的命令前可以存在Tab制表符,而且必须使用

伪目标

1
2
3
目标 
	命令
.PHONY:目标

伪目标,没有先决条件

一个Makefile文件中,不可以只有伪目标

make的流程

先发现最终目标

准备执行动作时发现目标依赖文件不存在,则会在makefile文件寻找生成该依赖文件的规则。

如果找到则继续执行,如果未找到,则报错,所以可以理解为make会递归在Makefile文件中进行规则执行


variable变量

1
变量名 = 变量值

调用时$(变量名)

进行赋值时,等号两边有空格

系统内置变量

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
AR	函数库打包程序,可创建静态库.a文档,默认是“ar”
AS	汇编程序,默认是“as”
CC	C编译器,默认是“cc”
CXX	C++编译器,默认是“g++”
CPP	C程序的预处理器,默认为是“$(CC) -E”
RM	删除命令,默认是“rm -f”
ARFLAGS	执行AR命令的命令行参数。默认值是“rv”
ASFLAGS	汇编器AS的命令行参数(明确指定“.s”或“.S”文件时)
CFLAGS	执行CC编译器的命令行参数(编译.c源文件的选项)
CXXFLAGS	执行g++编译器的命令行参数(编译.cc源文件的选项)

自动化变量

1
2
3
4
5
6
@	规则的目标的名字
%	代表所在规则的静态库的一个成员名
<	第一个先决条件的名字
	所有时间戳比目标文件新的依赖文件列表,用于增量编译
+	代表其所在规则的依赖列表
*	在模式规则和静态模式规则中,代表茎

变种变量

在自动化变量后加入“D”或者“F”字符

D:路径

F:文件

用于快速获取文件目录/文件名

变量名 含义 备注
@D 代表目标文件的目录部分(去掉目录部分的最后一个斜杠) 如果“$@”是“dir/foo.o”,那么“$(@D)”的值为“dir”。如果“$@”不存在斜杠,其值就是“.”(当前目录)。注意它和函数“dir”的区别
@F 目标文件的完整文件名中除目录以外的部分(实际文件名) 如果“$@”为“dir/foo.o”,那么“$(@F)”只就是“foo.o”。“$(@F)”等价于函数“$(notdir $@)”
*D 代表目标茎中的目录部分
*F 代表目标茎中的文件名部分
%D 当以如“archive(member)”形式静态库为目标时,表示库文件成员“member”名中的目录部分 仅对“archive(member)”形式的规则目标有效
%F 当以如“archive(member)”形式静态库为目标时,表示库文件成员“member”名中的文件名部分 仅对“archive(member)”形式的规则目标有效
<D 代表规则中第一个依赖文件的目录部分
<F 代表规则中第一个依赖文件的文件名部分
^D 代表所有依赖文件的目录部分 同一文件不可重复
^F 代表所有依赖文件的文件名部分 同一文件不可重复
+D 代表所有依赖文件的目录部分 同一文件可重复
+F 代表所有依赖文件的文件名部分 同一文件可重复
?D 代表被更新的依赖文件的目录部分。
?F 代表被更新的依赖文件的文件名部分。

静态规则

工作原理是:$(OBJ)被称为原始列表,即(a.o b.o x.o y.o),紧跟在其后的%.o被称为匹配模式,含义是在原始列表中按照这种指定的模式挑选出能匹配得上的单词(在本例中要找出原始列表里所有以.o为后缀的文件)作为规则的目标。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
OBJ = a.o b.o c.o	

image:$(OBJ)
	$(CC) $(OBJ) -o image
$(OBJ):%.o:%.c
	$(CC) $(^) -o $(@) l -c -Wal
	
clean:
	$(RM) $(OBJ) image
.PHONY: clean

img

img

本例中%.o:%.c的意思就是:每一个匹配出来的目标所对应的依赖文件是同名的.c文件

%可以理解为通配符


积累

ifdef用于判断一个变量是否被定义

+=追加赋值,向已有变量的末尾追加内容,追加时会自动在原有内容和新内容之间加空格

:=简单展开赋值(立即展开),赋值时立即展开右侧内容,将结果存入变量

?=条件赋值,仅当变量未被定义/为空时,才执行赋值。若变量已有值,则赋值语句无效

LDFLAGS给链接器传递参数的环境/自定义变量,先搜索自定义的路径,再搜索默认路径

1
OBJECTS := $(patsubst %.c,%.o,$(wildcard *.c))

$(wildcard *.c)获取工作目录下所有的.c文件

使用wildcard函数可以使通配符生效

patsubst %.c,%.o将所有的.c文件替换为.o

最后更新于 2026-03-28 13:56
...