makefile 主要包含以下几点
显式规则 :描述了在何种情况下如何更新一个或者多个被称为目标的文件(Makefile的目标文件)。书写Makefile时需要明确地给出目标文件、目标的依赖文件列表以及更新目标文件所需要的命令(有些规则没有命令,这样的规则只是纯粹的描述了文件之间的依赖关系)。
隐含规则:
它是make根据一类目标文件(典型的是根据文件名的后缀)而自动推导出来的规则。make根据目标文件的名,自动产生目标的依赖文件并使用默认的命令来对目标进行更新(建立一个规则)。简单的说就是 a.c 推出 a.o 或 a.o 推出 a.c 变量定义:使用一个字符或字符串代表一段文本串,当定义了一个变量以后,Makefile后续在需要使用此文本串的地方,通过引用这个变量来实现对文本串的使用。第一章的例子中,我们就定义了一个变量“objects”来表示一个.o文件列表。 Makefile指示符:
指示符指明在make程序读取makefile文件过程中所要执行的一个动作。其中包括: 读取一个文件,读取给定文件名的文件,将其内容作为makefile文件的一部分。
决定(通常是根据一个变量的得值)处理或者忽略Makefile中的某一特定部分。
定义一个多行变量。
Makefile注释内容:Makefile中“#”字符后的内容被作为是注释内容(和shell脚本一样)处理。如果此行的第一个非空字符为“#”,那么此行为注释行。注释行的结尾如果存在反斜线(\),那么下一行也被作为注释行。一般在书写Makefile时推荐将注释作为一个独立的行,而不要和Makefile的有效行放在一行中书写。当在Makefile中需要使用字符“#”时,可以使用反斜线加“#”(\#)来实现(对特殊字符“#”的转义),其表示将“#”作为一字符而不是注释的开始标志。
备注:以tab开头的行是以shell脚本执行。
makefile文件名查找顺序 :“GNUmakefile”、“makefile”、“Makefile”。 当makefile文件的命名不是这三个任何一个时,需要通过make的“-f”或者“--file”选项来指定make读取的makefile文件.
include 作用:在一个MakefileA中包含其它的makefileB文件,这样就可以使用在
MakefileA中就可以使用makefileB中的变量和规则 include 指示符告诉make暂停读取当前的Makefile,而转去读取“include”指定的一个或者多个文件,完成以后再继续当前Makefile的读取格式:include foo
a.mk b.mk c.mk 适用场合:
1.
有多个不同的程序,由不同目录下的几个独立的Makefile来描述其重建规则。它们需要使用一组通用的变量定义或者模式规则。通用的做法是将这些共同使用的变量或者模式规则定义在一个文件中(没有具体的文件命名限制),在需要使用的Makefile中使用指示符“include”来包含此文件。2.
当根据源文件自动产生依赖文件时;我们可以将自动产生的依赖关系保存在另外一个文件中,主Makefile使用指示符“include”包含这些文件。这样的做法比直接在主Makefile中追加依赖文件的方法要明智的多。其它版本的make已经使用这种方式来处理。注意-include
FILENAMES... 与
include
FILENAMES... 之间 的区别。 出现错误时候
退出与
继续的区别
条件分支宏“ifdef”、“ifeq”、“ifndef”和“ifneq” 条件分支的展开是“立即”的变量“MAKEFILES”主要用在“make”的递归调用过程中的的通信
注意:“MAKEFILES”定义的包含文件是否存在不会导致make错误
MAKEFILES ,include 解析执行之前make读取的文件名将会被自动依次追加到变量“MAKEFILE_LIST”的环境变量中。其他环境变量GNU make 还支持一些特殊变量。它们一般都是只读的。 如(
.VARIABLES 环境变量 makefile文件中所定义的所有全局变量列表)宏变量 :
$*
$@ 代表规则的目标$?
$< 代表规则中通过目录搜索得到的依赖文件列表的第一个依赖文件$^ 代表所有通过目录搜索(VPATH ;GPATH; vpath)得到的依赖文件的完整路径名
动态相关函数:
$$@
objects := $(patsubst
%.c,%.o,$(wildcard *.c)) 将目录列表中所有文件名的后缀.c替换为.o。这样我们就可以得到在当前目录可生成的.o文件列表foo :
$(objects) cc -o foo
$(objects)
规则:如:
foo.o[目标文件集合] : foo.c
defs.h [依赖文件集合] # module for twiddling the frobs
cc -c -g foo.c [命令 ; 此行需要以tab键开头]
格式: 目标集合:依赖集合
命令集合
规则重载(
对于“GUNmakefile”中没有此目标的规则 就会执行重载规则 ,如 执行 make 'ABCDEFG' 由于没有制定 ABCDEFG 规则 所以执行重载规则里面的命令)
%: force
@$(MAKE) -f
Makefile $@
force: ;
文件名通配符:
*
?
[...]
注意:主要用于文件名通配变量定义中使用的通配符不会被统配处理(只会当成字符串处理,不会展开)
目录搜索机制是通过
"VPATH”;“vpath”;"GPATH"指定的来指定规则中的依赖文件通过变量“VPATH”可以指定依赖文件的搜索路径,当规则的依赖文件在当前目录不存在时,
make会在此变量所指定的目录下去寻找这些依赖文件VPATH = src:../headers
选择性搜索(关键字vpath)它可以为不同类型的文件(由文件名区分)指定不同的搜索目录
vpath %.h ../headers 以上意思是
Makefile中需要的.h文件;如果不能在当前目录下找到,则到目录“../headers”下寻找;%.h”表示所有以“.h”结尾的文件
vpath %.c
foo
vpath %
blish
vpath %.c
bar表示对所有的.c文件,make依次查找目录:“foo”、blish”、“bar”
vpath %.c
foo:bar
vpath %
blish对于所有的.c文件make将依次查找目录:“foo”、“bar”、“blish”Makefile伪目标,强制目标,空目标,特殊目标,多目标,多规则目标
静态模式规则
静态模式规则对一个较大工程的管理非常有用。它可以对整个工程的同一类文件的重建规则进行一次定义,而实现对整个工程中此类文件指定相同的重建规则。可以用来描述整个工程中所有的.o文件的依赖规则和编译命令。通常的做法是将生成同一类目标的模式定义在一个make.rules的文件中。在工程各个模块的Makefile中包含此文件。格式:
TARGETS ...:
TARGET-PATTERN: PREREQ-PATTERNS ...
COMMANDS
例如:
files = foo.elc
bar.o lose.o
$(filter %.o,$(files)):
%.o: %.c
$(CC) -c $(CFLAGS)
$< -o $@
$(filter %.elc,$(files)):
%.elc: %.el
emacs -f
batch-byte-compile $<
它根据相应的.c文件来编译生成“foo.o”和“bar.o”文件: