- Makefile格式:
目标文件:依赖文件
[Tab] 命令
- Makefile规则:
1. 当"目标文件"不存在或某个依赖文件比目标文件"新"时则执行"命令";
2. 使用make命令时[make 目标],若指定目标不存在,默认为第一个目标;
新建一个名为Makefile的文件,写入:
----------------------------------------------
test:a.o b.o
gcc -o test a.o b.o
a.o:a.c
gcc -c -o a.o a.c
b.o:b.c
gcc -c -o b.o b.c
-----------------------------------------------
[make]执行(会自动执行当前Makefile文件中的第一个目标——规则二)
第一次执行:gcc -c -o a.o a.c gcc -c -o b.o b.c gcc -o test a.o b.o
修改a.o后第二次执行:gcc -c -o a.o a.c gcc -o test a.o b.o
(会根据文件更新的时间戳来决定哪些文件需要重新编译——规则一)
通配符:$@表示目标 $<表示第一个依赖 $^表示所有依赖
等价Makefile文件:
----------------------------------------------
test:a.o b.o
gcc -o test $^
%.o:%.c
gcc -c -o $@ $<
-----------------------------------------------
新建一个名为Makefile的文件,写入:
----------------------------------------------
test:a.o b.o
gcc -o test $^
%.o:%.c
gcc -c -o $@ $<
clean:
rm *.o test
-----------------------------------------------
[make clean]执行
若当前目录下有clean的同名文件,该操作会因缺少依赖文件而报错
解决办法:
使用关键字PHONY将clean作为假想目标
----------------------------------------------
test:a.o b.o
gcc -o test $^
%.o:%.c
gcc -c -o $@ $<
clean:
rm *.o test
.PHONY:clean
-----------------------------------------------
Makefile中的变量:
即时变量(简单变量):变量的值在定义时即刻确定;
延时变量:变量的值在使用时才确定;
运算符确定的变量类型:
:= 即时变量
= 延时变量
?= 延时变量 (首次定义时有效,若变量已被定义则忽略此句)
+= 即时变量还是延时变量取决于先前定义
Makefile的文件 [make]执行输出 A:=$(D)
B=$(D)
C=abc
C?=123
D=smile
all:
@echo A=$(A)
@echo B=$(B)
@echo C=$(C)
D+=aaa
A=
B=smileaaa
C=abc
tip:
echo 在shell中显示该条命令和其输出结果
@echo 不在shell中显示该条命令,只显示其输出结果
Makefile中的函数:
1.$(foreach var,list,text) 对list中的每个var都执行text操作
Makefile的文件 [make]执行输出 A=a b c
B=$(foreach f,$(A),$(f).o)
all:
@echo B=$(B)
B=a.o b.o c.o
2.$(patsubst pattern,replacement,text) 将text中取出的pattern格式替换成replacement格式
(text中不符合pattern格式的不会被替换)
Makefile的文件 [make]执行输出 A=a.c b.c c.c 123
B=$(patsubst %.c,%.o,$(A))
all:
@echo B=$(B)
B=a.o b.o c.o 123
3.$(wildcard pattern) 取出该目录下所有pattern格式的文件名
Makefile的文件 [make]执行输出 files=$(wildcard *.o)
all:
@echo files=$(files)
files=a.o b.o c.o
4.$(filter pattern...,text) 在text中取出符合pattern格式的值
$(filter-out pattern...,text) 在text中取出不符合pattern格式的值
Makefile的文件 [make]执行输出 A=a b c d/
B=$(filter %/,$(A))
C=$(filter-out %/,$(A))
all:
@echo B=$(B)
@echo C=$(C)B=d/
C=a b c
Makefile中的依赖:
gcc -M c.c 打印c.c的依赖文件 gcc -M -MF c.d c.c 把依赖文件写入c.d gcc -c -o c.o c.c -MD -MF c.d 编译c.o成c.c,同时把依赖文件写入c.d 新建一个名为Makefile的文件,写入:
----------------------------------------------
test:a.o b.o c.o
gcc -o test $^
%.o:%.c
gcc -c -o $@ $<
clean:
rm *.o test
.PHONY:clean
-----------------------------------------------
[make]执行
若修改c.c的头文件c.h再执行,该操作会因未更新依赖文件而失效
解决办法:
更新依赖时生成.d文件,根据.d文件是否存在进行判断然后更新
----------------------------------------------
objs = a.o b.o c.o
dep_files := $(patsubst %,.%.d, $(objs)) //将objs中的文件xx变成.xx.d
dep_files := $(wildcard$(dep_files)) //dep_files :=.a.o.d .b.o.d .c.o.d
test:$(objs)
gcc -o test $^
ifneq ($(dep_files),) //若dep_files为空则include
include $(dep_files)
endif
%.o:%.c
gcc -c -o $@ $< -MD -MF .$@.d
clean:
rm *.o test
distclean:
rm $(dep_files)
.PHONY:clean
-----------------------------------------------