makefile
*和%的区别: SRCS := $(Wildcard *.c) OBJS := $(patsubst %.c,%.o,$(SRCS)) *:表示在当前目录下的所有.c文件 %:表示所有的.c文件中的一个.c文件
Makefile规则
生成目标:make [目标],如果make后面没有跟目标,那就生成makefile中第一个规则的第一个目标(即test);也可以make指定的目标,如make clean
命令被执行的 2 个条件:
1. 依赖文件比目标文件新
2. 没有目标文件。
为什么要伪目标?
因为在执行像make clean这样的指令时,由于他没有依赖,如果在该目录下有一个clean文件或目录,那么rm *.o test命令就无法执行,因为不满足命令被执行的第一个条件,所以要用PHONY来说明目录下的clean文件或目录不是目标(即现在还有目标文件,所以make clean时,命令Rm *.o test会被执行)
有a.c 、b.c、 c.c三个文件
目标:依赖(一个或多个依赖文件)
[TAB]命令
Test: a.o b.o c.o gcc -o test $^($^ 表示所有的依赖文件) %.o : %.c gcc -c -o $@ @<($@:表示目标; $<:表示依赖中的第一个文件) .PHONY:clean (伪目标) clean: Rm *.o test
通配符:
$@ 表示目标
$< 表示依赖的第一个文件
$^ 表示所有的依赖文件
变量:
:= #及时变量 如A = XX;A的值即刻确定,在定义时即确定
= #延时变量 如B :=xx; B的值在使用时才确定
?= #延时变量,如果第一次定义才起效,如果在前面该变量已定义则忽略这句
+= #附加,他是及时变量还是延时变量取决于前面的定义
A : = $(C) #A是即使变量,所以在定义时即可确定,但是C还没有定义,所以A为空 B = $(C)#B是延时变量,在使用时才确定,所以下面输出B=ABC123 C = ABC#在定义时C为延时变量 D = 100ASK D ?=ZJ#这条语句被忽略 all: echo A = $(A)#这里输出A = echo B= $(B) echo D= $(D) C +=123#附加时,这个就是延时变量,所以在使用时才确定,所以$(C)为ABC123
函数($是引用或调用函数):
$(foraech var,list,text)#调用foreach函数,对 list 中的每一个元素,取出来赋给 var,然后把 var改为text所描述 的形式
$(filter pattern...,text)#调用filter 函数,在text中取出符合pattern格式的值
$(filter-out pattern...,text)在text中取出不符合pattern格式的值
$(wildcard pattern)pattern定义文件名的格式,wildcard取出当前目录存在的pattern格式文件
$(patsubst pattern,replacement,$(var))替换
在test下,建立a.c和b.c2个文件,在sub目录下,建立sa.c和sb.c2 个文件
建立一个简单的Makefile
src=$(wildcard .c ./sub/.c) #输出a.c b.c ./sub/sa.c ./sub/sb.c2
dir=$(notdir $(src)) #输出a.c b.c sa.c sb.c notdir : 去除路径
obj=$(patsubst %.c,%.o,$(dir) )#输出a.o b.o sa.o sb.o