Makefile基本规则和原理

阅读《跟我一块儿写makefile》,摘录文章我的认为有助于理解的语句,并记录本身验证明践的过程,方便本身后续工做中复习。bash

1、基本规则

target ... : prerequisites ... command测试

  • target 是一个目标文件(makefile支持多目标),能够是 Object File,也能够是执行文件,还能够是一个标签(Label)。
  • prerequisites 生成 target 所须要的文件或是目标。
  • command 为 make 须要执行的命令。(任意的 Shell 命令)

这是一个文件的依赖关系,也就是说,target 这一个或多个的目标文件依赖于prerequisites 中的文件,其生成规则定义在 command 中。说白一点就是说,prerequisites中若是有一个以上的文件比 target 文件要新的话,command 所定义的命令就会被执行。这就是 Makefile 的规则。也就是 Makefile 中最核心的内容。ui

2、最基本的实例

显式规则,依赖关系写的比较清楚。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的依赖关系正确和编译命令所需的文件是存在的状况下。

3、基本原理

  1. make 会在当前目录下找名字叫“Makefile”或“makefile”的文件。
  2. 若是找到,它会找文件中的第一个目标文件(target),实例中第一个目标target为run
  3. 若是 run 文件不存在,或是run 所依赖的后面的 .o 文件的文件修改时间要比 run这个文件新,那么,他就会执行后面所定义的命令来生成 run这个文件。(根据这个特性,我每次修改相应的文件时候,有依赖关系的文件都会从新编译和连接。其实彻底能够不用make clean,毕竟大型源码从新编译一次是很耗费时间的。)
  4. 若是run所依赖的.o 文件也存在,那么 make 会在当前文件中找目标为.o 文件的依赖关系,也按照第3点的判断依据来更新生成.o文件。
  5. 若是run依赖关系中好比test.o的生成规则没在makefile文件中体现,make会自动产生规则并生成test.o文件,前提是test.c存在当前目录下,不然直接终止执行。
  6. 最终根据对应的依赖关系生成run这个可执行文件。
相关文章
相关标签/搜索