概述
makefile是一款对工程进行自动化编译的工具,可以决定哪些文件先编译,哪些文件后编译,哪些文件重新编译。也像shell脚本一样可以执行操作系统命令。只要写好了makefile,通过make命令,整个工程就完全自动编译。makefile中写的就是一条条编译指令。
make是一个命令工具,用来解释makefile中的指令并执行。
关于程序的编译和链接
对于C/C++源文件,首先要把源文件编译成中间代码文件,unix下是.o文件,即目标文件(object file),这个动作叫编译(compile)。然后把大量的目标文件合成可执行文件,这个动作叫链接(link)。
编译时,编译器需要的是语法正确,函数和变量的声明正确。对于后者,需要要你告诉编译器头文件所在的位置,头文件中只是声明,而定义应该放在c++ 源文件中。只要语法正确,编译器就可以生成中间目标文件。一般来说,每个源文件对应一个中间目标文件。链接时主要是链接函数和全局变量。链接器不管函数所在源文件,只管中间目标文件。
在大多时候,由于源文件太多,编译生成的目标文件太多,而在链接时需要明显的指出中间目标文件名称,这对编译很不方便。所以要给中间目标文件打个包。在windows下这种包叫“库文件”(library file),就是.lib文件。在Unix下是Archive file,就是.a文件。
Makefile介绍
make命令执行时,需要一个makefile文件,以告诉make命令需要怎么样去编译和链接程序。编写makefile就是在告诉make命令如何去编译和链接工程中的文件。
相关规则:
Makefile的规则
target ... : prerequisites ...
command
target是目标文件,也可以是执行文件。还可以是一个label。prerequisites就是要生成那个target所需要的文件或者目标。
command就是make需要执行的命令,可以是任意的shell命令。
target这一个或多个目标文件依赖于prerequisites中的文件,其生成规则定义在command中。如果prerequisites中有一个以上的文件比target新的话,command命令就会被执行。这就是makefile的规则,也是makefile中最核心的内容。
main.o : main.c defs.h \
insert.h
其中反斜杠是换行的意思。
makefile模板,如下:
目标文件 : 生成目标文件所需要的文件
具体执行命令
从下往上先写源文件编译成目标文件,然后是目标文件链接成可执行文件
具体执行和书写就是把这些指令存在一个名为Makefile的文件中,然后在该文件所在的目录下直接执行make命令就可以生成可执行文件了。光写make命令就可以,后面不需要加Makefile文件名称。
如果要删除执行文件和所有的中间目标文件,那么只要简单的执行下make clean命令就可以。
command这一行要以tab键作为开头。make会比较targets和prerequisites文件的修改日期,如果prerequisites文件的日期要比targets新,或者target不存在的话,那么make就会执行后续定义的命令。
clean :
rm editmain.o command.o display.o \
insert.o
这里clean不是一个文件,他只不过是一个动作名字,有点像c语言的label一样,冒号后面什么都没有,那么make就不会自动去找文件见的依赖性,也就不会自动执行其后所定义的命令。如果要执行其后的命令,就需要在make命令后面显示的指出这个label的名字。这样的方法很有用,是我们可以在makefile中定义不用的编译或者是和编译无关的命令,比如程序打包、程序备份等。
make是如何工作的
makefile中使用变量
makefile中的变量也就是一个字符串,理解成C语言中的宏可能会更好。
# 未使用变量
edit : main.o kbd.o command.o \
insert.o
cc -o edit main.o kbd.o command.o \
insert.o
# 使用变量时
objects = main.o kbd.o command.o \
insert.o
edit : $(objects)
cc -o edit $(objects)
makefile中使用变量获取值的方式:$(objects),如果有新的.o文件加入,只需简单修改下objects变量就可以了。