6.变量的高级主题
变量的替换
变量值的替换
- 使用指定字符(串)替换变量值中的后缀字符(串)
- 语法格式:$(var:a=b) 或 ${var:a=b}
- 替换表达式中不能有任何的空格
- make中支持使用 ${} 对变量进行取值
变量的模式替换
- 使用%保留变量值中的指定支付,替换其他字符
- 语法格式:$(var:a%b=x%y) 或 ${ var:a%b=x%y }
- 替换表达式中不能有任何空格
- make中支持使用 ${} 对变量进行取值
规则中的模式替换
targets : target-pattern : prereq-pattern
command1
command2
…
意义:通过target-pattern 从targets中匹配子目标;再通过prereq-pattern从字母表生成依赖;进而构成完整的规则。
示例代码:变量的替换
.PHONY : test1 test2
src := a.c b.c c.c
obj := $(src:c=o)
src2 := a12b.c aousb.c a3b.c
obj2 := ${src2:a%b.c=x%y.c}
test1 :
@echo $(obj)
test2 :
@echo $(obj2)
输出结果:
C:\exercise\makefile>make
a.o b.o c.o
C:\exercise\makefile>make test2
x12y.c xousy.c x3y.c
分析:
- 在变量的模式替换中,通配符%,所代表的不仅是一个字符,而是一个字符串。
示例代码:规则中的模式替换
CC := g++
TARGET := hello-makefile.out
OBJS := func.o main.o const.o
$(TARGET) : $(OBJS)
$(CC) -o $@ $^
$(OBJS) : %.o : %.c
$(CC) -o $@ -c $^
.PHONY : rebuild clean all
rebuild : clean all
all : $(TARGET)
clean :
$(RM) *.o $(TARGET)
分析:
$(OBJS) : %.o : %.c
$(CC) -o $@ -c $^
这条指令会变成 ->
func.o : func.c
$(CC) -o $@ -c $^
main.o : main.c
$(CC) -o $@ -c $^
const.o : const.c
$(CC) -o $@ -c $^
为什么要使用这么晦涩的写法。代码不是尽量写的让人看懂么?实际上,在工程中这么写是很有必要的。因为工程中有大量的源文件,这样写就可以直接一条语句搞定了。
变量值的嵌套引用
- 一个变量名之中可以包含对其他变量的引用
- 嵌套引用的本质是使用一个变量表示另外一个变量
命令行变量
- 运行make 时,在命令行定义变量
- 命令行变量默认覆盖makefile中定义的变量
见招拆招:有些时候我们需要放置误赋值。
override 关键字
- 用于指示makefile中定义的变量不能被覆盖
- 变量的定义和赋值都需要使用override关键之
define关键字
- 用于在makefile中定义多行变量
- 多行变量的定义从变量名开始到endef结束
- 可使用override关键字防止变量被覆盖
- define定义的变量等价于使用 = 定义的变量
示例代码:变量的特殊用法
hm := hello makefile
override var := override-test
define foo
I'm fool!
endef
override define cmd
@echo "run cmd ls ..."
@dir
endef
test :
@echo "hm => $(hm)"
@echo "var => $(var)"
@echo "foo => $(foo)"
${cmd}
输出结果:
C:\exercise\makefile>make hm:=Hello,Make! var:= test
“hm => Hello,Make!”
“var => override-test”
"foo => I’m fool! "
“run cmd ls …”
驱动器 C 中的卷是 Windows
卷的序列号是 5873-F506
C:\exercise\makefile 的目录
2017/05/04 15:55
2017/05/04 15:55
2017/05/11 10:12 240 makefile
1 个文件 240 字节
2 个目录 60,497,719,296 可用字节