我是靠谱客的博主 负责钢笔,这篇文章主要介绍makefile的foreach、filter、wildcard、patsubst用法及.d文件的生成,现在分享给大家,希望可以做个参考。

函数

  • 1.$(foreach var,list,text) : 对list中的每一个变量var执行text语句。
    例如:
复制代码
1
2
3
4
5
A = a b c B = $(foreach f, $(A), $(f).o) all: @each B = $(B)

输出: B = a.o b.o c.o 这样就能遍历A集合

  • 2.$(filter pattern...,text):在text中取出符合pattern格式的值
    $(filter-out pattern...,text):在text中取出不符合pattern格式的值。
复制代码
1
2
3
4
C = a b c d/ D = $(filter %/,$(C)) E = $(filter-out %/,$(C))

all:
@echo D = $(D)
@echo E = $(E)

这里我们使用通配符%来匹配
输出: D = d/ E = a b c

  • 3.$(wildcard pattern):pattern定义了文件名的格式,wildcard取出其中存在的文件。
    我们在makefile目录下添加a.c b.c c.c 几个文件
复制代码
1
2
3
4
filters = $(wildcard *.c) all : @echo filters = $(filters)

输出:filters = a.c b.c c.c

  • 4.$(patsubst pattern,replacement,text):将text中符合pattern的值替换为replacement
复制代码
1
2
3
4
5
files = a.c b.c c.c dep_files = $(patsubst %.c, %.d,$(files)) all : @echo dep_files= $(dep_files)

输出:dep_files = a.d b.d c.d

实例

创建3个文件 a.c b.c c.c c.h
a.c文件:

复制代码
1
2
3
4
#include <stdio.h> void func_b(); void func_c();

int main(){
func_b();
func_c();
return 0;
}

b.c文件:

复制代码
1
2
3
4
5
#include <stdio.h> void func_b(){ printf("This is Bn"); }

c.c文件 依赖c.h文件,并使用C这个宏:

复制代码
1
2
3
4
5
6
#include <stdio.h> #include <c.h> void func_c(){ printf("This is C = %dn", C); }

c.h文件:

复制代码
1
2
#define C 1

makefile文件:

复制代码
1
2
3
4
5
6
7
8
test : a.o b.o c.o gcc -o test $^ %.o : %.c gcc -c -o $@ $< clean: rm *.o test .PHONY : clean

我们执行make 与./test指令,可以成功执行输出:
This is B
This is C = 1
当我们修改c.h文件中的#define C 2后再次运行make 与./test执行还是得到同样的输出,也就是我们修改的c.h文件没生效。
这主要是我们的c.o文件只依赖了c.c文件。我们加上c.o : c.c c.h两个依赖即可:

复制代码
1
2
3
4
5
6
7
8
9
test : a.o b.o c.o gcc -o test $^ c.o : c.c c.h %.o : %.c gcc -c -o $@ $< clean: rm *.o test .PHONY : clean

再次执行make 与./test则正常输出:
This is B
This is C = 2
所以我们要给.o文件加上.h的依赖。但是.h有很多,手动添加很麻烦,makefile给我们提供了自动生成依赖的功能。

  • 自动生成依赖:
    可以使用:gcc -M c.c可以查看c.c的所有依赖;
    使用:gcc -M -MF c.d c.c 可以将c.c的所有依赖文件名写入到c.d文件中:


    image.png

    使用gcc -c -o c.o c.c -MD -MF c.d会生成c.o文件,也会生成c.d依赖文件
    现在我们修改makefile文件生成依赖文件:

复制代码
1
2
3
4
5
6
7
8
9
test : a.o b.o c.o gcc -o test $^ c.o : c.c c.h %.o : %.c gcc -c -o $@ $< -MD -MF .$@.d clean: rm *.o test .PHONY : clean

会生成多个.a.o.d 、.b.o.d 、 .c.o.d依赖文件
这样我们就可以把这些依赖文件添加到makefile文件中
条件是:只有.o.d文件存在才添加

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
objs = a.o b.o c.o #将objs文件都加上 .开始 .d结束 def_files := $(patsubst %,.%.d,$(objs)) #判断def_files是否存在,如果存在则包含进来,这里的包含指的是加入def_file变量中 def_files := $(wildcard $(def_files)) test : $(objs) gcc -o test $^ ifneq ($(def_files),) #如果存在则包含进来 include $(def_files) endif %.o : %.c gcc -c -o $@ $< -MD -MF .$@.d clean : rm *.o test distclean: rm $(def_files) .PHONY : clean

这时候我们使用make与 ./test则输出:
This is B
This is C = 2
我们再次修改#define C 3
再次make 与 ./test则输出
This is B
This is C = 3
这样我们就不用手工添加.o文件依赖.h文件了,让makefile自动包含依赖

  • 添加CFLAGS 添加编译选项
    例如 CFLAGS = -Werror 编译时将所有的警告当错误处理
    CFLAGS = -I包含编译目录,例如指定gcc搜索头文件的指定目录CFLAGS = -Iinclude

最后

以上就是负责钢笔最近收集整理的关于makefile的foreach、filter、wildcard、patsubst用法及.d文件的生成的全部内容,更多相关makefile内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(85)

评论列表共有 0 条评论

立即
投稿
返回
顶部