使用GCC编译器自动创建依赖文件的功能
假设我们在文件夹下一共有这3个文件
//a.c
#include <stdio.h>
#include "a.h"
int main()
{
printf("hello, world!\n");
printf("A= %d\n", A);
test_fun();
return 0;
}
//a.h
#define A 1
//b.c
#include <stdio.h>
int test_fun()
{
printf("it is B\n");
return 0;
}
对于这三个文件,我们用上上节的自动变量的知识可以用以下这个makefile文件编译
test:a.o b.o
gcc -o test a.o b.o
a.o:a.c a.h
%.o : %.c
gcc -c -o $@ $<
可以发现我们用上了自动变量和模式变量,但是还是要手动去指定a.o目标文件的依赖文件。那么如果我们的项目非常的大,一个个去指定依赖文件实在是太麻烦了,我们可以利用gcc中的列出依赖文件的功能。先看例子:
objs := a.o b.o
test:$(objs)
gcc -o test $^
dep_files := $(foreach f,$(objs),.$(f).d)
dep_files := $(wildcard $(dep_files))
ifneq ($(dep_files),)
include $(dep_files)
endif
%.o : %.c
gcc -Wp,-MD,.$@.d -c -o $@ $<
clean:
rm *.o test
使用这个功能就是在gcc编译后面加上-Wp,-MD,[file]在上面的例子中,我们运行完make命令以后,会在当前文件夹下生成 .a.o.d 和 .b.o.d两个文件,这两个文件列出了a.o和b.o两个文件的依赖关系


objs := a.o b.o
test:$(objs)
gcc -o test $^
# .a.o.d .b.o.d
dep_files := $(foreach f,$(objs),.$(f).d)
dep_files := $(wildcard $(dep_files))
ifneq ($(dep_files),)
include $(dep_files)
endif
%.o : %.c
gcc -Wp,-MD,.$@.d -c -o $@ $<
clean:
rm *.o test
接着我们分析一下这个Makefile文件,首先输入make以后,因为目标文件缺省,所以test为总的目标文件,把objs变量带入后可知,test依赖于a.o和b.o。先分析a.o,a.o依赖于a.c,然后执行下面的命令,生成a.o和.a.o.d。b.o同理,a.o和b.o都有了以后链接起来生成test可执行文件。第二次执行的时候因为我们在第一次生成了.a.o.d和.b.o.d文件,这次这两个文件就会被包含进来。如果我们修改了a.h,会发现a.o会被重现编译。

这篇博客介绍了如何利用GCC编译器自动创建依赖文件的功能,以简化大型项目的Makefile编写。通过在gcc编译命令后添加特殊选项,可以生成列出目标文件依赖关系的.d文件。在Makefile中利用这些文件,可以实现当头文件改变时自动重新编译对应的源文件,提高了编译效率。
402

被折叠的 条评论
为什么被折叠?



