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.
.