zoukankan      html  css  js  c++  java
  • makefile实验三 理解make工作的基本原则

    代码简单,但测试花样多,若能回答对本博客的每个步骤的预期结果,可以说对makefile的基础掌握是扎实的。

    一,当前的makefile代码

    root@ubuntu:~/Makefile_Test# 
    root@ubuntu:~/Makefile_Test# 
    root@ubuntu:~/Makefile_Test# cat My_Make 
    
    Target := Hello.out
    
    $(Target) :
        @echo "Target"
    
    
    test.out : $(Target)
        @echo "test.out"

    二,当前的ubuntu环境 

    root@ubuntu:~/Makefile_Test# ls
    3.Makefile_PHONY_test2  func.c  Hello.out  Makefile_another_way_of_PHONY  Make-f_YOUR_OWN_Makefile.txt  tmp.c
    clean                   func.h  main.c     Makefile_PHONY_clean           My_Make

    ps: 这里存在一个Hello.out文件

     

    三,现在一步步(按本博客各个步骤的先后顺序理解)执行makefile,你可以在脑子里预期每一步的执行效果,我也会附上解析

    root@ubuntu:~/Makefile_Test# 
    root@ubuntu:~/Makefile_Test# make -f My_Make Hello.out 
    make: 'Hello.out' is up to date.
    root@ubuntu:~/Makefile_Test# make -f My_Make test.out
    test.out

    解析:当前本地存在Hello.out   , 所以make Hello.out 得到 make: 'Hello.out' is up to date.  这一结果是合理的。 若不懂,看我前面的博客。

              当前本地不存在test.out, 所以尝试make test.out有效,即会执行目标test.out所在规则内的命令(全部命令,一条或多条)。

    接着操作:

    root@ubuntu:~/Makefile_Test# echo ""I am test.out"" > test.out
    root@ubuntu:~/Makefile_Test# cat test.out 
    "I am test.out"
    root@ubuntu:~/Makefile_Test# make -f My_Make test.out
    make: 'test.out' is up to date.

    在命令行内,先创建了一个本地的test.out, 那么此时,本地存在Hello.out和test.out, make test.out无效(即不会执行目标test.out所在规则内的命令)

    接着来:

    root@ubuntu:~/Makefile_Test# rm Hello.out 
    root@ubuntu:~/Makefile_Test# make -f My_Make test.out
    Target
    test.out

    在命令行内,先删除Hello.out,

       回看源代码:

    Target := Hello.out
    
    $(Target) :
        @echo "Target"
    此时本地不存在Hello.out,目标Target相当于永远不是最新的目标。

    那么此时去make test.out,首先一定会打印出:Target

    再次回看源代码:

    test.out : $(Target)
        @echo "test.out"
    test.out依赖于Target。
    也就是说test.out依赖于一个永远不是最新的目标,自然,test.out就变成了一个永远不是最新的目标,即被make
    test.out,总是会生效.//说法(1)

    于是最终又打印了出了test.out
    这里要注意哦:虽然本地存在了test.out,但是鉴于上述的原因: 即make软件认为当前的目标test.out比它的依赖旧,所以make test.out是有效的. / / 说法(2)

    换种说法也是一样的,也就是上面的说法(1): 如果一个目标X的依赖是另一个目标Y,目标Y都被重新make了,那么目标X一定会被重新make。

    因为,make软件要做到: 目标比依赖更新。

       这里再来小结下make软件的工作原理

            1,目标文件不存在,make软件会将本次make该目标的操作生效(即会执行规则内的命令)。

                                 2,目标文件存在,但是比依赖的文件旧,make软件也会将本次make该目标的操作生效(即会执行规则内的命令)。

     接着来

    root@ubuntu:~/Makefile_Test# echo ""I am Hello.out"" > Hello.out
    root@ubuntu:~/Makefile_Test# cat Hello.out 
    "I am Hello.out"
    root@ubuntu:~/Makefile_Test# ls
    3.Makefile_PHONY_test2  func.c  Hello.out  Makefile_another_way_of_PHONY  Make-f_YOUR_OWN_Makefile.txt  test.out
    clean                   func.h  main.c     Makefile_PHONY_clean           My_Make                       tmp.c
    root@ubuntu:~/Makefile_Test# make -f My_Make test.out
    test.out
    root@ubuntu:~/Makefile_Test# make -f My_Make test.out
    test.out

    使用命令行,又在本地创建了一个Hello.out。

    经过上面的讲解,现在可以很容易地理解 make Target,一定不会执行 Target规则内的命令(不会打印Target)。

    现在本地已经有了Hello.out 和 test.out。 可是为什么还打印出了test.out呢? 

    难道是make软件运行错误了?!

    回顾本博客上文所总结的知识点 =》make软件的工作原理

    本地的Hello.out是我们刚才新建的,而test.out在这之前就有了,所以,天空一声巨响,make(有效的,会执行命令的make)闪亮登场。

    最后再做一个小实验,和刚才的这个实验遥相呼应

    root@ubuntu:~/Makefile_Test# rm test.out
    root@ubuntu:~/Makefile_Test# echo ""I am test.out, a newer one"" > test.out
    root@ubuntu:~/Makefile_Test# 
    root@ubuntu:~/Makefile_Test# make -f My_Make test.out
    make: 'test.out' is up to date.
    root@ubuntu:~/Makefile_Test# 
    root@ubuntu:~/Makefile_Test# 

    我们在代码内做了一个操作,删除并创建了一个test.out。该操作的目的就是让test.out比Hello.out更新。

    然后make test.out,结果符合预期。

    make: 'test.out' is up to date.

    .

    /************* 社会的有色眼光是:博士生、研究生、本科生、车间工人; 重点大学高材生、普通院校、二流院校、野鸡大学; 年薪百万、五十万、五万; 这些都只是帽子,可以失败千百次,但我和社会都觉得,人只要成功一次,就能换一顶帽子,只是社会看不见你之前的失败的帽子。 当然,换帽子决不是最终目的,走好自己的路就行。 杭州.大话西游 *******/
  • 相关阅读:
    HDU5730 Shell Necklace
    BZOJ4883 [Lydsy2017年5月月赛]棋盘上的守卫
    Spring boot 配置文件
    org.joda.time.DateTime 日期操作
    Elasticsearch + Springboot 启动报错 java.net.ConnectException: Connection refused
    centos7 在docker下安装es Elasticsearch
    centos 7 。 docker 安装rabbitmq 以及集权搭建
    linux 安装mysql5.7.25
    安装rabbtimq CentOS 7
    docker + spring boot 打包 部署。
  • 原文地址:https://www.cnblogs.com/happybirthdaytoyou/p/11316782.html
Copyright © 2011-2022 走看看