1. makefile中变量的替换
1.1 变量值的普通替换
(1)使用指定字符(串)替换变量值中的后缀字符(串)
(2)语法格式: $(var:a=b) 或 ${var:a=b}
-
替换表达式中不能有任何的空格
-
make 中支持使用 ${} 对变量进行取值
# 变量的普通替换(替换后缀) src := a.cc b.cc c.cc obj := ${src:cc=o} test : @echo "obj => $(obj)"
输出结果:
obj => a.o b.o c.o
1.2 变量值的模式替换
(1)使用 % 保留变量值中的指定字符,替换其它字符,%可以替换任何字符串
(2)语法格式: $(var:a%b=x%y) 或 ${var:a%b=x%y}
-
替换表达式中不能有任何的空格
-
make 中支持使用 ${} 对变量进行取值
-
模式替换是整体匹配模式,如 a%b 能和 a123b 匹配,但是不能和 sa123b 匹配
# 变量的模式替换 src := a1b.c a2b.c a3b.c obj := ${src:a%b.c=x%y} test : @echo "obj => $(obj)"
输出结果:
obj => x1y x2y x3y
1.3 规则中的模式替换
(1)语法格式
targets : target-pattern : prereq-pattern
command1
command2
...
(2)语法含义:通过 target-pattern 从 targets 中匹配子目标;再通过 prereq-pattern 从子目标生成依赖;进而构成完整的规则。
(3)规则中使用模式替换的意义
① 在大型的工程中 .o 文件的数量很多,按照一般的写法 makefile 会非常繁琐,而使用模式替换可以自动生成众多 .o 文件需要的规则。
② 在工程中要增添或者删减文件,只需要在 OBJS 变量中增添或删减即可,非常方便。如果采用一般的写法,要增添或删减规则,很繁琐。
(4)编程实验
main.c
extern void foo(); int main() { foo(); return 0; }
func.c
#include "stdio.h" extern char* g_hello; void foo() { printf("void foo() : %s ", g_hello); }
const.c
const char* g_hello = "hello makefile";
makefile
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)
运行结果:
2. 变量值的嵌套引用
(1)一个变量名之中可以包含对其它变量的引用
(2)嵌套引用的本质是使用一个变量表示另外一个变量
注意: x := y 这里的 y 是字符(字符串) 而 y := z 中的 y 表示的是变量,这两者是两个东东。
3. 命令行变量
(1)运行 make 时,在命令行定义变量
(2)命令行变量默认覆盖 makefile 中定义的变量
(3)在实际工程中,通过命令行变量临时改变变量的值,得到特殊的可执行程序(一般测试使用)
编程实验:
1 # 例1:make 中的命令行变量 2 3 test : 4 echo "hm => $(line)" 5 6 # 执行 make hm=swj 7 # 输出 hm => swj 8 9 # 例2:make中的命令行变量 10 11 hm := hello makefile 12 13 test : 14 echo "hm => $(hm)" 15 16 # 执行 make hm=cmd 17 # 输出 hm => cmd ,覆盖了makefile中原本定义的 hm 变量
4. override 关键字
(1)用于指示 makefile 中定义的变量不能被覆盖
(2)变量的定义和赋值都需要使用 override 关键字
编程实验:
1 # 测试override关键字用法 2 3 override var := test 4 5 test : 6 @echo "var => $(var)" 7 8 # 执行 make var=cmd 9 # 输出 var => test 变量没有被命令行变量所覆盖
5. define 关键字
(1)用于在 makefile 中定义多行变量
(2)多行变量的定义从变量名开始到 endef 结束
(3)可使用 override 关键字防止变量被覆盖
(4)define 定义的变量等价于使用 = 定义的变量(define 赋值的方式是递归赋值)
编程实验: 变量的特殊用法 makefile.3
hm := hello makefile override var := override-test define foo I'm fool! endef override define cmd @echo "run cmd ls ..." @ls endef test : @echo "hm => $(hm)" @echo "var => $(var)" @echo "foo => $(foo)" ${cmd}
运行结果:
6. 小结
(1)变量值的普通替换: $(var:a=b) 或 ${var:a=b}
(2)变量值的模式替换: $(var:a%b=x%y) 或 ${var:a%b=x%y}
(3)makefile支持将模式替换可以直接用于规则中
(4)规则中的模式替换:
targets : target-pattern : prereq-pattern
command1
command2
...
(5)makefile中的变量值能否嵌套应用
(6)命令行中定义的变量能否覆盖makefile中定义的变量
(7)override用于指示makefile中定义的变量不能被覆盖
(8)define用于在makefile中定义值为多行的变量