如何写 makefile文件
学习别人的程序就面临着重写makefile的问题.下面以问答的形式来解释如何写makefile文件.
1.makefile的核心:
target...(目标文件|object文件|可执行文件|标签) : prerequisites( 生成target所需要的文件,也可以是target中的一种...)
Command (shell 命令)
target这一个或多个的目标文件依赖于prerequisites中的文件,其生成规则定义在command中。prerequisites中如果有一个以上的文件比target文件更新的话,command所定义的命令就会执行。
2.make 的工作原理:
例, 文件名:makefiletest
test : test.o
gcc -o test test.o
test.o: test.h test.c
gcc -c test.c
clean:
rm test.o test
在默认方式下,只输入make命令。其会做如下工作:
make会在当前目录下找名字为“Makefile文件”或“makefile文件”的文件。如果找到,它会找文件中的第一个目标文件(target)。在上面的例子中,它会找到makefiletest这个文件,并把test作为最终的目标文件;如果test文件不存在,或是test所依赖的后面的 .o 文件的修改时间要比test这个文件新,它就会执行后面所定义的命令来生成test文件。
如果test所依赖的.o文件也存在,make会在当前文件中找目标为.o文件的依赖性,如果找到,则会根据规则生成.o文件(这有点像一个堆栈的过程)。
当然,C文件和H文件如果存在,make会生成 .o 文件,然后再用 .o 文件生成make的最终结果,也就是执行文件test。
这就是整个make的依赖性,make会一层又一层地去找文件的依赖关系,直到最终编译出第一个目标文件。在找寻的过程中,如果出现错误,比如最后被依赖的文件找不到,make就会直接退出,并报错。而对于所定义的命令的错误,或是编译不成功,make就不会处理。如果在make找到了依赖关系之后,冒号后面的文件不存在,make仍不工作
通过上述分析,可以看出像clean这样没有被第一个目标文件直接或间接关联时,它后面所定义的命令将不会被自动执行,不过,可以显式使make执行。即使用命令make clean,以此来清除所有的目标文件,并重新编译。
在编程中,如果这个工程已被编译过了,当修改了其中一个源文件时,比如test.c,根据依赖性,目标test.o会被重新编译(也就是在这个依赖性关系后面所定义的命令),则test.o文件也是最新的,即test.o文件的修改时间要比test要新,所以test也会被重新连接了。
3 定义变量:
ltest=test.h test.c
上面的makefiletest可以改写为:
test : test.o
gcc -o test test.o
test.o: $(ltest)
gcc -c test.c
clean:
rm test.o test
4 makefile文件的自动推导
test : test.o
gcc -o test test.o
test.o: test.h
clean:
rm test.o test
看一下test.o这个target,省略了 prerequisites的 test.c和command的gcc -c test.c,这些是target为test.o能推导出来的.
5 清空目标文件
.PHONY : clean
clean :
-rm test.o test
前面说过,.PHONY表示clean是一个“伪目标”,而在rm命令前面加了一个小减号的目的是,如果某些文 件出现问题将被忽略,继续进行后面的操作。当然,clean的规则不要放在文件的开头,否则会变成make的 默认目标。不成文的规矩是“clean从来都放在文件的最后”
6.注释:
#. 为行注释,与//类似
7.显示指定makefile文件名
将makefiletest改为make.test
make -f make.test
8.TAB键
为command命令的识别键,在command头使用,最好不要用在其它地方
9.包含 其它 makefile文件
include <filename>
filename可以是当前操作系统Shell的文件模式(可以保含路径和通配符)。在include前面可以有一些空字符,但是绝不能以[Tab]键开始。include和<filename>可以用一个或多个空格隔开。举个例子,有这样几个makefile文件:a.mk、b.mk、c.mk,还有一个文件叫foo.make,以及一个变量$(bar),其包含了e.mk和f.mk,下面的语句:
include foo.make *.mk $(bar)
等价于:
include foo.make a.mk b.mk c.mk e.mk f.mk
10 -include和sinclude 都可以ignore error,
11. make的工作顺序
(1) 读入所有的makefile文件。
(2) 读入被include包括的其他makefile文件。
(3) 初始化文件中的变量。
(4) 推导隐式规则,并分析所有规则。
(5) 为所有的目标文件创建依赖关系链。
(6) 根据依赖关系,决定哪些目标要重新生成。
(7) 执行生成命令。
12.转义字符与通配符
/
*,?,[...],~
其它请参见用户手册.