---- 整理自狄泰软件唐佐林老师课程
文章目录
- 1. 变量值的替换
- 2. 变量的模式替换
- 3. 规则中的模式替换
- 4. 变量值的嵌套使用
- 5. 命令行变量
- 6. 环境变量
- 7. 目标变量(局部变量)
- 8. 模式变量
- 9. 工程
1. 变量值的替换
- 使用指定字符(串)替换变量值中的后缀字符(串)
- 语法格式:
$(var:a=b)
或${var:a=b}
,即:使用 b 替换变量 var 的后缀 a- 替换表达式中不能有任何的空格
- make 中支持使用
${}
对变量进行取值
src := a.cc b.cc c.cc
obj := $(src:cc=o)
test:
@echo "obj => $(obj)"
2. 变量的模式替换
- 使用 % 保留变量值中的指定字符串,替换其它字符。% 可以理解为 Makefile 中的通配符
- 语法格式:
$(var:a%b=x%y)
或${var:a%b=x%y}
- 替换表达式中不能有任何空格
- make 中支持使用
${}
对变量进行取值
src := a1b.c a2b.c a3b.c
obj := $(src:a%b.c=x%y)
test:
@echo "obj => $(obj)"
3. 规则中的模式替换
- %.o 在 OBJS 中匹配子目标,首先找到 func.o
- 再根据 func.o 找个子目标生成依赖 func.c,构成整个规则 func.o: func.c
- 继续 1 和 2,匹配其它子目标
.PHONY : clean rebuild all
target := hello.out
CC := gcc
obj : main.o func.o
#使用模式规则替换,避免每一条.c都要写一个编译命令
$(obj) : %o : %c
$(CC) -o $@ -c $^
$(target) : main.o func.o
$(CC) -o $@ $^
all : $(target)
rebuild : clean all
clean :
rm -f *.o $(target)
4. 变量值的嵌套使用
- 一个变量名之中可以包含对其它变量的引用
- 嵌套引用的本质是使用一个变量表示另外一个变量
x := y
y := z
val := $($(x))
all:
@echo "val => $(val)"
5. 命令行变量
- 运行 make 时,在命令行定义变量
- 命令行变量默认覆盖 makefile 中定义的变量
hm := hello makefile
test:
@echo "hm => $(hm)"
- override 关键字
- 使用 override 关键字可以防止 makefile 中定义的变量被命令行变量覆盖
- override 用于指示 makefile 中定义的变量不能被覆盖
- 变量的定义和赋值都需要使用 override 关键字
- define 关键字
- 用于在 makefile 中定义多行变量
- 多行变量的定义从变量名开始到 endef 结束
- 可使用 override 关键字防止变量被覆盖
- define 定义的变量等价于使用 = 定义的变量
define fool
I'm fool!
endef
override define cmd
@echo "run cmd here"
endef
test:
@echo "fool => $(fool)"
$(cmd)
6. 环境变量
- makefile 中能够直接使用环境变量的值
- makefile 中定义与环境变量同名的变量,环境变量会被覆盖
- 运行 make 时指定
-e
选项,优先使用环境变量
- 变量在不同 makefile 之间的传递
- 直接在外部定义环境变量进行传递(不推荐,因为依赖于系统,导致 makefile 的移植性问题)
- 使用 export 定义变量进行传递(定义临时环境变量)
- 定义 make 命令行变量进行传递(推荐做法)
HOME := new_home
test:
@echo "$(HOME)"
由 make 结果可知,系统中的环境变量 HOME 的内容 /home/wx
,在 makefile 中被改为了 new_home
。
# Makefile
HOME := new_home
var := uuxiang
test:
@echo "HOME => $(HOME)"
@echo "var => $(var)"
@echo "make Makefile.2"
@$(MAKE) -f Makefile.2
# Makefile.2
test:
@echo "HOME => $(HOME)"
@echo "var => $(var)"
make 时,HOME 被临时改写为了 new_home,因此,这个值被传递到 Makefile.2 中,而 var 的作用域只在 Makefile 中,取法传递到 Make file.2 中,因此,输出为空。
如果想要将 var 也传递到 Makefile.2 中,可以使用 export 关键字。
# Makefile
HOME := new_home
export var := uuxiang
new := hello
test:
@echo "HOME => $(HOME)"
@echo "var => $(var)"
@echo "make Makefile.2"
@$(MAKE) -f Makefile.2
@$(MAKE) -f Makefile.2 new:=$(new)
# Makefile.2
test:
@echo "HOME => $(HOME)"
@echo "var => $(var)"
@echo "new => $(new)"
export 关键字修饰 var 变量,使其成为临时环境变量,这样就可以传递到 Makefile.2 中了。
7. 目标变量(局部变量)
- 作用域只在指定目标及连带规则中
var := hello
test: var := test-var
test: another
@echo "test:"
@echo "var => $(var)"
another:
@echo "another:"
@echo "var => $(var)"
test: var := test-var
,即定义了目标变量 var,此时这个变量的值 test-var 的作用域在 test 目标及其连带规则中,而在其它地方,var 变量的值仍然为 hello,这个变量值的作用域为整个文件。
var := hello
test: var := test-var
test:
@echo "test:"
@echo "var => $(var)"
another:
@echo "another:"
@echo "var => $(var)"
8. 模式变量
- 模式变量时目标变量的扩展
- 作用域只在符合模式的目标及连带规则中
var := hello
test: var := test-var
new := uuxiang
%e: override new := test-new
test:
@echo "test:"
@echo "var => $(var)"
@echo "new => $(new)"
rule:
@echo "rule:"
@echo "var => $(var)"
@echo "new => $(new)"
rule 目标对应的规则符合 %e 模式,因此,rule 规则中的 new 输出为 test-new 为模式变量。
9. 工程
【06-07 变量的高级主题】