文章目录
- 前言
- 一、变量值的替换
- 1.简单替换
- 2.模式替换
- 1.变量的模式替换
- 2.规则中的模式替换
- 二、变量值的嵌套
- 三、命令行变量
- 四、define和override
- 五.环境变量
- 六.局部变量
- 七.模式变量
- 总结
前言
本篇文章将给大家讲解一下变量的高级主题,变量的拓展,这些主题可以让你更加灵活地编写和维护 Makefile。
一、变量值的替换
1.简单替换
变量替换语法格式:
$(var:a=b)
其中,a 可以是一个字母,表示 var 中每个单词结尾的这个字母。b 则是替换的字符串。它会替换每个单词结尾的 a(如果有的话)。
这个语法通常用于修改一些表示文件路径或文件名的变量,以方便进行操作。
这里给出一个例子:
src := a.bc b.bc c.bc
obj := $(src:bc=oo)
test:
@echo "src=>$(src)"
@echo "obj=>$(obj)"
运行结果:
2.模式替换
1.变量的模式替换
在变量中使用模式替换就是将%前面和后面的换成我们想要替换的值。
src2 := a11b.c a22b.c a33b.c
src3 := $(src2:a%b.c=x%y)
test :
@echo "src3=>$(src3)"
运行结果:
2.规则中的模式替换
在工程开发中会有很多个需要被编译的文件,那么我们肯定不会和之前一样一个目标对应一个依赖,这样写是非常低效的,当要修改时也是非常困难的,所以在这里我们采取模式替换的方式来编写。
CC := gcc
TARGET := hello
OBJS := hello.o func.o
TARGET : $(OBJS)
$(CC) -o $@ $^
$(OBJS) : %.o : %.c
$(CC) -c -o $@ $<
.PHONY: clean rebuild all
rebuild : clean all
all : TARGET
clean :
$(RM) *.o TARGET
二、变量值的嵌套
在Makefile中,变量可以嵌套使用,以方便进行更加复杂的操作。嵌套变量的语法格式如下:
$(first_var$(second_var))
其中,first_var和second_var都是变量名。Make会首先展开$(second_var),以获取second_var的值,然后再将其插入到$(first_var)中,以展开为最终的变量值。
下面举一个例子:
x := y
y := z
a := $($(x))
test3 :
@echo "x=>$(x)"
@echo "y=>$(y)"
@echo "a=>$(a)"
运行结果:
三、命令行变量
在Makefile中,命令行变量指的是通过make命令行传递给Makefile的参数。这些参数可以用于控制Makefile执行过程中的一些行为,例如指定编译器、调试选项等等。命令行变量的定义方式如下:
make <variable>=<value>
其中,variable 是命令行变量的名称,value是其值。在Makefile中,可以使用$(variable)来引用这个命令行变量的值。
这里举一个例子说明一下:
test := hello makefile
all :
@echo $(test)
运行结果:
四、define和override
在 Makefile 中,define 和 override 是两种比较重要的关键字。
define 关键字用来定义一个多行字符串,它的语法格式如下:
define <variable_name>
<string>
endef
其中,<variable_name> 是定义的变量名,<string> 是这个变量名所对应的字符串,endef 表示字符串定义的结束标志符。事实上,define 定义的是一个多行的文本字符串,可以是命令、参数或者其他内容。定义后,这个变量就可以在 Makefile 的其他地方使用。
举个例子,你可以这样定义一个变量:
define MY_VARIABLE
echo "hello world"
endef
然后在 Makefile 的其他地方,使用 $(MY_VARIABLE) 得到 “hello world” 的输出。
输出结果:
override关键字用于指示makefile中定义的变量不能被覆盖。
我们尝试着使用命令行来替换这个override 定义的变量:
define MY_VARIABLE
"hello world"
endef
override var := hello
all :
@echo $(MY_VARIABLE)
@echo $(var)
运行结果:
这里可以发现使用override定义的变量无法被命令行参数覆盖。
五.环境变量
在 Makefile 中,可以使用环境变量来传递参数或设置选项。环境变量是一种全局变量,对于整个 shell 都是可见的。Makefile 中可以访问这些环境变量,并在其中读取或设置值。
1.CFLAGS:编译选项的环境变量,可以用来设置编译器选项,例如 -Wall 和 -O2 等。
2.LDFLAGS:链接选项的环境变量,可以用来设置链接器选项,例如 -L 和 -l 等。
3.CC:编译器的环境变量,可以用来指定使用的编译器。例如 CC=gcc 表示使用 gcc 编译器。
使用export定义环境变量
一次定义一个变量和它的值:
export VARIABLE=value
示例代码:
test:
@echo "var => $(var)"
定义环境变量:
运行结果:
这里定义的环境变量不仅可以在这个makefile当中使用也可以在其他的makefile中使用。
环境变量也能够被命令行变量覆盖:
使用-e选项可以优先使用环境变量:
var := abc
test :
@echo "var =>$(var)"
使用make -e选项运行结果:
六.局部变量
在 Makefile 中,可以使用局部变量(也称为自动化变量),用于临时存储一些值,例如命令行参数、编译器选项和源文件列表等。和全局变量不同,局部变量只在当前的规则中有效。
test : test1
test : var1:=test-var1
test : test1
@echo "var1=>$(var1)"
test1 :
@echo "var1=>$(var1)"
test2 :
@echo "var1=>$(var1)"
运行效果:
从结果可以看出局部变量只在指定目标和连带规则中有效。
七.模式变量
模式变量则是一种构建在模式规则之上的变量类型,它可以让我们更方便地定义和管理模式规则的组合。
var := D.T.Software
new := TDelphi
%e : override new:= test-new
test : rule
@echo "var => $(var)"
@echo "new => $(new)"
rule :
@echo "var => $(var)"
@echo "new => $(new)"
运行结果:
从结果中可以看出模式变量作用域只在符合模式的目标及连带规则中。
总结
本篇文章知识点较多,这些内容也是makefile中比较重要的一些内容大家看完后要多加练习。