makefile
makefile 的执行步骤
- 读入所有的 Makefile;
- 读入被 include 的其它 Makefile;
- 初始化文件中的变量;
- 推导隐晦规则,并分析所有规则;
- 为所有的目标文件创建依赖关系链;
- 根据依赖关系,决定哪些目标要重新生成;
- 执行生成命令;
文件搜索路径
目标文件和依赖文件
执行 make 命令时,要寻找目标文件和依赖文件的路径;
-
设置全局访问路径 VAPTH
通过变量 VPATH 指定依赖文件的搜索路径。在规则的依赖文件在当前目录不存在时,make 会在此变量所指定的目录下去寻找这些依赖文件。变量 VPATH 的定义中,使用空格或者冒号(:)将多个目录分开。make 搜索的目录顺序按照变量 VPATH 定义中顺序进行(当前目录永远是第一搜索目录)。
源文件所要包含的头文件等相关文件的路径;
函数
调用语法
函数调用,很像变量的使用,也是以 $ 来标识的,其语法如下:
$(<function> <arguments>)
# 或者
${<function> <arguments>}
<function>
就是函数名。 <arguments>
为函数的参数,参数间以逗号 “,” 分隔。函数名和参数之间以“空格”分隔。函数调用以 “$” 开头,以圆括号或花括号把函数名和参数括起。函数中的参数可以使用变量,为了风格的统一,函数和变量的括号最好一样。如下所示:
$(subst a,b,$(x)) #推荐使用
$(subst a,b,${x})
示例:
comma:= ,
empty:=
space:= $(empty) $(empty)
foo:= a b c
bar:= $(subst $(space),$(comma),$(foo))
$(comma)
的值是一个逗号。 $(space)
使用了 $(empty)
定义了一个空格, $(foo)
的值是 “a b c”, $(bar)
的定义用,调用了函数 subst
, 这是一个替换函数,这个函数有三个参数,第一个参数是被替换字串,第二个参数是替换字串,第三个参数 是替换操作作用的字串。这个函数也就是把 $(foo)
中的空格替换成逗号,所以 $(bar)
的值 是 “a,b,c”。
addsuffix
$(addsuffix suffix, names… )
-
名称:添加后缀
-
功能:在每个
names
后添加后缀suffix
。多个names
用空格分开。 -
返回:返回连接后的字符串,以空格分开。
-
示例:
$(addsuffix .c,foo bar) # result # src/foo src/bar
patsubst
$(patsubst <pattern>,<replacement>,<text>)
-
名称:模式字符串替换
-
功能:查找
<text>
中的单词(单词以“空格”、“Tab”或“回车”“换行”分隔)是否符合模式<pattern>
,如果匹配的话,则以<replacement>
替换。这里,<pattern>
可以包括通配符 “%” ,表示任意长度的字串。如果<replacement>
中也包含 “%” ,那么,<replacement>
中的这个 “%” 将是<pattern>
中的那个 “%” 所代表的字串。 (可以用 “" 来转义,以 “%” 来表示真实含义的 “%” 字符) -
返回:函数返回被替换过后的字符串。
-
示例:
$(patsubst %.c,%.o,x.c.c bar.c)
把字串 “x.c.c bar.c” 符合模式 “%.c” 的单词替换成 “%.o” ,返回结果是 “x.c.o bar.o”。
$(var:<pattern>=<replacement>;) #相当于 $(patsubst <pattern>,<replacement>,$(var)) $(var: <suffix>=<replacement>) #相当于 $(patsubst %<suffix>,%<replacement>,$(var))
例如有:
objects = foo.o bar.o baz.o, $(objects:.o=.c) # 等于 $(patsubst %.o,%.c,$(objects))
foreach
$(foreach <var>,<list>,<text>)
-
功能:把参数
<list>
中的单词逐一取出放到参数<var>
所指定的变量中, 然后再执行<text>
所包含的表达式。每一次<text>
会返回一个字符串,循环过程中,<text>
的所返回的每个字符串会以空格分隔,最后当整个循环结束时,<text>
所返回的每个字符串所组成的整个字符串(以空格分隔)将会是”foreach” 函数的返回值。所以,
<var>
最好是一个变量名,<list>
可以是一个表达式,而<text>
中一般会使用<var>
这个参数来依次枚举<list>
中的单词。 -
示例:
names := a b c d files := $(foreach n,$(names),$(n).o)
上面的例子中,
$(name)
中的单词会被挨个取出,并存到变量n
中,$(n).o
每次 根据$(n)
计算出一个值,这些值以空格分隔,最后作为 “foreach” 函数的返回,所以,$(files)
的值是 “a.o b.o c.o d.o”。注意,”foreach” 中的
<var>
参数是一个临时的局部变量,”foreach” 函数执行完后,参数<var>
的变量将不在作用,其作用域只在 “foreach” 函数当中。