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.

 

 

 

 

.

 

posted @ 2019-08-07 17:48  一匹夫  阅读(510)  评论(0编辑  收藏  举报