• 第十四篇 自动生成依赖关系(终结)


     前面三篇已经把自动生成依赖关系所需要的知识点进行了剖析,本篇就来完成这个完整的makefile程序。
    整体的依赖关系如下所示:
     
    目标文件、依赖文件、最终的可执行文件我们都创建对应的文件夹来管理。下面直接给出编写完成的makefile程序:
     
    执行make,输出结果如下图所示:
     
    到目前,一切都很正常,下面我们来改一下头文件。
    新建一个文件new.h,将func.h中的宏定义剪切并放到new.h中,在func.h中包含new.h,执行make。输出结果如下:
     
    可见,make已经感知到了func.h得变化,于是重新执行了编译和链接,但是.dep依赖文件是没有重新生成的,现在我们更改new.h中的宏定义,将Hello Makefile改为Hello World。再次执行make,这次make提示没有什么可做的。
      我们明明更改了new.h中的宏定义,make却没有感知到。这是因为当.dep文件生成后,如果动态的改变头文件之间的依赖关系,那么make可能无法检测到这个改变,进而做出错误的编译决策。
      我们打开func.dep文件,内容如下:
     
      虽然我们增加了new.h,但是make并没有去更新依赖文件,导致依赖文件处于一个比较旧的状态,所以,当我们在新增加的头文件中做更改时,make是无法感知到的,因为这些头文件根本就没有作为依赖加入到规则中。
      考虑以下的解决方案:
      1、将依赖文件名作为目标加入自动生成的依赖关系中。
      2、通过include加载依赖文件时判断是否执行规则。
      3、在规则执行时重新生成依赖关系文件。
      4、最后加载新的依赖文件。
    上面的2、3、4条正是我们在上一篇中分析的include的不为人知的行为。我们只需在makefile中做微小的修改即可。如下所示,我们将$@加入到了正则表达式的替换部分,也即将依赖文件名作为目标。
    make在解析makefile时,首先加载include部分文件,然后根据文件名去查找规则,如果有新的头文件加入,如果包含到了c文件中,那必然会被感知到,如果是被包含在以前的旧的头文件中,这也会被make感知到(因为解决方案中的第一条,相当于我们给依赖文件增加了一些依赖),这时make会及时更新.dep依赖文件,将最新的依赖关系保存在依赖文件中,并重新加载依赖文件。
    这时func.dep文件的内容如下所示:
     
    deps/func.dep : func.c func.h new.h这条依赖和$(DIR_DEPS)/%.dep : %.c形成了依赖拆分的关系,这也是我们先前讲到的预备知识。
     
    小结:
      1、makefile中可以将目标的依赖拆分写到不同的地方。
      2、include关键字能够触发相应规则的执行。
      3、如果规则的执行导致依赖的更新,可能导致再次解释执行相应的规则,甚至形成死循环。
      4、依赖文件也需要依赖于源文件得到正确的编译决策。
      5、自动生成文件间的依赖关系能够提高makefile的移植性。
     
    参考如下:
                 狄泰软件教程及课件
       gun make手册
       专业嵌入式软件开发
     
     
     
     
     
     
     
  • 相关阅读:
    java如何操作注册表(Preferences类)(在windows的注册表中保存、读取)
    转-正则表达式
    js数字格式化千分位格式
    es6严格模式需要注意的地方
    html5手势原理知识
    js事件总结
    js键盘相关知识总结
    html5 拖放
    js学习日记-隐式转换相关的坑及知识
    移动端各种分辨率匹配
  • 原文地址:https://www.cnblogs.com/wanmeishenghuo/p/8424038.html
Copyright © 2020-2023  润新知