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

  编译单个源文件时,需要获取文件中包含的头文件的信息,但是一般的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中自动生成头文件依赖的更多相关文章

  1. Makefile自动生成头文件依赖

    前言 Makefile自动生成头文件依赖是很常用的功能,本文的目的是想尽量详细说明其中的原理和过程. Makefile模板 首先给出一个本人在小项目中常用的Makefile模板,支持自动生成头文件依赖 ...

  2. pycharm自动生成头文件注释

    1.在file->settings->file and code templates->python script即可自定制pycharm创建文件自动生成的头文件注释信息 2.创建p ...

  3. php中soap的使用实例以及生成WSDL文件,提供自动生成WSDL文件的类库——SoapDiscovery.class.php类

    1. web service普及: Webservice soap wsdl区别之个人见解 Web Service实现业务诉求:  Web Service是真正“办事”的那个,提供一种办事接口的统称. ...

  4. 用shell脚本新建shell文件并自动生成头说明信息

    目标: 新建文件后,直接给文件写入下图信息 代码实现: [root@localhost test]# vi AutoHead.sh #!/bin/bash#此程序的功能是新建shell文件并自动生成头 ...

  5. 在visual studio code和visual studio中编写TypeScript文件自动生成JavaScript文件

    注:此处的自动生成都为保存ts文件时自动生成js文件 VS CODE 只需要在TypeScript的终端控制台中输入如下命令即可,并注意需要将其中的*换成对应的文件名,此处的*似乎不能作为通用匹配. ...

  6. 用shell脚本新建文件并自动生成头说明信息

    目标: 新建文件后,直接给文件写入下图信息 代码实现: [root@localhost test]# vi AutoHead.sh #!/bin/bash #此程序的功能是新建shell文件并自动生成 ...

  7. 1、Pycharm中创建项目自动生成头信息

    1.打开PyCharm 选择File-Settings 2.模块变量描述,并且重新创建一个.py的文件测试,检测是否自动生成头信息

  8. CPLUSPLUS 获得 一个源文件的头文件依赖。即该文件所需要的所有头文件

    核心命令:gcc -M *.h.*.cpp 转: 自动处理头文件的依赖关系 http://blog.csdn.net/su_ocean16/article/details/5374696 现在我们的M ...

  9. 程序自动生成Dump文件

    前言:通过drwtsn32.NTSD.CDB等调试工具生成Dump文件, drwtsn32存在的缺点虽然NTSD.CDB可以完全解决,但并不是所有的操作系统中都安装了NTSD.CDB等调试工具.了解了 ...

随机推荐

  1. 「从零单排canal 03」 canal源码分析大纲

    在前面两篇中,我们从基本概念理解了canal是一个什么项目,能应用于什么场景,然后通过一个demo体验,有了基本的体感和认识. 从这一篇开始,我们将从源码入手,深入学习canal的实现方式.了解can ...

  2. 01-最大子列和问题(java)

    问题描述:给定N个整数的序列{A1,A2,A3,…,An},求解子列和中最大的值. 这里我们给出{-2,11,-4,13,-5,-2}这样一个序列,正确的最大子列和为20 该题是在数据结构与算法中经常 ...

  3. Python3-shutil模块-高级文件操作

    Python3中的shutil模块提供了对文件和容器文件的一些高级操作 shutil.copy(src, dst) 拷贝文件,src和dst为路径的字符串表示,copy()会复制文件数据和文件权限,但 ...

  4. 02 [掌握] redis详情命令

    1,常用命令 keys * 获取所有的key select 0 选择第一个库 move myString 1 将当前的数据库key移动到某个数据库,目标库有,则不能移动 flushdb 清除指定库 r ...

  5. python基础扩展(二)

    python基础扩展(二) 常用操作 1.startswith(以什么开始) endswith(y)什么结束 s='taiWanw39dd' print(s.startswith('t')) #意思是 ...

  6. 字符串String和list集合判空验证

    1`字符串判断处理: 结论: 当if判断条件为两个,并且它们两个为或的关系,如果第一个条件为false,则继续第二个条件的判断:如果第一个条件为true,该例子不足以说明是否判断第二个条件, 最终可以 ...

  7. mybatis源码配置文件解析之五:解析mappers标签流程图

    前面几篇博客分析了mybatis解析mappers标签的过程,主要分为解析package和mapper子标签.补充一张解析的总体过程流程图,画的不好,多多谅解,感谢.

  8. springMVC中的HttpSession与Model

    目录 1.1 spring的@MODELATTRIBUTE 2.1 session的概念 3.1 示例 4.1 为什么springmvc框架要使用model这个对象呢? 突然发问:相信很多人在做WEB ...

  9. java语言基础(七)_继承_super_this_抽象类

    继承 1. 继承概述 2. 继承格式 在继承的关系中,"子类就是一个父类".也就是说,子类可以被当做父类看待. 例如父类是员工,子类是讲师,那么"讲师就是一个员工&quo ...

  10. 一文说清 KubeSphere 容器平台的价值

    KubeSphere 作为云原生家族 后起之秀,开源近两年的时间以来收获了诸多用户与开发者的认可.本文通过大白话从零诠释 KubeSphere 的定位与价值,以及不同团队为什么会选择 KubeSphe ...