Makefile
Makefile¶
基础概念¶
Makefile由若干条规则(Rule)构成,每一条规则指出一个目标文件(Target),若干依赖文件(prerequisites),以及生成目标文件的命令。
执行make 参数命令会构建参数对应的规则,若没有参数则默认执行第一条规则。
一条规则格式为目标文件: 依赖文件1 依赖文件2 ...,紧接着,以Tab开头的是命令,用来生成目标文件。
Makefile会自动判断依赖并打印执行命令。
Makefile最大的优势就是增量更新,它会根据依赖文件与目标文件的修改时间来自动判断是否更新
规则详解¶
伪目标¶
我们会希望通过一些规则丰富操作,如清理中间文件。
此时要避免规则被视为目标文件,可引入伪目标标识Phony Target
.PHONY: clean
clean:
rm -f m.txt
rm -f x.txt
命令执行¶
make针对每条命令,都会创建一个独立的Shell环境
为了让命令在同一环境执行,需要连接为一行,采用;分割命令, \换行以便于浏览
;可以换为&&,好处是某条命令执行失败后,后续命令不会继续执行
cd_ok:
pwd; \
cd ..; \
pwd
默认情况下,make会打印出它执行的每一条命令,并且在命令出错后,打印错误并退出
我们可以通过@来取消命令的打印,用-来忽视报错并继续执行
@echo 'not display'
-rm zzz.txt
对于重复的命令,我们还可以定义命令包,以define开始,以endef结束
随后可以用$(包名)作为命令。(亦可以用于多行变量的命名)
define run-yacc
yacc $(firstword $^)
mv y.tab.c $@
endef
变量使用¶
Makefile,中可以命名变量(一般大写)来代替重用内容,变量定义用变量名 = 值
变量命名还可以使用make的模式替换的内置语法,如OBJS = $(SRCS:.c=.o)
同时我们可以使用Makefile中的自有变量:
-
$(CC): 表示C编译器的名字
-
$@:表示目标文件
-
$^:表示所有依赖文件
-
$<:表示第一个依赖项
-
$*:表示目标文件名的主体部分(不包括扩展名)
-
$(*D):表示目标文件主体部分的目录。如果目标文件主体是
dir/target,则$(*D)为dir。 -
$(*F):表示目标文件主体部分的文件名。如果目标文件主体是
dir/target,则$(*F)为target。
规则进阶¶
模式规则¶
Makefile中,我们可以自定义模式规则,make会依据规则模式自动匹配,如:
# 模式匹配规则:当make需要目标 xyz.o 时,自动生成一条 xyz.o: xyz.c 规则:
%.o: %.c #`%`是一个通配符,表示任意数量的字符
@echo 'compiling $<...'
cc -c -o $@ $<
%是一个通配符,表示任意数量的字符
自动生成依赖¶
可以通过Makefile中的内置函数帮助依赖生成
-
wildcard
语法如,
$(wildcard pattern),用于匹配文件模式并返回符合模式的文件列表。
-
patsubst
语法如,
$(patsubst pattern,replacement,text)用于字符串替换。
-
findstring
语法如
$(findstring a,a b c)#返回a如果
find是in的子串,则返回find