zoukankan      html  css  js  c++  java
  • make是如何工作的

    在默认的方式下,也就是我们只输入make命令。那么,
    1、make会在当前目录下找名字叫“Makefile”或“makefile”的文件。
    2、如果找到,它会找文件中的第一个目标文件(target),在上面的例子中,他会找到“edit”这个文件,并把这个文件作为最终的目标文件。
    3、如果edit文件不存在,或是edit所依赖的后面的 .o 文件的文件修改时间要比edit这个文件新,那么,他就会执行后面所定义的命令来生成edit这个文件。
    4、如果edit所依赖的.o文件也存在,那么make会在当前文件中找目标为.o文件的依赖性,如果找到则再根据那一个规则生成.o文件。(这有点像一个堆栈的过程)
    5、当然,你的C文件和H文件是存在的啦,于是make会生成 .o 文件,然后再用 .o 文件生命make的终极任务,也就是执行文件edit了。
    这就是整个make的依赖性,make会一层又一层地去找文件的依赖关系,直到最终编译出第一个目标文件。在找寻的过程中,如果出现错误,比如最后被依赖的文件找不到,那么make就会直接退出,并报错,而对于所定义的命令的错误,或是编译不成功,make根本不理。make只管文件的依赖性,即,如果在我找了依赖关系之后,冒号后面的文件还是不在,那么对不起,我就不工作啦。

    通过上述分析,我们知道,像clean这种,没有被第一个目标文件直接或间接关联,那么它后面所定义的命令将不会被自动执行,不过,我们可以显示要make执行。即命令——“make clean”,以此来清除所有的目标文件,以便重编译。
    于是在我们编程中,如果这个工程已被编译过了,当我们修改了其中一个源文件,比如file.c,那么根据我们的依赖性,我们的目标file.o会被重编译(也就是在这个依性关系后面所定义的命令),于是file.o的文件也是最新的啦,于是file.o的文件修改时间要比edit要新,所以edit也会被重新链接了(详见edit目标文件后定义的命令)。
    而如果我们改变了“command.h”,那么,kdb.o、command.o和files.o都会被重编译,并且,edit会被重链接。

    GNU的make工作时的执行步骤入下:(想来其它的make也是类似)
    1、读入所有的Makefile。
    2、读入被include的其它Makefile。
    3、初始化文件中的变量。
    4、推导隐晦规则,并分析所有规则。
    5、为所有的目标文件创建依赖关系链。
    6、根据依赖关系,决定哪些目标要重新生成。
    7、执行生成命令。
    1-5步为第一个阶段,6-7为第二个阶段。第一个阶段中,如果定义的变量被使用了,那么,make会把其展开在使用的位置。但make并不会完全马上展开,make使用的是拖延战术,如果变量出现在依赖关系的规则中,那么仅当这条依赖被决定要使用了,变量才会在其内部展开。
    当然,这个工作方式你不一定要清楚,但是知道这个方式你也会对make更为熟悉。有了这个基础,后续部分也就容易看懂了。

    声明:由于不清楚makefile的匹配规则算法,下面的结论都是自己思考后测试的结果,如若有出错,还请指出

    =============================================================

    结论:(优先级由上往下递减)
    显式规则:

    完全匹配

    半匹配

    完全通配符匹配

    隐藏规则:

    (据说按照隐藏规则的顺序,测试发现,能一步达成的优先级高于分多步达成,

    例如:%:%.c > %.o:%.c + %:%.o)

    需要补充说明的是:显式规则若无命令,则此规则不参与匹配优先级

    ==============================================================

    以下为验证过程:

    <span style="font-size:18px;">.PHONY:all clean

    all:quick_sort bubble_sort
    #匹配1
    %_sort: %_sort.c
        @echo "matching $@"
        @echo 'in %_sort'
    #匹配2
    %:%.c
        @echo "matching $@"
        @echo 'in %'
    #匹配3
    quick_sort:quick_sort.c
        @echo "matching $@"
        @echo 'in quick_sort'

    clean:
        $(RM) *.o bubble_sort quick_sort</span>

    输出结果:

    $make
    matching quick_sort
    in quick_sort
    matching bubble_sort
    in %_sort
    $

    结论:

    显式规则中并不是按照上下文顺序匹配,因为匹配quick_sort时3个目标每一个都能匹配,而make选择了3最大匹配。匹配bubble_sort时,目标1、2均能匹配,然后make选择了2半匹配(%_sort)

    因此,显式匹配中,按照最大匹配优先,其次为半匹配,最后为完全通配符匹配


    由于显式规则能重载、取消隐藏规则(测试见我的另外一篇博客),因此显式规则优先级 > 隐藏规则
    ---------------------
    作者:GMPY_Tiger
    来源:CSDN
    原文:https://blog.csdn.net/gmpy_tiger/article/details/50899659
    版权声明:本文为博主原创文章,转载请附上博文链接!

  • 相关阅读:
    Python解释器安装
    有钱就放余额宝的人,这个习惯恐怕要改一改!
    这么详细的存储基础知识,你不看看? 会后悔的!
    超全!华为交换机端口vlan详解~
    华为:鸿蒙绝不是安卓换皮!!!
    VS Code 真的会一统江湖吗?
    用户与安全 -(1)Linux用户及组管理
    运维必看!这个技能薪水28.8万,工资竟然还只是零花钱....
    原来 Linux 日志文件系统是这样工作的~
    干货长文:Linux 文件系统与持久性内存介绍
  • 原文地址:https://www.cnblogs.com/idyllcheung/p/10383403.html
Copyright © 2011-2022 走看看