makefie最基本的语法是规则,规则:
目标 : 依赖1 依赖2 … [TAB]命令//命令必须以[TAB]开始
规则执行的条件:
1、目标文件不存在
2、依赖文件比目标新
当“依赖”比“目标”新,执行它们下面的命令,写成makefile规则,如下:
test :a.o b.o //test是目标,它依赖于a.o b.o文件,一旦a.o或者b.o比test新的时候, 就需要执行下面的命令,重新生成test可执行程序。
gcc -o test a.o b.o a.o : a.c //a.o依赖于a.c,当a.c更加新的话,执行下面的命令来生成a.o
gcc -c -o a.o a.c b.o : b.c //b.o依赖于b.c,当b.c更加新的话,执行下面的命令,来生成b.o gcc -c -o b.o b.c
为了规避引用规则很多的问题,通常使用通配符,下面是常见的通配符
| #管道符,或者(正则)
% #匹配零或若干字符
’‘ #匹配一系列文件
< #输入重定向
<< #追加输入重定向
~ #当前用户家目录
`` $() #引用命令被执行后的结果
$ #以。。。结尾(正则)
^ #以。。。开头(正则)
‘’ #匹配全部字符,通配符
? #任意一个字符,通配符
#注释
& #让程序或脚本切换到后台执行
&& #并且 同时成立
[] #表示一个范围(正则,通配符)
{} #产生一个序列(通配符)
. #当前目录的硬链接
… #上级目录的硬链接
例子:
%.o:表示所用的.o文件
%.c:表示所有的.c文件
$@:表示目标文件的集合
$<:表示第1个依赖文件
$^:表示所有依赖文件
假想目标.PHONY(避免判断同名文件存在而不执行此目标文件)
例子:清除文件(加在Makefile结尾):执行make clean即执行: rm *.o test。
clean:
[TAB]rm *.o test
.PHONY: clean//把clean定义为假象目标。他就不会判断名为“clean”的文件是否存在
变量
1、简单变量(即使变量):
A := xxx # A的值即刻确定,在定义时即确定
2、延时变量:
B = xxx # B的值使用到时才确定,定义时不确定
使用变量需要使用"
"
来引用
[
如
"来引用[如
"来引用[如(obj)或${obj}],不显示命令本身可以在命令前加上"@"(执行@echo A = $(A) 打印A= )
常用的变量定义如下:
:= # 即时变量
= # 延时变量
?= # 延时变量, 如果是第1次定义才起效, 如果在前面该变量已定义则忽略这句
+= # 附加, 它是即时变量还是延时变量取决于前面的定义
?=: 如果这个变量在前面已经被定义了,这句话就会不会起效果,
变量导出(export):某个变量的值在所有目录中都可见
Makeflie中可以使用shell命令:
比如:TOPDIR := $(shell pwd)//等于pwd后的结果
常用函数:
1、$(foreach var,list,text):展开分别扩展for each var in list, change it to text
例:objs := a.o b.o
dep_files := $(foreach f,
(
o
b
j
s
)
,
.
(objs), .
(objs),.(f).d) // 最终 dep_files := .a.o.d .b.o.d
2、$(wildcard pattern) :pattern定义文件名的格式,wildcard取出其中存在的文件
这个函数wildcard会以pattern这个格式,去寻找存在的文件,返回存在文件的名字
例:src_files := $( wildcard *.c) // 最终 src_files中列出了当前目录下的所有.c文件
3、$(filter pattern…,text):把text中符合pattern格式的内容,filter(过滤)出来、留下来。
例:obj-y := a.o b.o c/ d/
DIR := $(filter %/, $(obj-y)) //结果为:c/ d/
4、$(filter-out pattern…,text):把text中符合patten格式的内容,filter过滤出来,丢掉
例:obj-y := a.o b.o c/ d/
DIR := $(filter-out %/, $(obj-y)) //结果为:a.o b.o
5、$(patsubst pattern,replacement,text):寻找‘text‘中符合格式’pattern‘的字,并用’replacement’替换。pattern’和
replacement’中可以使用通配符。
例:subdir-y := c/ d/
subdir-y := $(patsubst %/, %, $(subdir-y)) // 结果为:c d