zoukankan      html  css  js  c++  java
  • 第十三篇 自动生成依赖关系(下)

     上一篇中我们初步生成了.dep依赖文件,但是,实际工程中,源文件成千上万,生成的依赖文件需要用文件夹管理起来,也就是在makefile中将.dep文件组织到指定目录。

     我们可以通过以下思路来组织.dep文件,当include发现.dep文件不存在时:
     1、通过规则和命令创建deps文件夹。
     2、将所有.dep文件创建到deps文件夹。
     3、.dep文件中记录目标文件的依赖关系。
     
    初步想法如下,让deps文件夹作为all目标的依赖,执行make all时创建deps文件夹。代码如下:
     
    执行make all,输出如下所示:
     
    由于make解释器对include的处理方式,导致在输出结果中,先创建了依赖文件,然后才创建了deps文件夹,这是不符合我们的预期的,可见,让deps作为目标all的依赖不是一个好的方案。我们应该在用到deps文件夹的时候才让它生成。
     
    修改makefile如下:
     
    此时,deps文件夹作为.dep文件的依赖,因此,在需要生成.dep依赖文件时才生成deps文件夹,执行make all,输出结果如下:
     
    从上图可见,这次是先创建了deps文件夹,然后又创建的.dep依赖文件。
    但同时一个新问题也暴漏了出来,main.dep竟然被创建了两次,这究竟是怎么回事呢?
    make解释器在解析makefile时,根据$(DIR_DEPS)/%.dep : $(DIR_DEPS) %.c这条模式规则生成具体的规则并记录下来,对于main来说就是deps/main.dep : deps main.c,make解释器记录下该规则后便去执行规则下的命令,生成依赖文件,接着再去推倒出func相关的规则并执行命令。当生成deps/func.dep时,deps文件夹的时间戳也被更新了,因此,make解释器根据记录下来的规则发现,应该重新生成main.dep,这就是为什么执行结果中出现了创建两次main.dep的现象。这是一个严重的问题,必须要解决掉,否则,当存在大量源文件要生成依赖文件时,容易造成死循环,导致崩溃。
     
    引入条件语句,修改makefile,执行make all结果如下:
     
     
         make解释器在第一次解析makefile时,发现deps文件夹不存在,这时解析出的规则为deps/main.dep : deps main.c,并记录下来。当生成deps/func.dep时同样也会更新deps文件夹的时间戳,此时会触发make再次解析刚刚记录的规则,而这时deps文件夹是存在的,因此会用新规则deps/main.dep : main.c替换刚刚的规则,这时不再依赖deps文件夹,而main.c又未曾改变,所以就不会再次创建main.dep了。 
    这就是使用ifeq来动态决定.dep的依赖:
     
     
    上述makefile中使用了include $(DEPS),但是,当DEPS不存在时,make会寻找相应的目标和规则,在规则中可能会创建一个DEPS文件,但是创建好之后make是否还会进行一些操作呢?这就关系到make解释器对include关键字的处理方式了。
     
    include的不为人知的知识点:
     1、include前使用"-"号,不但会关闭警告,而且会关闭错误报告。
     
     
    上图中程序中,即使当前目录不存在test.txt文件,执行make all,也会正常输出this is all,这是因为include前使用了"-"。
     
     2、如果include触发规则创建了文件,那么make会将新创建出的文件重新包含进来。
     看下面一段程序:
     
    执行make后输出如下:
     
    乍一看输出结果可能有点儿出乎意料,为什么不是this is all? 其实make一开始发现test.txt并不存在,于是开始寻找以test.txt作为目标的规则,找到之后便执行这个规则下的命令,这些命令创建了一个test.txt文件,于是make再次将这个文件的内容包含到调用include的地方,在本例中也就作为了第一个规则,make默认情况下,执行第一个规则,所以输出this is other。
     
     3、如果include包含的文件存在,make还是会去检查是否存在以文件名作为目标的规则,若存在,且该规则的依赖在时间上较新,则会进一步去执行这个规则。
     编写makefile如下:
     
    执行make all,输出如下:
     
     我们保证b.txt文件是最新的,从执行结果来看,虽然当前目录下存在test.txt,但是依然触发了test.txt : b.txt这条规则的执行。
     
    关于include的总结:
     
     
    参考如下:
       狄泰软件教程及课件
       gun make手册
       专业嵌入式软件开发
        
     
     
     
     
     
     
     
     
     
     

     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     

    <wiz_tmp_tag id="wiz-table-range-border" contenteditable="false" style="display: none;">





  • 相关阅读:
    2015南阳CCPC L
    2015南阳CCPC H
    2015南阳CCPC G
    2015南阳CCPC D
    2015南阳CCPC C
    2015南阳CCPC A
    2015长春赛区总结(其实是流水账
    Codeforces Round #326 (Div. 2) D. Duff in Beach dp
    Codeforces Round #326 (Div. 2) C. Duff and Weight Lifting 水题
    Codeforces Round #326 (Div. 2) B. Duff in Love 分解质因数
  • 原文地址:https://www.cnblogs.com/wanmeishenghuo/p/8423230.html
Copyright © 2011-2022 走看看