1.5.2 变量的定义与赋值
赋值符号 ------------------------------------> 含义
:= 简单展开型,在makefile解析时,就立刻展开赋值
= 递归展开型,只有在变量调用的时候才展开赋值
?= 条件赋值型,只有当变量还没有值时才赋值
+= 附加赋值
Make解释器执行脚本过程:
1:Make解析器加载脚本以及脚本中include的其他脚本,加载完毕之后,解释器中会绘制一张关系图描绘各makefile脚本的关系。
2:根据用户指定的target,找出该target的全部依赖关系,并判断依赖关系中的时间戳,假如时间戳更新则执行命令。
赋值过程也叫展开过程,解释器会根据不同的赋值方式选择是立刻赋值还是延迟赋值,立刻赋值是在脚本加载时就赋值,延迟赋值是在运行时,用到变量才赋值。
定义 展开a 展开b
a:=b 立刻 立刻
a?=b 立刻 延迟
a=b 立刻 延迟
a+=b 立刻 出现在target后面时延迟赋值,一般情况下立刻赋值
define a
b....
b...
endef 立刻 延迟
1.5.3 条件控制语句
条件控制语句分为两种,一种是类似C语言的ifdef,加载时控制,另一种是类似函数控制流程,在脚本运行时控制。
语法模版
if-condition
text (如果条件为true)
endif
或者
if-condition
text(如果条件为true)
else
text(如果条件为false)
endif
conditon只能判断值是否相等或表达式是否被定义。
ifdef/ifndef var var变量被定义/没有定义
ifeq/ifneq test test表达式(可以为“a” “b” 或者a,b)相等/不等
1.5.4 (宏)函数定义
Make脚本中函数分为3类:
1:内置函数,任何脚本可直接调用,调用格式
$(fname,param...)
fname 是函数名 param是参数多个参数用,隔开
2:用户定义带参数的函数,用define关键字 定义调用格式
$(call fname,param...)
call关键字 fname 函数名 param参数
3:用户定义不带参数的函数
$(fname)
用户定义函数格式如下
define fname
具体命令
endef
函数内部,通过调用$(n)代表调用函数时的参数,$(0)代表函数本身,$(n)代表第几个参数。
自定义函数使用举例:
define showFirstName
echo $(1)
endef
调用:
.PHONY: name
name:
$(call showFirstName,cyc,ccy)
执行
make name
cyc
1.5.5 内置符号和变量
1.5.6 模板目标(pattern target)
例:OBJ=f1.o f2.o main.o
.PHONY: test
test:
gcc $(OBJ) -o main.bin
%.o: %.c
gcc -c -o $@ $<
%.o就是模板目标,%就是模版通配符,意思是所有的.o文件。$@代表目标名称,$<代表第一个先决条件
1.5.7 目标特定的变量赋值(target-special variable)
在脚本中给某个变量赋值之后无论编译哪个目标该变量的值总是相同的,
有时候希望在编译某个特定目标时候希望给变量重新赋值,且该赋值只在编译特定目标时有效,这就叫目标特定的变量赋值。
例:
tar2 : CFLAGS =
tar2 :
gcc $(CFLAGS) main.o
有时候用户又希望强制使用命令行中变量的赋值,而不使用目标特定的变量赋值。在调用命令时使用-e选项
例: make tar2 -e CFLAGS="-c -g"
有些目标又必须使用特定目标的赋值,就算使用-e选项也无法改变,可以在赋值前加上override关键字
例:
tar2 :override CFLAGS =
tar2 :
gcc $(CFLAGS) main.o
1.5.8 常用选项
调用make命令时可以加一些选项,已进行不同的操作,
-e 强制使用make命令中变量的赋值
-t 仅仅更新文件的时间戳而不执行target命令
-c 指定makefile执行的路径,默认情况下是在当前路径
-f 指定要执行的makefile的名词,默认情况下是Makefile或者Makefile.mk
-n 仅仅打印要执行的命令而不真正执行目标对应的命令。
-l 指定编译时所需的lib文件。