Makefile小疑问

在应用基础的视频里面,04 Makefile实例中。有一点没理解,就是韦老师在讲解生成了依赖.d文件后。为什么在Makefile文件开头,又使用了patsubst函数,把所有的文件都替换成 .%.d 的格式呢? 我不理解的地方是:我们.d格式的依赖文件已经有了,为什么需要替换一次呢?而且为什么需要替换成 .%d 的格式呢?这种用法和我们实际开发中有什么大的联系没有呢?
以上就是我的疑问,烦请各位大佬指教 :pray: :pray:

  1. make 这个指令本身,会把整个 Makefile 读进去,进行全部分析,然后解析里面的变量。
    dep_files := $(foreach f, $(objs), .$(f).d)
    dep_files := $(wildcard $(dep_files))
    这两条要结合起来看,就是判断是否存在 .*.d 的依赖文件;毕竟第一次 make 的时候,是不存在依赖文件的;
  2. 实际开发中联系不大,Makefile 要么自动生成,要么别人写好了;
分析一下过程

第一次 make 的时候;
先执行
dep_files := $(foreach f, $(objs), .$(f).d)
dep_files := $(wildcard $(dep_files))
得到 dep_files 的值为空;
执行 test 目标 => 依赖 objs 都不存在
include 空,
执行 %o 目标 => 生成 objs 依赖文件,和对应 *.c 的头文件依赖;
=>执行 test 生成

修改 b.c 的头文件 b.h 后;
第二次 make
先执行
dep_files := $(foreach f, $(objs), .$(f).d)
dep_files := $(wildcard $(dep_files))
得到 dep_files 的值为头文件依赖文件;
执行 test 目标 => 检查 objs 依赖是否有过修改
include 会包含对应文件
示例 sub.c 的头文件依赖文件 .sub.o.d 如下

sub.o: sub.c /usr/include/stdc-predef.h /usr/include/stdio.h \
 /usr/include/x86_64-linux-gnu/bits/libc-header-start.h \
 /usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \
 /usr/include/x86_64-linux-gnu/bits/wordsize.h \
 /usr/include/x86_64-linux-gnu/bits/long-double.h \
 /usr/include/x86_64-linux-gnu/gnu/stubs.h \
 /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \
 /usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h \
 /usr/lib/gcc/x86_64-linux-gnu/9/include/stdarg.h \
 /usr/include/x86_64-linux-gnu/bits/types.h \
 /usr/include/x86_64-linux-gnu/bits/timesize.h \
 /usr/include/x86_64-linux-gnu/bits/typesizes.h \
 /usr/include/x86_64-linux-gnu/bits/time64.h \
 /usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h \
 /usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h \
 /usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h \
 /usr/include/x86_64-linux-gnu/bits/types/__FILE.h \
 /usr/include/x86_64-linux-gnu/bits/types/FILE.h \
 /usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h \
 /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \
 /usr/include/x86_64-linux-gnu/bits/sys_errlist.h sub.h

同理:发现 b.o 的依赖文件 b.h 被修改;重新编译生成 b.o 文件;
生成 test 目标;