别裁伪体亲风雅,转益多师是汝师。这篇文章主要讲述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. 总结
【makefie文件的基本说明和使用】 最终目标写在第一条,比如上面的拆分演进里,目标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=https://www.songbingjia.com/android/$(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. 单独编译当前目录下的每一个.c源文件
src = https://www.songbingjia.com/android/$(wildcard *.c) //搜索当前目录的所有.c源文件,如test.c
targets = $(patsubst %.c, %, $(src)) //去掉文件后缀,如test.c变为test
CC = gcc
CFLAGS = -Wall -g //添加调试选项,不需要调试可去掉
all:$(targets)
$(targets):%:%.c //模式匹配%:%.c,直接写成%:%.c也可以
$(CC) $<
-o $@ $(CFLAGS)
.PHONY:clean all//声明伪目标
clean:-rm -rf $(targets)
11.更多参考GNU make手册
推荐阅读
- [ C++ ] C++类与对象(中) 类中6个默认成员函数 -- 运算符重载
- vi操作键盘图
- ubuntu下安装gcc,g++
- window10企业版永久密钥激活
- 提交本地项目到GitHub上
- vi基本操作
- 解决方案 git@github.com出现Permission denied (publickey)
- window下Jekyll+github搭建自己的博客
- 初始化并提交代码到github的步骤