目录
背景
实例代码
依赖关系
依赖方法
原理
项目清理
可重复执行的依据
背景
会不会写makefile,从一个侧面说明了一个人是否具备完成大型工程的能力一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefile都成为了一种在工程方面的编译方法。make是一条命令,makefifile是一个文件,两个搭配使用,完成项目自动化构建。
实例代码
C代码myfile:myfile.o gcc -o myfile myfile.o myfile.o:myfile.s gcc -c -o myfile.o myfile.s myfile.s:myfile.i gcc -S -o myfile.s myfile.i myfile.i:myfile.c gcc -E -o myfile.i myfile.c
myfile:myfile.c gcc -o myfile myfile.c
依赖关系
上面的文件myfile ,它依赖 myfile.omyfile.o , 它依赖 myfile.smyfile.s , 它依赖 myfile.imyfile.i , 它依赖 myfile.c
依赖方法
gcc myfile.* -option myfile.* ,就是与之对应的依赖关系
原理
make是如何工作的,在默认的方式下,也就是我们只输入make命令。那么,1. make会在当前目录下找名字叫“Makefile”或“makefile”的文件。2. 如果找到,它会找文件中的第一个目标文件(target),在上面的例子中,他会找到“ myfile ”这个文件,并把这个文件作为最终的目标文件。3. 如果 myfile 文件不存在,或是 myfile 所依赖的后面的 myfile .o文件的文件修改时间要比 myfile 这个文件新(可以用 touch 测试),那么,他就会执行后面所定义的命令来生成 myfile 这个文件。4. 如果 myfile 所依赖的 myfile .o文件不存在,那么make会在当前文件中找目标为 myfile .o文件的依赖性,如果找到则再根据那一个规则生成 myfile .o文件。(这有点像一个堆栈的过程)5. 当然,你的C文件和H文件是存在的啦,于是make会生成 myfile .o 文件,然后再用 myfile .o 文件声明make的终极任务,也就是执行文件 myfile 了。6. 这就是整个make的依赖性,make会一层又一层地去找文件的依赖关系,直到最终编译出第一个目标文件。7. 在找寻的过程中,如果出现错误,比如最后被依赖的文件找不到,那么make就会直接退出,并报错,而对于所定义的命令的错误,或是编译不成功,make根本不理。8. make只管文件的依赖性,即,如果在我找了依赖关系之后,冒号后面的文件还是不在,那么对不起,我就不工作啦。
项目清理
工程是需要被清理的!像clean这种,没有被第一个目标文件直接或间接关联,那么它后面所定义的命令将不会被自动执行,不过,我们可以显示要make执行。即命令——“make clean”,以此来清除所有的目标文件,以便重编译。
- clean 后指令会被执行,也可以执行echo等指令
- 调换一下顺序:make 执行第一part的指令
1 clean: 2 rm -f myfile.i myfile.s myfile.o myfile 3 4 myfile:myfile.o 5 gcc -o myfile myfile.o 6 myfile.o:myfile.s 7 gcc -c -o myfile.o myfile.s 8 myfile.s:myfile.i 9 gcc -S -o myfile.s myfile.i 10 myfile.i:myfile.c 11 gcc -E -o myfile.i myfile.c
但是一般我们这种clean的目标文件,我们将它设置为伪目标,用 .PHONY 修饰,伪目标的特性是, 总是被执行的 。 可以将我们的 myfile 目标文件声明成伪目标,测试一下
- 未加.PHONY
- 加了.PHONY
1
1 myfile:myfile.o 2 gcc -o myfile myfile.o 3 myfile.o:myfile.s 4 gcc -c -o myfile.o myfile.s 5 myfile.s:myfile.i 6 gcc -S -o myfile.s myfile.i 7 myfile.i:myfile.c 8 gcc -E -o myfile.i myfile.c 9 10 11 .PHONY:clean 12 clean: 13 rm -f myfile.i myfile.s myfile.o myfile
2
1 .PHONY:myfile 2 myfile:myfile.c 3 gcc -o myfile myfile.c 4 5 .PHONY:clean 6 clean: 7 rm -f myfile
一般只clean部分总是执行
可重复执行的依据
touch已存在的文件,更新其时间
[root@VM-12-17-centos lesson7]# vim myfile.c [root@VM-12-17-centos lesson7]# make gcc -o myfile myfile.c [root@VM-12-17-centos lesson7]# ll total 20 -rw-r--r-- 1 root root 359 Jan 12 21:59 Makefile -rwxr-xr-x 1 root root 8360 Jan 12 22:01 myfile -rw-r--r-- 1 root root 100 Jan 12 22:01 myfile.c [root@VM-12-17-centos lesson7]# stat myfile File: ‘myfile’ Size: 8360 Blocks: 24 IO Block: 4096 regular file Device: fd01h/64769d Inode: 790145 Links: 1 Access: (0755/-rwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/ root) Access: 2023-01-12 22:01:58.304080944 +0800 Modify: 2023-01-12 22:01:58.002078678 +0800 Change: 2023-01-12 22:01:58.002078678 +0800 Birth: - [root@VM-12-17-centos lesson7]# stat myfile.c File: ‘myfile.c’ Size: 100 Blocks: 8 IO Block: 4096 regular file Device: fd01h/64769d Inode: 790102 Links: 1 Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root) Access: 2023-01-12 22:01:52.357036316 +0800 Modify: 2023-01-12 22:01:52.355036301 +0800 Change: 2023-01-12 22:01:52.355036301 +0800 Birth: - [root@VM-12-17-centos lesson7]# touch myfile.c [root@VM-12-17-centos lesson7]# stat myfile.c File: ‘myfile.c’ Size: 100 Blocks: 8 IO Block: 4096 regular file Device: fd01h/64769d Inode: 790102 Links: 1 Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root) Access: 2023-01-12 22:02:42.314411188 +0800 Modify: 2023-01-12 22:02:40.966401073 +0800 Change: 2023-01-12 22:02:40.966401073 +0800 Birth: -