在 Linux 中使用 make 命令来编译程序,特别是大程序;而 make 命令所执行的动作依赖于 Makefile 文件。
最简单的Makefile文件:
hello: hello.c //最简单的Makefile文件
gcc -o hello hello.c
clean:
rm -f hello
Makefile的核心——规则
目标 : 依赖1 依赖2 ……
[TAB]命令
当“目标文件”不存在,或某个以来文件比目标文件“新”,则执行“命令”。
示例:
test:a.o b.o
gcc a.o b.o -o test
a.o : a.c
gcc a.c -o a.o -c
b.o : b.c
gcc b.c -o b.o -c
Makefile的语法
1、通配符
假如一个目标文件所依赖的依赖文件很多,那样岂不是我们要写很多规则,这显然是不合乎常理的。
我们可以使用通配符,来解决这些问题。
我们对上面示例进行修改:
test: a.o b.o
gcc -o test $^
%.o : %.c
gcc -c -o $@ $<
clean:
rm *.o test -f
通配符:%.o
$@ 表示目标
$< 表示第一个依赖文件
$^ 表示所有依赖文件
2、假想目标: .PHONY
要清除文件,我们在Makefile的结尾添加如下代码就可:
clean:
rm *.o test
1)执行 make
:生成第一个可执行文件。
2)执行 make clean
: 清除所有文件,即执行: rm \*.o test
。
3、即时变量、延时变量
变量定义:
A = xxx // 延时变量
B := xxx // 即时变量
C ?= xxx // 延时变量,只有第一次定义时赋值才成功;如果曾定义过,此赋值无效
D += yyy // 附加,它是即时变量还是延时变量取决于前面的定义
Makefile函数
makefile里面可以包含很多函数,这些函数都是make本身实现的,下面我们来几个常用的函数。引用一个函数用“$
”
函数foreach
$(foreach var,list,text)
对 list 中的每一个元素,取出来赋给 var,然后把 var 改为 text 所描述的形式。
A = a b c
B = $(foreach f, &(A), $(f).o)
all:
@echo B = $(B)
结果:
B = a.o b.o c.o
函数filter/filter-out
函数filter/filter-out语法如下:
$(filter pattern...,text) # 在text中取出符合patten格式的值
$(filter-out pattern...,text) # 在text中取出不符合patten格式的值
实例:
C = a b c d/
D = $(filter %/, $(C))
E = $(filter-out %/, $(C))
all:
@echo D = $(D)
@echo E = $(E)
结果:
D = d/
E = a b c
Wildcard
函数Wildcard语法如下:
$(wildcard pattern) # pattern定义了文件名的格式, wildcard取出其中存在的文件。
这个函数 wildcard 会以 pattern 这个格式,去寻找存在的文件,返回存在文件的名字。
实例:
在该目录下创建三个文件:a.c b.c c.c
files = $(wildcard *.c)
all:
@echo files = $(files)
结果:
files = a.c b.c c.c
我们也可以用wildcard函数来判断,真实存在的文件
实例:
files2 = a.c b.c c.c d.c e.c abc
files3 = $(wildcard $(files2))
all:
@echo files3 = $(files3)
结果:
files3 = a.c b.c c.c
patsubst函数
函数 patsubst 语法如下:
$(patsubst pattern,replacement,$(text))
patsubst 函数是从 text 变量里面取出每一个值,如果这个符合 pattern 格式,把它替换成 replacement 格式。
实例:
files2 = a.c b.c c.c d.c e.c abc
dep_files = $(patsubst %.c, %.d, $(files2))
all:
@echo dep_files = $(dep_files)
结果:
dep_files = a.d b.d c.d d.d e.d abc