首页 > 代码库 > makefie文件的基本说明和使用

makefie文件的基本说明和使用

1. Makefile的三要素(构成一个规则):
目标:依赖 //目标在前,依赖在后,分号分开
命令 //命令前面一个tab缩进
2. 举例说明:
cal:add.c sub.c #直接依赖.c文件
gcc -c add.c sub.c -o cal
3. 举例说明拆分演进
cal:add.o sub.o #改为依赖.o文件
gcc add.o sub.o -o cal
add.o:add.c #.o文件依赖.c文件
gcc -c add.c #gcc -c生成add.o文件
sub.o:sub.c #.o文件依赖.c文件
gcc -c sub.c #gcc -c生成sub.o文件
4. 总结
最终目标写在第一条,比如上面的拆分演进里,目标cal写在第一条,最终目标依赖的东西如果存在,则直接执行,如果不存在,再往下查找依赖,以此类推。
从上往下查找依赖,以此类推,树状结构。
从下往上执行命令,最终生成第一条的终极目标。
附:是否重新执行命令(编译),是比较各个目标和自身依赖的时间来确定的(包括最终目标和各个子目标)。正常情况目标是要比依赖晚的,因为目标是由依赖生成的嘛,如果依赖修改了,那依赖的时间就比目标的晚了,那就要重新编译了。
5. 使用Makefile的变量
obj=add.o sub.o #自定义变量
target=cal #自定义变量
$(target):$(obj) #这里的$(自定义变量) 表示引用自定义变量
gcc $(obj) -o $(target)
%.o:%.c #模式匹配使用%,比如$(obj)匹配后变为add.o:add.c,sub.o:sub.c
gcc -c $< -o $@ #变量$<表示规则里的第一个依赖(比如add.o:add.c规则里的第一个依赖就是add.c,当然这个规则本身就只有一个依赖),$@表示规则里的目标
6. 使用Makefile的变量
obj=add.o sub.o
target=cal
$(target):$(obj)
$(CC) $^ -o $@ #变量CC是Makefile的预定义变量,默认值是cc,也就是gcc, $^表示规则里的所有依赖
%.o:%.c
$(CC) -c $< -o $@ #变量$<,$@,$^称为自动变量,只能在规则里的命令里面使用
7. Makefile的函数使用
src=http://www.mamicode.com/$(wildcard ./*.c) #wildcard是函数名,./*.c是函数参数,这里表示当前目录下的所有.c文件,多个参数之间使用逗号分开,$表示取值;整体就是查找当前目录下的所有.c文件
obj=$(patsubst ./%.c, ./%.o, $(src)) //字符串替换,替换名称.c为.o,%是通配符
target=cal
$(target):$(obj)
$(CC) $^ -o $@
%.o:%.c
$(CC) -c $< -o $@
其他函数:$(subst FROM,TO,TEXT),$(patsubst PATTERN,REPLACEMENT,TEXT),$(strip STRINT),$(findstring FIND,IN)等等,更多可参考GNU make手册
8.make clean
.PHONY:clean #声明虚伪目标,这样就不会比较目标时间了,防止当前目录下刚好有一个clean文件,误当作目标拿来比较,从而提示你clean是最新的,而不执行clean操作
clean: #没有依赖的情况
rm -f $(obj) $(target) #删除当前目录下的.o文件和cal文件
执行:make clean #执行时指定clean目标,clean目标和cal目标是没有任何关系的
附:直接执行make,是执行第一个目标;make [目标],是执行指定的目标。
9. -命令 #加上-,表示如果命令有误,就忽略它继续执行下去,如果不加-,一旦命令有误就立刻终止执行了。
举例说明:-rm /test 删除根目录下的test文件需要root权限,所以报错,但是加了-,会继续执行其他命令而不会终止。

10.更多参考GNU make手册 

makefie文件的基本说明和使用