Makefile中自动生成头文件依赖

Posted chusiyong

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Makefile中自动生成头文件依赖相关的知识,希望对你有一定的参考价值。

为什么需要自动生成头文件依赖?

  编译单个源文件时,需要获取文件中包含的头文件的信息,但是一般的Makefile不会在规则中明确写明文件依赖的头文件,所以单独修改头文件后,不会导致包含头文件的源文件重新编译。如果每次手动的添加头文件依赖,又会非常的繁琐,所以需要一种自动生成依赖的方法。

 

编译器中神奇的选项

  • 使用$(CC)中的-M命令就可以完美的解决问题,因为-M选项可以将源文件依赖的所有头文件,自动解析出来。
  • 例子:在当前路径下,编辑test.c和test.h文件,test.c如下所示,test.h为空
#include <stdio.h>
#include "test.h"

int main()

	return 0;
  • 运行命令:gcc -M test.c,输出如下:
test.o: test.c /usr/include/stdc-predef.h /usr/include/stdio.h  /usr/include/features.h /usr/include/sys/cdefs.h  /usr/include/bits/wordsize.h /usr/include/gnu/stubs.h  /usr/include/gnu/stubs-64.h  /usr/lib/gcc/x86_64-redhat-linux/4.8.5/include/stddef.h  /usr/include/bits/types.h /usr/include/bits/typesizes.h  /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h  /usr/lib/gcc/x86_64-redhat-linux/4.8.5/include/stdarg.h  /usr/include/bits/stdio_lim.h /usr/include/bits/sys_errlist.h test.h  
  • 运行命令:gcc -MM test.c,输出如下:
test.o: test.c test.h  
  • 结论:gcc -MM 命令可以自动生成源文件对头文件的依赖关系,且剔除掉库里面的头文件

 

解决方法

%.d: %.c
    @set -e;     rm -f $@;     $(CC) -MM $(CPPFLAGS) $< > $@.$$$$;     sed ‘s,\($*\)\.o[ :]*,\1.o $@ : ,g‘ < $@.$$$$ > $@;     rm -f $@.$$$$
  • set -e : 后续命令只要执行失败,直接结束全部流程,返回
  • rm -f $@ : 删除上一次编译的残留文件
  • $(CC) -MM $(CPPFLAGS) $< > $@.$$$$ : 将生成的依赖关系输出到指定的目录中,其中$$$$表示一个随机数,防止文件名重复
  • sed ‘s,\($*\)\.o[ :]*,\1.o $@ : ,g‘ < $@.$$$$ > $@ : ;利用sed命令,将xxx.d添加到规则中的目标里面,形成多目标,如:将 main.o : main.o mian.h 变成main.o main.d : main.o mian.h。目的:头文件更新后,d文件也需要同步更新
  • rm -f $@.$$$$ : 删除中间文件

 

提示:上述方法中隐含了,目标相同的多条规则会自动进行合并的机制,所以规则的目标一定要相同,才能使得原来的编译规则(%.c:%.o)中添加对头文件的依赖。

 

以上是关于Makefile中自动生成头文件依赖的主要内容,如果未能解决你的问题,请参考以下文章

makefile自动生成依赖关系 可自动检测头文件变化

如何通过自动生成的makefile 看各个文件的依赖关系

makefile(05)_自动生成依赖关系

makefile新手添加依赖文件的位置

如何在makefile中指定头文件目录

自动生成依赖关系