前言
一、变量替换:
1. 变量值的替换。
使用 指定的字符(串)
替换变量值中的后缀字符(串)
。
语法格式: $(var:a=b) 或 ${var:a=b} 。
- 替换表达式中不能有任何的空格。
- make 中支持使用 ${ } 对变量进行取值。
示例 :
src1 := a.c b.c c.c obj1 := $(src1:c=o) test: @echo "obj1 => $(obj1)"
2. 变量的模式替换。
使用 % 保留变量值中的指定字符
,替换其他字符。
语法格式: $(var:a%b=x%y) 或 ${var:a%b=x%y}
- 替换表达式中不能有任何空格。
- make 中支持 使用 $ { } 对变量进行取值。
示例 :
src1 := a1b.c a2b.c a3b.c obj1 := $(src1:a%b=x%y) test1: @echo "obj1 => $(obj1)" src2 := a11b.c a22b.c a33b.c obj2 := $(src2:a%b=x%y) test2: @echo "obj2 => $(obj2)"
3. 规则中的模式替换。
表示,target-pattern 从target 中匹配子目标;再通过 prereq-pattern 从子目标生成依赖; 进而构成完整的规则。
流程图:
示例 :
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) # $(RM):用于删除文件的命令
- 提问 : 为什莫使用 规则中的模式替换呢?
因为工程中我们的 .c .o 文件非常多。如果 想要将 .c 编译成 .o 文件时,
可以使用 这种替换方法。 直接将 文件 加在下面的 第一行后即可。
OBJS := func.o main.o const.o
$(OBJS) : %.o : %.c
$(CC) -o $@ -c $^
这样可以很快的完成编译,减少工作量。
二、变量的嵌套使用
一个变量名之 可以包含对其他变量的引用
。
嵌套引用的本质是使用一个变量表示另一个变量。
x := y y := z a := $($(x)) test : @echo " a => $(a)"
需要注意的是,在变量值的嵌套引用中,Makefile 的解析顺序是从内而外
的,即先解析内部的变量,再逐级向外解析外部的变量。
三、命令行变量
在 Makefile 中,可以使用命令行变量来传递参数给 Make 命令。
命令行变量可以在命令行中通过 “-变量名=变量值” 的方式定义,并在 Makefile 中使用 $(变量名) 的方式引用。
- 运行 make 时,
在命令行定义变量
。 - 命令行变量默认 覆盖 makefile 中定义的变量。
hm := hello test : @echo " hm => $(hm)" # 在命令行改变其值 @echo " new =>$(new)" # 打印未定义的变量,在命令行定义赋值
四、override ,define 关键字
- override 关键字:
- 用于指示 makefile 中
定义的变量不能被覆盖
。 - 变量的定义和赋值都需要使用 override 关键字。
override hm := hello test : @echo " hm => $(hm)" # 在命令行改变其值
- define 关键字:
- 用于在 makefile 中
定义多行变量
。 - 多行变量的定义
从变量名开始 到 endef结束
。 - 可使用 override 关键字防止变量被覆盖。
- define 定义的变量等价于使用 = 定义的变量。
define fool I'm fool! endef override define cmd # 使用 override 防止变量被覆盖 @echo "run cmd ls ..." @ls endef test : @echo "f00 => $(fool)" $(cmd) # 调用 cmd 变量
总结
下一篇 介绍 makefile 的全局变量,文件变量,局部变量。