makefile代码分析
scripts目录头文件Makefile:
变量定义:
1、通过“:=”来实现
例如:a1:= a.o
a2:= $(a1) b.o
这种方式下变量a1的值是a.o,变量a2的值是a.o b.o。
例如:a1:= $(a2) b.o
a2:= a.o
这种方式下变量a1的值是b.o,而不是“a.o b.o“
也就是说前面的变量不能通过后面的变量来定义。
以上代码用CC代替gcc编译器,用CFLAGS代替-Wall(开警告) -O3(三级优化),用target代替client(客户端)
2、 通过“=”来实现
例如:a1= $(a2)
a2= $(a3)
a3= a.o
这种方式下变量a1的值是a.o
也就是说前面的变量可以通过后面的变量来定义。但使用这种方式定义变量时,要防止出现死循环的情况。
以上代码用Libs代替-lpthread(链接选项)
3、wildcard
格式:$(wildcard模式参数)
功能:列出当前目录下所有符合模式参数的文件名
返回值:当前目录下所有符合模式参数的文件名
例如:result := $(wildcard *.c)
result的值为当前目录下所有的C文件名。
第5行代码中的source为src路径下的所有C文件名
4、patsubst
格式:$(patsubset模式参数,参数1,参数2)
功能:把参数2中符合模式参数的单词(单词是指参数中被空格隔开的字符串)替换成参数1
返回值:被替换后的参数2
例如:result := $(patsubst %.c, %.o, x.c y.c)result的值为“x.o y.o”
第6行代码将source中的所有.c文件编译为.o文件并用Objs表示
5、通过“+=”来实现
例如:a1= a.o
a1+= b.o
这种方式下变量a1的值是“a.o b.o”。也就是说“+=”可以实现给变量追加值。
第7行代码Modules代表check_putin pack_message main
6、addsuffix
格式:$(addsuffix 参数1,参数2)
功能:在参数2中的每个单词加上后缀参数1
返回值:加上后缀的所有单词例
如:result := $(addsuffix .c, x y)result的值为“x.c y.c”。
第8行代码将Modules的所有文件加上/src/*.c文件后缀
总控Makefile
1、include scripts/Makefile:导入Makefile,可以使用该Makefile的定义的变量
2、all
运行命令“make all”后,Make会把all看成是最终的目标。由于伪目标和真实目标一样都有依赖文件,所以Make会更新all的依赖文件test、a.o和b.o。
第8行代码指更新Target
3、foreach
格式:$(foreach 变量参数,参数1,表达式)
功能:循环取出参数1中的单词赋给变量参数,然后运行表达式
返回值:表达式的运行结果
例如:a:= x y zresult := $(foreach b, $(a), $(b).c)
result的值为“x.c y.c z.c”。注意,b在这里是一个临时的变量。
call
格式: $ (call 变量参数,参数…)
功能:循环把参数依次赋给变量参数中的 $ (1)、 $(2)…
返回值:赋值后的变量值
例如:a:= $(2) $(1)
result := $(call $(a), x y)
result的值为“yx”。
module_make= $(MAKE) -C $(1):进入 $(1)所对应的目录,执行make命令
module_make= $(MAKE) clean -C $(1):进入 $(1)所对应的目录,执行make clean命令
第11行伪代码命令mm是循环取出Modules中的量赋给临时变量n,然后运行call函数,就是进入各个功能目录执行make命令
第13行伪代码命令mc是循环取出Modules中的量赋给临时变量n,然后运行call函数,就是进入各个功能目录执行make clean命令
4、Target命令翻译:gcc -Wall -O3 -o client check_putin/src/.o pack_message/src/.o main/src/*.o -lphthread
是将check_putin、 pack_message、 main中的所有.o文件链接的结果
clean是删除Target
功能目录Makefile
check_putin、 pack_message、 main中的Makefile代码都如图所示
更新或删除Objs(source的.o文件)值
main函数作用:建立一个线程来读取服务器发送来的信息
check_putin函数作用:字符串解析函数,不同的命令返回不同的值
pack_message函数作用:将数据打包并通过命令输出信息
include头文件定义 、宏定义命令的动作
实践:
将上述makefile模板应用在编写的计算器程序上
建立对应的目录以及文件
将该makefile拷贝到各功能目录的makefile下
scripts下的makefile要做更改:
①Libs= -lm
②Target := cal
③Moudules +=add sub mul div main
总控Makefile不变
最终结果: