选项:
-j 指定同时允许执行多少条命令
-k 忽略执行命令的错误,继续执行
-t 更新时间戳
$(wildcard *.c)
获取工作目录下的所有的.c文件列表
$(patsubst %.c,%.o,$(wildcard *.c))
首先使用“wildcard”函数获取工作目录下的.c文件列表;之后将列表中所有文件名的后缀.c替换为.o。这样我们就可以得到在当前目录可生成的.o文件列表
$(subst output,,$@)
替换子串
$(filter %.o,$(files))
过滤字串
$(addsuffix .c,$@)
增加后缀
${VAR:A=B}
替换变量“VAR”中所有“A”字符结尾的字为“B”结尾的字
VPATH
Makefile中所有文件的搜索路径
1、vpath PATTERN DIRECTORIES
为所有符合模式“PATTERN”的文件指定搜索目录“DIRECTORIES”。多个目录使用空格或者冒号(:)分开。类似上一小节的“VPATH”变量。
2、vpath PATTERN
清除之前为符合模式“PATTERN”的文件设置的搜索路径。
3、vpath
清除所有已被设置的文件搜索路径。
$(CFLAGS)
编译.c文件时gcc的编译选项
$(MAKE)
对变量“MAKE”的引用
$(CURDIR)
当前目录
$?
代表依赖中被修改过的文件列表
$^
代表所有通过目录搜索得到的依赖文件的完整路径名(目录 + 一般文件名)列表
$@
代表规则的目标
$<
代表规则中通过目录搜索得到的依赖文件列表的第一个依赖文件
$*
.LIBPATTERNS
值为:“lib%.so lib%.a”
指定依赖库,例:
foo : foo.c -lcurses
cc $^ -o $@
伪目标, 例:
.PHONY: clean
clean:
rm *.o temp
子目录编译,例:
SUBDIRS = foo bar baz
.PHONY: subdirs $(SUBDIRS)
subdirs: $(SUBDIRS)
$(SUBDIRS):
$(MAKE) -C $@
伪目标嵌套,例:
.PHONY: cleanall cleanobj cleandiff
cleanall : cleanobj cleandiff
rm program
cleanobj :
rm *.o
cleandiff :
rm *.diff
foo: baz
环境变量:
MAKELEVEL
调用深度
MAKEFLAGS
可传递的命令行参数, “-C”、“-f”、“-o”和“-W”除外
Makefile的特殊目标:
.PHONY:
目标“.PHONY”的所有的依赖被作为伪目标。
.SUFFIXES:
特殊目标“SUFFIXES”的所有依赖指出了一系列在后缀规则中需要检查的后缀名(就是当前make需要处理的后缀)。
.DEFAULT
Makefile中,目标“.DEFAULT”所在规则定义的命令,被用在重建那些没有具体规则的目标(明确规则和隐含规则)
.PRECIOUS
目标“.PRECIOUS”的所有依赖文件在make过程中会被特殊处理:当命令在执行过程中被中断时,make不会删除它们
.INTERMEDIATE
目标“.INTERMEDIATE”的依赖文件在make时被作为中间过程文件对待。
.SECONDARY
目标“.SECONDARY”的依赖文件被作为中间过程文件对待。
.DELETE_ON_ERROR
如果在Makefile中存在特殊目标“.DELETE_ON_ERROR”,make在执行过程中,如果规则的命令执行错误,将删除已经被修改的目标文件
.IGNORE
如果给目标“.IGNORE”指定依赖文件,则忽略创建这个文件所执行命令的错误。
.LOW_RESOLUTION_TIME
目标“.LOW_RESOLUTION_TIME”的依赖文件被make认为是低分辨率时间戳文件。
.SILENT
出现在目标“.SILENT”的依赖列表中的文件,make在创建这些文件时,不打印出重建此文件所执行的命令。
.EXPORT_ALL_VARIABLES
此目标应该作为一个简单的没有依赖的目标,它的功能含义是将之后所有的变量传递给子make进程。
.NOTPARALLEL
Makefile中,如果出现目标“.NOPARALLEL”,则所有命令按照串行方式执行,即使存在make的命令行参数“-j”。但在递归调用的字make进程中,命令可以并行执行
双冒号规则与单冒号规则的区别:
1. 双冒号规则中,当依赖文件比目标更新时。规则将会被执行。对于一个没有依赖而只有命令行的双冒号规则,当引用此目标时,规则的命令将会被无条件执行。而普通规则,当规则的目标文件存在时,此规则的命令永远不会被执行(目标文件永远是最新的)。
2. 当同一个文件作为多个双冒号规则的目标时。这些不同的规则会被独立的处理,而不是像普通规则那样合并所有的依赖到一个目标文件。这就意味着对这些规则的处理就像多个不同的普通规则一样。就是说多个双冒号规则中的每一个的依赖文件被改变之后,make只执行此规则定义的命令,而其它的以这个文件作为目标的双冒号规则将不会被执行。
子目录的编译:
subsystem:
cd subdir && $(MAKE)
或
subsystem:
$(MAKE) -C subdir
=
递归展开式
:=
直接展开,定义时展开
?=
条件展开式,如果之前没定义,则展开
cat cmp cp diff echo egrep expr false grep install-info
ln ls mkdir mv pwd rm rmdir sed sleep sort tar test touch true
ar bison cc flex install ld ldconfig lex
make makeinfo ranlib texi2dvi yacc
-j 指定同时允许执行多少条命令
-k 忽略执行命令的错误,继续执行
-t 更新时间戳
$(wildcard *.c)
获取工作目录下的所有的.c文件列表
$(patsubst %.c,%.o,$(wildcard *.c))
首先使用“wildcard”函数获取工作目录下的.c文件列表;之后将列表中所有文件名的后缀.c替换为.o。这样我们就可以得到在当前目录可生成的.o文件列表
$(subst output,,$@)
替换子串
$(filter %.o,$(files))
过滤字串
$(addsuffix .c,$@)
增加后缀
${VAR:A=B}
替换变量“VAR”中所有“A”字符结尾的字为“B”结尾的字
VPATH
Makefile中所有文件的搜索路径
1、vpath PATTERN DIRECTORIES
为所有符合模式“PATTERN”的文件指定搜索目录“DIRECTORIES”。多个目录使用空格或者冒号(:)分开。类似上一小节的“VPATH”变量。
2、vpath PATTERN
清除之前为符合模式“PATTERN”的文件设置的搜索路径。
3、vpath
清除所有已被设置的文件搜索路径。
$(CFLAGS)
编译.c文件时gcc的编译选项
$(MAKE)
对变量“MAKE”的引用
$(CURDIR)
当前目录
$?
代表依赖中被修改过的文件列表
$^
代表所有通过目录搜索得到的依赖文件的完整路径名(目录 + 一般文件名)列表
$@
代表规则的目标
$<
代表规则中通过目录搜索得到的依赖文件列表的第一个依赖文件
$*
.LIBPATTERNS
值为:“lib%.so lib%.a”
指定依赖库,例:
foo : foo.c -lcurses
cc $^ -o $@
伪目标, 例:
.PHONY: clean
clean:
rm *.o temp
子目录编译,例:
SUBDIRS = foo bar baz
.PHONY: subdirs $(SUBDIRS)
subdirs: $(SUBDIRS)
$(SUBDIRS):
$(MAKE) -C $@
伪目标嵌套,例:
.PHONY: cleanall cleanobj cleandiff
cleanall : cleanobj cleandiff
rm program
cleanobj :
rm *.o
cleandiff :
rm *.diff
foo: baz
环境变量:
MAKELEVEL
调用深度
MAKEFLAGS
可传递的命令行参数, “-C”、“-f”、“-o”和“-W”除外
Makefile的特殊目标:
.PHONY:
目标“.PHONY”的所有的依赖被作为伪目标。
.SUFFIXES:
特殊目标“SUFFIXES”的所有依赖指出了一系列在后缀规则中需要检查的后缀名(就是当前make需要处理的后缀)。
.DEFAULT
Makefile中,目标“.DEFAULT”所在规则定义的命令,被用在重建那些没有具体规则的目标(明确规则和隐含规则)
.PRECIOUS
目标“.PRECIOUS”的所有依赖文件在make过程中会被特殊处理:当命令在执行过程中被中断时,make不会删除它们
.INTERMEDIATE
目标“.INTERMEDIATE”的依赖文件在make时被作为中间过程文件对待。
.SECONDARY
目标“.SECONDARY”的依赖文件被作为中间过程文件对待。
.DELETE_ON_ERROR
如果在Makefile中存在特殊目标“.DELETE_ON_ERROR”,make在执行过程中,如果规则的命令执行错误,将删除已经被修改的目标文件
.IGNORE
如果给目标“.IGNORE”指定依赖文件,则忽略创建这个文件所执行命令的错误。
.LOW_RESOLUTION_TIME
目标“.LOW_RESOLUTION_TIME”的依赖文件被make认为是低分辨率时间戳文件。
.SILENT
出现在目标“.SILENT”的依赖列表中的文件,make在创建这些文件时,不打印出重建此文件所执行的命令。
.EXPORT_ALL_VARIABLES
此目标应该作为一个简单的没有依赖的目标,它的功能含义是将之后所有的变量传递给子make进程。
.NOTPARALLEL
Makefile中,如果出现目标“.NOPARALLEL”,则所有命令按照串行方式执行,即使存在make的命令行参数“-j”。但在递归调用的字make进程中,命令可以并行执行
双冒号规则与单冒号规则的区别:
1. 双冒号规则中,当依赖文件比目标更新时。规则将会被执行。对于一个没有依赖而只有命令行的双冒号规则,当引用此目标时,规则的命令将会被无条件执行。而普通规则,当规则的目标文件存在时,此规则的命令永远不会被执行(目标文件永远是最新的)。
2. 当同一个文件作为多个双冒号规则的目标时。这些不同的规则会被独立的处理,而不是像普通规则那样合并所有的依赖到一个目标文件。这就意味着对这些规则的处理就像多个不同的普通规则一样。就是说多个双冒号规则中的每一个的依赖文件被改变之后,make只执行此规则定义的命令,而其它的以这个文件作为目标的双冒号规则将不会被执行。
子目录的编译:
subsystem:
cd subdir && $(MAKE)
或
subsystem:
$(MAKE) -C subdir
=
递归展开式
:=
直接展开,定义时展开
?=
条件展开式,如果之前没定义,则展开
cat cmp cp diff echo egrep expr false grep install-info
ln ls mkdir mv pwd rm rmdir sed sleep sort tar test touch true
ar bison cc flex install ld ldconfig lex
make makeinfo ranlib texi2dvi yacc