1.Makefile介绍
在Linux中使用make命令来编译程序,特别是大程序;而make命令所执行的动作依赖于Makefile文件。最简单的Makefile文件如下:
hello:hello.c
gcc -o hello hello.c //以Tab键缩进
clean:
rm -f hello //以Tab键缩进
当一个文件夹中有hello.c、Makefile文件时,在linux终端中输入make命令时就可以编译程序,执行make clean即可清除编译出来的结果。make命令根据文件更新的时间戳来决定哪些文件需要重新编译,这样可以避免编译已经编译过的、没有变化的程序,提高了编译效率,这对大型工程特别有利。
2.Makefile规则
一个简单的Makefile文件包含一系列的规则,如下所示:
目标(target)...:依赖(prerequiries)
<Tab>命令(command)
目标(target)通常是要生成文件的名称,可以是可执行文件或OBJ文件,如上述的hello就是目标,属于可执行文件,
也;可以是执行的动作名称,如上述的clean。
依赖是用来产生目标的材料,如上述的hello.c,属于源文件。
命令是生成目标时所执行的动作,每个命令占一行,如上述的gcc -o hello hello.c和rm -f hello都是命令。
3.Makefile文件中变量的赋值方法
在GNU make中对变量的赋值方法有两种方式,分别为延时变量、立即变量。
3.1延时变量
延时变量在使用时才展开,即真正使用的时候这个变量的值才确定使用 =、?=、或 define 指令定义。其中?= 用来定义第一次出现的延时变量。语法形式如下:
var(变量)=val(值)
var(变量)?=val(值)
define var(变量)
3.2立即变量
立即变量的值在定义的时候就已经确定,语法形式如下:
var(变量):=val(值)
4.Makefile中的函数调用格式
Makefile中的函数调用格式如下:
$(function arguments)
这里function是函数名,arguments是该函数的参数。参数与函数名之间用空格或Tab隔开,如果有多个参数,用逗号隔开。这些空格和逗号不是参数值的一部分。
5.Makefile文件示例
此目下包含以下文件:main.c、Makefile、sub.c、sub.h。Makefile的代码如下:
//File:Makefile
01 src := $(shell ls *.c)
02 objs := $(patsubst %.c,%.o,$(src))
03
04 test: $(objs)
05 gcc -o $@ $^
06
07 %.o:%.c
08 gcc -c -o $@ $<
09
10 clean:
11 rm -f test *.o
上述Makefile中 $@
、$^
、$<
称为自动变量。$@
表示规则的目标文件名;$^
表示所有依赖的名字,名字之间用空格隔开;$<
表示第一个依赖的文件名。%
为通配符,它和一个字符串中任意个数的字符相匹配。
第一行中 src
的值为main.c sub.c
。$(shell ls *.c)
是Makefile中的函数,是查找当前目录下后缀为 .c
的文件,*
为通配符。
第二行中 objs
变量的值为 main.o sub.o
,是 src
变量经过 patsubst
函数处理后得到的。
patsubst为Makefile中的函数,为模式字符串替换函数。格式如下:
$(patsubst pattern,replacement,text)
寻找text中符合格式pattern的字,用replacement替换它们。比如:
$(patsubst %.c,%.o,x.c.c bar.c)
结果为:
x.c.o bar.o
第四行实际上就是:
test:main.o sub.o
目标test的依赖为main.o和sub.o。开始时这两个文件还没生成,在执行生成test的命令之前,先将main.o、sub.o作为目标查找合适的规则,以生产main.o、sub.o。
第七、八行就是用来生成main.o、sub.o的规则。
main.o的规则如下:
main:main.c
gcc -c -o main.o main.c
sub.o的规则如下:
sub:sub.c
gcc -c -o sub.o sub.c
这样,test的依赖main.o和sub.o就生成了。
在终端中输入make时,会看到如下信息:
gcc -c -o main.o main.c
gcc -c -o sub.o sub.c
gcc -o test main.o sub.o
其中test为可执行文件,在终端中输入make clean,则可清除编译生成的文件。