makefile就是创建一个文件叫做 makefile 。
我们敲出上图代码。正常情况下,我们要编译 test.c 文件,我们直接 gcc test.c ,加上 -o [文件名]可以指定编译出来的可执行程序名字。
其中 test:test.c 冒号左边是生成的程序名,冒号右边的是程序生成依赖的文件,这一行是依赖关系。而下面一行则是依赖方法,记住,下面一行开头必须是 tab 键。
clean没有依赖的文件,所以后面不接文件名,下面同样是依赖方法。而 .PHONY: 则是将clean修饰成伪目标。
做好上述的的准备之后,我们输入 make
就会发现,系统会自动帮我们输入依赖关系。当操作的文件非常多的时候,这是极其方便的。
我们再次 make 就会发现系统提示我们 test 文件已经是最新的了,不能再编译。
我们想要删除输入:make clean ,可是我们却发现 make clean 是可以一直清理的。这就是因为我们用 .PHONY 将它设置成了伪目标,伪目标的特性是:总是被执行。
那么 make 是如何识别文件是不是最新的呢?
当我们用 stat 命令查看文件属性的时候,我们可以看到有:access、modify、change 三个时间。
access:是进入文件的时间,但是当一个系统运行起来的时候,同时会进入非常多的文件,如果每进入一次,就修改大量文件的时间,那么也太浪费性能了,所以就规定了一段时间进入了一定次数后才修改时间。
modifiy:是修改文件内容的时间,当修改一个文件的内容的时候,access的时间一定改变。
change:是修改文件属性的时间。
当可执行文件生成的时候会得到这三个时间,如果我们源文件修改了,时间也会刷新,当源文件的内容修改时间要比可执行文件的时间晚的时候,那么这时候我们输入 make 才会重新编译。
例如:
mycode 是依赖 mycode.o的,而 mycode.o 是依赖 mycode.s 的,mycode.s 是依赖 mycode.i的,mycode.i 是依赖 mycode.c 的,没有依赖文件就会向下去找,逐层递归,最终倒着生成。mycode.i依赖 mycode.c 生成,然后mycode.s 依赖 mycode.i 生成……,最终生成了mycode,但是我们实际上写的时候是没必要这样写的, 我们直接mycode依赖mycode.c就行了,其他的编译器会自动处理的。