分类: C/C++
2015-03-07 15:05:19
对于复杂的C程序,.c文件不只一个,如果经常更新,把所有的.c文件都要重新编译一次肯定没问题,问题是编译过程往往比较耗时,如果只改了某一个文件的一行代码,也要全部重新编译,这肯定不合理,有没有一种机制根据只编译改动的文件的关联的那部分文件呢?
复杂的C程序,每次编译都用gcc,那得用多少次gcc?简单的办法是写个shell脚本,但是shell脚本的功能还不够,有些灵活的用法无法实现。
Makefile就是用来解决这两个问题的。
Makefile的基本规则就是: 目标:条件1,条件2... 命令
先判断目标文件是否存在,不存在就根据命令创建,创建之前,判断条件中的文件是否都存在,假定条件1不存在或者已经更新了,就看以条件1为目标的那行语句的对应关系。一次类推。形成了一个复杂又有条理的依赖关系。
通常判断是否需要更新有3个条件:
目标没有生成。
某个条件需要更新。
某个条件的修改时间比目标晚。
在一条规则被执行之前,规则的条件可能处于以下三种状态之一:
· 需要更新。能够找到以该条件为目标的规则,并且该规则中目标需要更新。
· 不需要更新。能够找到以该条件为目标的规则,但是该规则中目标不需要更新;或者不能找到以该条件为目标的规则,并且该条件已经生成。
· 错误。不能找到以该条件为目标的规则,并且该条件没有生成。
执行一条规则A的步骤如下:
1. 检查它的每个条件P:
· 如果P需要更新,就执行以P为目标的规则B。之后,无论是否生成文件P,都认为P已被更新。
· 如果找不到规则B,并且文件P已存在,表示P不需要更新。
· 如果找不到规则B,并且文件P不存在,则报错退出。
2. 在检查完规则A的所有条件后,检查它的目标T,如果属于以下情况之一,就执行它的命令列表:
· 文件T不存在。
· 文件T存在,但是某个条件的修改时间比它晚。
· 某个条件P已被更新(并不一定生成文件P)。
clean:
@echo "cleanning project"
-rm main *.o
@echo "clean completed"
.PHONY: clean #伪目标避免存在一个名叫clean文件导致冲突
通常一个Makefile中的伪目标至少有如下4个:
· all,执行主要的编译工作,通常用作缺省目标。
· install,执行编译后的安装工作,把可执行文件、配置文件、文档等分别拷到不同的安装目录。
· clean,删除编译生成的二进制文件。
· distclean,不仅删除编译生成的二进制文件,也删除其它生成的文件,例如配置文件和格式转换后的文档,执行make distclean之后应该清除所有这些文件,只留下源文件。
执行make命令时,是按照GNUmakefile、makefile、Makefile的顺序找到第一个存在的文件并执行它,不过还是建议使用Makefile做文件名