阅读《跟我一块儿写makefile》,摘录文章我的认为有助于理解的语句,并记录本身验证明践的过程,方便本身后续工做中复习。bash
target ... : prerequisites ... command测试
这是一个文件的依赖关系,也就是说,target 这一个或多个的目标文件依赖于prerequisites 中的文件,其生成规则定义在 command 中。说白一点就是说,prerequisites中若是有一个以上的文件比 target 文件要新的话,command 所定义的命令就会被执行。这就是 Makefile 的规则。也就是 Makefile 中最核心的内容。ui
显式规则,依赖关系写的比较清楚。spa
run: main.o hello.o test.o
gcc -o run main.o hello.o test.o
main.o: main.c
gcc -c main.c
hello.o: hello.c
gcc -c hello.c
test.o: test.c
gcc -c test.c
clean:
rm run *.o
复制代码
运行结果:code
root@chenwr-pc:/home/workspace/my_workspace/study/makefile# make run
gcc -c main.c
gcc -c hello.c
gcc -c test.c
gcc -o run main.o hello.o test.o
复制代码
run所须要的依赖文件不存在时,执行下一语句。待依赖文件生成时,继续执行run对应的命令。get
若是依赖的test.o文件没有生成的规则,makefile会自动产生规则去生成test.o文件。这个特性就是隐晦规则,主要靠make自动推导。只要 make 看到一个[.o]文件,它就会自动的把[.c]文件加在依赖关系中,如自动把test.c加入到依赖关系中,而且cc -c -o test.o test.c也会被推导出来。源码
删除该语句测试
test.o: test.c
gcc -c test.c
复制代码
运行结果:string
gcc -c main.c
gcc -c hello.c
cc -c -o test.o test.c
gcc -o run main.o hello.o test.o
复制代码
若是没有test.c文件则没法生成,直接终止执行。it
root@chenwr-pc:/home/workspace/my_workspace/study/makefile# make run
gcc -c main.c
gcc -c hello.c
make: *** No rule to make target `test.o', needed by `run'. Stop.
复制代码
make 并无论命令是怎么工做的,他只管执行所定义的命令。 make 会比较 targets 文件和 prerequisites 文件的修改日期,若是 prerequisites 文件的日期要比 targets 文件的日期要新,或者 target 不存在的话,那么,make 就会执行后续定义的命令。我发觉书上这句话有点问题。 测试把hello.c文件删除后,即没法生成hello.o这个target,执行make run,结果以下编译
root@chenwr-pc:/home/workspace/my_workspace/study/makefile# make run
gcc -c main.c
make: *** No rule to make target `hello.c', needed by `hello.o'. Stop.
复制代码
后续定义的语句并不会去执行,直接终止。
test.o: test.c
gcc -c test.c
复制代码
原来是我理解错误了,书中后面提到: 在找寻的过程当中,若是出现错误,好比最后被依赖的文件找不到,那么make 就会直接退出,并报错,而对于所定义的命令的错误,或是编译不成功,make 根本不理。make 只管文件的依赖性,即,若是在我找了依赖关系以后,冒号后面的文件仍是不在,那么对不起,我就不工做啦。 这个target不存在,是指上一次编译生成的run,已经不存在须要执行对应的command来产生。而且大前提是整个makefile的依赖关系正确和编译命令所需的文件是存在的状况下。