<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">假设有下面几个文件:</span>
maze.h maze.c main.h main.c stack.h stack.c
但是这个方法不好,当对maze.c做了一点点的修改之后就要重新编译那些没有修改的文件。当然首先想到的解决办法就是用下面这种方式
gcc -c main.c gcc -c maze.c gcc -c stack.c gcc main.o maze.o stack.o -o main但是这种方式导致了当改变一个文件之后,每次编译的命令都不一样,恒容易出错。
可以编写一个简单的makefile来解决上面这些问题:
main: main.o stack.o maze.o gcc main.o stack.o maze.o -o main main.o: main.c main.h maze.h stack.h gcc -c main.c maze.o: maze.c maze.h main.h gcc -c maze.c stack.o: stack.c stack.h main.h gcc -c stack.c
makefile的一般规则如下所示:
target ...: prerequisites .... command1: command2: ....目标与条件的一般关系为:想要更行目标必须要先更新其所有的条件,所有的条件指套有一个被更新了,那么目标也会被更新。
所以说makefile执行的一般步骤就是:
1.检查规则A的每个条件P: 如果存在以P为目标的规则B,那么执行规则B 如果找不到以P为目标的规则,而且P已存在,那么表示P不需要更新 上述情况如果P不存在的话就报错退出 2.检查完A的所有条件后,检查目标T。如果有如下的情况之一,那么表示T需要更新,那么执行起命令列表,执行完成后无论是否生成文件T,都认为T被更新了 文件T不存在 文件T存在,但是一个是条件的文件P起修改时间晚于T的修改时间 某个条件P被更新过
每个makefile实际上也对应着一套clean规则,用于清理编译生成的二进制文件。
对应上面这个例子,可以在makefile的最后加入下面的clean规则:
clean: @echo "cleaning project" -rm main *.o @echo "clean complete"
使用clean可以通过执行make clean来实现。
这里的clean实际上也是一个目标,指定了make clean相当于也就指定了clean这个目标,那么执行clean后面的方法,如实如果不指定的话就会指定默认的目标,也就是第一行的第一条。(但是实际上不会生成clean目标,应为正如前面所说,只要执行了命令列表就算更行了目标(这里是clean),有的命令列表是不会生成目标的)
注意,上面的命令前面加上了-以及@符号
命令前面的-表示的是:即使这条命令执行出错了,那么也会继续向后执行
命令前面的@表示的是:不会显示命令本身而只是显示其产生的结果。
注意因为有clean规则,但是不需要什么文件,如果目录下存在一个clean的文件的话,那么make clean实际上不会执行任何操作,如果想要避免这种情况的发生可以使用,可以加一条特殊的规则,讲clean作为伪目标:
.PHONY: clean //这里就将clean作为是伪目标,不会去关注外面已经生成的clean文件。类似clean这样的约定俗成的名字还有:
all,执行主要的编译工作,通常作为缺省的目标
install,执行编译完成之后的安装工作
clean ,删除编译生成的二进制文件
disclean, 删除除源码之外的所有文件