1. make命令和makefile文件
makefile关系到整个工程的编译规则,一个工程中的源文件不计其数,按照类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定哪些文件需要先编译,那些文件需要后编译;当有文被修改时,哪些文件需要重新编译;甚至更复杂的功能操作,makefile就像一个shell脚本,其中也能执行操作系统命令。makefile带来的最大好处是”自动化编译“,一旦写好makefile文件,只需要一个make命令,整个工程完全自动编译。
make是一个命令工具,用于解释makefile文件。大多数的IDE都自带了类似的命令。make命令执行时,需要一个makefile文件,告诉make命令需要如何去编译和链接程序。
2.makefile规则
target : prerequisites
command
target 也就是一个目标文件,可以是.o或可执行文件,还可以是”伪目标“;prerequisites是target所依赖的文件,command是make需要执行的命令(任意的shell命令)。make的核心规则是:如果prerequisites中有一个以上的文件比target文件要新的话,command所定义的命令就会被执行。
如下是一个简单的makefile文件
1 main : main.o lib.o 2 g++ -o main main.o lib.o 3 4 main.o : main.cpp 5 gcc -o main.o main.cpp 6 7 lib.o : lib.cpp 8 gcc -o lib.o lib.cpp 9 10 clean : 11 rm main *.o
其中,可执行文件main需要依赖于目标文件main.o 和lib.o来链接生成,而main.o和lib.o 分别需要用main.cpp和lib.cpp来编译生成。默认方式下,只需输入make命令,其工作过程如下:
2.1. make在当前目录下寻找文件名为Makefile或makefile的文件,并读入文件。
2.2. 寻找文件中第一个目标文件(例子中的main),并将其当作最终的目标文件。如果main文件不存在,或者后面的main.o或lib.o文件比main文件要新,则make会执行后面所定义的命令(g++)来生成main文件。
2.3. 如果main所依赖的文件 main.o或lib.o 也不存在,则会根据.o文件的依赖性,生成.o文件。make一层层找依赖关系,知道最终编译出第一个目标文件。
2.4. 在寻找依赖关系的过程中,如果出现错误,比如最后被依赖的文件找不到,make会直接退出并报错,而对于所定义的命令的错误,或者编译不成功,make不会理会。make只管文件的依赖性。
2.5. 类似上面makefile中的clean,没有被第一个目标文件直接或间接依赖,那么它后面的命令(rm)将不会被执行,所以需要显示make执行,即命令 "make clean"。
3.makefile中使用变量
相当于c语言的宏——字符串替代,赋值时用"="或":=",取值时用"$()"或${}
1 CC := gcc 2 CXX := g++ 3 4 main : main.o lib.o 5 $(CXX) *.o -o main 6 main.o : main.cpp 7 $(CC) -c main.cpp 8 lib.o : lib.cpp 9 $(CC) -c lib.cpp 10 11 clean : 12 rm *.o main
=和:=的区别:
3.1 "="
make会将整个makefile展开之后,再决定变量的值。也就是说,变量的值将会是整个makefile中最后被指定的值。
1 x = foo 2 y = $(x)bar 3 x = xyz
上例中,x的值将会是xyzbar,而不是foobar.
3.2 ":="
":="表示变量的值取决于在makefile中的位置,而不是整个makefile展开后的最终值。
1 x := foo 2 y := $(x)bar 3 x := xyz
上例中,y的值将会是foobar,不是xyzbar.
4.引用其它makefile
include /home/tafjce/FightServer/FightServer.mk
5. 一个小问题
makefile中command之前必须是tab键
参考:GUNmake 中文手册 http://os.chinaunix.net/a2008/1006/986/000000986738.shtml