本文主要参考 GNU make中文手册 做一些简单的摘抄总结,原文参见 http://www.yayu.org/book/gnu_make/
第二章:GNU make 介绍
2.5指定变量
“objects”作为一个变量,它代表所有的.o文件的列表。在定义了此变量后,我们就可以在需要使用这些.o文件列表的地方使用“$(objects)”来表示它,而不需要罗列所有的.o文件列表。
2.6自动推导原则:
在使用make编译.c源文件时,可以省略编译一个.c文件所使用的命令,即构建规则。另外可以省略依赖规则中的相应源文件。
2.8清除工作目录过程文件
clean :
rm edit $(objects)
在实际应用时,我们会把这个规则写成如下稍微复杂一些的样子。以防止出现始料未及的情况。
.PHONY : clean
clean :
-rm edit $(objects)
第三章: makefile 总述
3.1 makefile的内容
如果此行的第一个非空字符为“#”,那么此行为注释行。注释行的结尾如果存在反斜线(\),那么下一行也被作为注释行。当在Makefile中需要使用字符“#”时,可以使用反斜线加“#”(\#)来实现
变量以及功能的定义将在引用的地方自动展开,类似宏。例如:
0 define all-cpp-files-under
1 $(patsubst ./%,%, \
2 $(shell cd $(LOCAL_PATH) ; \
3 find $(1) -name "*.cpp" -and -not -name ".*") \
4 )
5 endef
1 #LOCAL_OPPO_SRC_FILES := $(call all-cpp-files-under, ../oppo)
3.2 makefile文件的命名
注释:通过命令指定目标使用make的隐含规则:
当前目录下不存在以“GNUmakefile”、“makefile”、“Makefile”命名的任何文件,
1. 当前目录下存在一个源文件foo.c的,我们可以使用“make foo.o”来使用make的隐含规则自动生成foo.o。当执行“make foo.o”时。我们可以看到其执行的命令为:
cc –c –o foo.o foo.c
之后,foo.o将会被创建或者更新。
2. 如果当前目录下没有foo.c文件时,就是make对.o文件目标的隐含规则中依赖文件不存在。如果使用命令“make foo.o”时,将回到到如下提示:
make: *** No rule to make target ‘foo.o’. Stop.
3. 如果直接使用命令“make”时,得到的提示信息如下:
make: *** No targets specified and no makefile found. Stop.
3.3 包含其他makefile
如果一行以[Tab]字符开始make程序将此行作为一个命令行来处理,一般情况使用空格来代替
使 “include FILENAMES...”,make程序处理时,如果“FILENAMES”列表中的任何一个文件不能正常读取而且不存在一个创建此文件的规则时make程序将会提示错误并退出。
使用 “-include FILENAMES...”的情况是,当所包含的文件不存在或者不存在一个规则去创建它,make程序会继续执行,只有在因为makefile的目标的规则不存在时,才会提示致命错误并退出。
疑问:include文件中的变量定义,以及包含的静态库,是否会传导如其他文件中,待Qcom camera hal进行测试验证?3.4变量MAKEFILES
系统包含的环境变量,不能用作编译目标
3.5变量MAKEFILE_LIST
系统读取的所有makefile文件名,最后一个附带到后面
3.6VARIABLES变量
此引用点之前makefile中所有的全局变量列表
3.8 重载另外一个makefile
#sample GNUmakefile
foo:
frobnicate > foo
%: force
@$(MAKE) -f Makefile $@
force: ;
首先尝试在GNUmakefile中寻找规则,当无法找到规则时再在Makefile中寻找,避免直接include造成多处冲突。此方法有拦截作用
3.9Make如何解析makefile
GUN make的执行过程分为两个阶段。
第一阶段:读取所有的makefile文件(包括“MAKIFILES”变量指定的、指示符“include”指定的、以及命令行选项“-f(--file)”指定的makefile文件),内建所有的变量、明确规则和隐含规则,并建立所有目标和依赖之间的依赖关系结构链表。
在第二阶段:根据第一阶段已经建立的依赖关系结构链表决定哪些目标需要更新,并使用对应的规则来重建这些目标。
规则定义的符号不明白怎么描述的?
3.10总结
make的执行过程如下:
1. 依次读取变量“MAKEFILES”定义的makefile文件列表
2. 读取工作目录下的makefile文件(根据命名的查找顺序“GNUmakefile”,“makefile”,“Makefile”,首先找到那个就读取那个)
3. 依次读取工作目录makefile文件中使用指示符“include”包含的文件
4. 查找重建所有已读取的makefile文件的规则(如果存在一个目标是当前读取的某一个makefile文件,则执行此规则重建此makefile文件,完成以后从第一步开始重新执行)
5. 初始化变量值并展开那些需要立即展开的变量和函数并根据预设条件确定执行分支
6. 根据“终极目标”以及其他目标的依赖关系建立依赖关系链表
7. 执行除“终极目标”以外的所有的目标的规则(规则中如果依赖文件中任一个文件的时间戳比目标文件新,则使用规则所定义的命令重建目标文件)
8. 执行“终极目标”所在的规则
第四章: makefile 规则
4.2规则语法
规则的中心思想就是:目标文件的内容是由依赖文件文件决定,依赖文件的任何一处改动,将导致目前已经存在的目标文件的内容过期。规则的命令为重建目标提供了方法。这些命令运行在系统shell之上
4.3依赖的类型
我们需要对依赖进行分类,一类是这些依赖文件的更新需要对应更新目标文件,另一类是这些依赖的更新不会导致目标被重建。第二类的依赖我们就称他为:“order-only”依赖。在书写规则时,“order-only”依赖使用管道符号“|”开始,作为目标的一个依赖文件。规则的依赖列表中管道符号“|”左边的是常规依赖文件,所有出现在管道符号右边的就是“order-only”依赖。规则依赖文件中如果一个文件被同时声明为常规依赖和“order-only”依赖,那么此文件被作为常规依赖处理
4.4文件名使用通配符
Makefile中统配符可以出现在以下两种场合:
1. 可以用在规则的目标、依赖中,此时make会自动将其展开;
2. 可出现在规则的命令中,其展开是在shell在执行此命令时完成。
转移字符可以用\来引用变量定义中使用的通配符不会被展开
函数wildcard
4.5目录搜索
4.5.1一般性搜索
4.5.3目录搜索机制
当两个目录都不存在目标文件“libtest.a”时,目标将会在当前目录(“prom”目录)下创建。如果“src”目录下已经存在目标文件“libtest.a”。当其依赖文件任何一个被改变以后执行make,目标“libtest.a”将会被在“src”目录下被更新
4.5.4命令行和搜索目录
规则命令行中的自动化变量“$^”代表所有的是的通过目录搜索得到的依赖文件的完整路径名(目录+一般文件名)列表。“$@”代表规则的目标
自动化变量“$<”代表规则中通过目录搜索得到的依赖文件列表的第一个依赖文件
4.5.5隐含规则和搜索目录
4.6 makefile伪目标
伪目标也称为标签,使用伪目标有两点原因:1. 避免在我们的Makefile中定义的只执行命令的的目标(此目标的目的为了执行执行一些列命令,而不需要创建这个目标)和工作目录下的实际文件出现名字冲突。2. 提高执行make时的效率,特别是对于一个大型的工程来说,编译的效率也许你同样关心
.PHONY: clean
clean:
rm *.o temp
make内嵌隐含变量???
4.7强制目标(没有命令或依赖的规则)
clean: FORCE
rm $(objects)
FORCE:
force无命令和依赖,所以总被认为是最新的。所以规则命令总会执行在使用GNU make,尽量避免使用这种方式。在GNU make中我们推荐使用伪目标方式
4.8空目标文件
一个空目标文件应该存在一个或者多个依赖文件。将这个目标作为终极目标,在它所依赖的文件比它新时,此目标所在规则的命令行将被执行。就是说,如果空目标的依赖文件被改变之后,空目标所在规则中定义的命令会被执行.
print: foo.c bar.c
lpr -p $?
touch print
4.9 Makefile的特殊目标4.10多目标
仅需要一个描述依赖关系的规则,而不需要在规则中定义命令
对于多个具有类似重建命令的目标。重建这些目标的命令并不需要是绝对相同,因为我们可以在命令行中使用make的自动环变量“$@”来引用具体一个目标,并完成对它的重建
4.11多规则的目标
Makefile中,一个文件可以作为多个规则的目标出现。这种情况时,此目标文件的所有依赖文件将会被合并成此目标一个依赖文件列表,其中任何一个依赖文件比目标更新(比较目标文件和依赖文件的时间戳)时,make将会执行特定的命令来重建这个目标。
对于一个多规则的目标,重建此目标的命令只能出现在一个规则中(可以是多条命令)。如果多个规则同时给出重建此目标的命令,make将使用最后一个规则所以的命令
静态模式规则是这样一个规则:规则存在多个目标,并且不同的目标可以根据目标文件的名字来自动构造出依赖文件。静态模式规则比多目标规则更通用,它不需要多个目标具有相同的依赖。但是静态模式规则中的依赖文件必须是相类似的而不是完全相同的4.13双冒号规则