1.变量和不同的赋值方式
(1)makefile中支持程序设计语言中变量的概念
(2)makefile中的变量只代表文本数据(字符串)
(3)makefile中的变量名规则
变量名可以包含字符,数字,下划线
不能包含“:”,"#","=“或” "
变量名大小写敏感
(4)变量的定义和使用
cc:=gcc
TARGET:=hello.out //变量定义$(TARGET):func.o main.o$(cc) -o $(TARGET) func.o main.o //变量使用
(5)makefile中变量的赋值方式
简单赋值(:=)
递归赋值(=)
条件赋值(?=)
追加赋值(+=)
简单赋值(:=):
程序设计语言中的通用的赋值方式
只针对当前语句的变量有效
x := foo
y := $(x)b
x := new.PHONY : test
test:@echo "x => $(x)" //x=> new@echo "y => $(y)" //y=> foob
递归赋值(=):
赋值操作可能影响多个其他变量
所有与目标变量相关的其他变量都将受到影响
x = foo
y = $(x)b
x = new.PHONY : test
test:@echo "x => $(x)" //x=> new@echo "y => $(y)" //y=> newb
条件变量(?=):
如果变量未定义,使用赋值符号中的值定义变量
如果变量已经定义,赋值无效
x := foo
y := $(x)b
x ?= new.PHONY : test
test:@echo "x => $(x)" //x=> new@echo "y => $(y)" //y=> foob
追加赋值(+=):
原变量值之后加上一个新值
原变量值与新值之间由空格隔开
x := foo
y := $(x)b
x += $(y).PHONY : test
test:@echo "x => $(x)" //x=> foo foob@echo "y => $(y)" //y=> foob
2.预定义变量的使用
(1)在makefile中存在一些预定义的变量
自动变量:
@ , @, @,^,$<
特殊变量
$(MAKE) , $(MAKECMDGOALS) , $(MAKEFILE_LIST)
$(MAKE_VERSION) , $(CURDIR) , $(.VARIABLES)
自动变量的意义:
$@:当前规则中触发命令被执行的目标
$^:当前规则中的所有依赖
$<:当前规则中的第一个依赖
all : first second third@echo "\$$@ => $@"@echo "$$^ => $^"@echo "$$< => $<"
注意:
1." " 对 于 m a k e f i l e 有 特 殊 意 义 输 出 时 需 要 加 上 一 个 " "对于makefile有特殊意义 输出时需要加上一个" "对于makefile有特殊意义输出时需要加上一个"“进行转义
2.”$@“对于Bash Shell有特殊含义
输出时需要加上”"进行转义
特殊变量的含义:
$(MAKE):当前make解释器的文件名
$(MAKECMDGOALS):命令行中指定的目标名(make的命令行参数)
$(MAKEFILE_LIST):
make所需处理的makefile文件列表
当前makefile的文件名总是位于列表的最后
文件名之间以空格进行分隔
$(MAKE_VERSION):当前make解释器的版本
$(CURDIR):当前make解释器的工作目录
$(.VARIABLES):所有已经定义的变量名列表(预定义变量和自定义变量)
小结:
makefile提供了预定义变量供开发者使用
预定义变量的使用能够使得makefile的开发更高效
自动变量是makefile中最常见的元素
使用$(.VARIABLES)能够获取所有的特殊变量
3.变量的高级主题
(1)变量值的替换
使用指定字符(串)替换变量值中的后缀字符(串)
语法格式: ( v a r : a = b ) 或 (var:a=b)或 (var:a=b)或{vat:a=b}
替换表达式中不能有任何的空格
make中支持使用${}对变量进行取值
src := a.cc b.cc c.cc
obj := $(src:cc=o)
test:@eccho "obj => $(obj)"
(2)变量的模式替换
使用%保留变量值中的指定字符,替换其他字符
语法格式: ( v a r : a (var:a%b=x%y)或 (var:a{var:a%b=x%y}
替换表达式中不能有任何的空格
make中支持使用${}对变量进行取值
src := a1b.c a2b.c a3b.c
obj := $(src:a%b.c=x%y)
test:@eccho "obj => $(obj)"
(3)规则中的模式替换
targets : target-pattern : preerq-pattern
command1
command2
…
意义:通过target-parttern从targets中匹配字目标;再通过prereq-pattern从字目标生成依赖;进而构成完整的规则。
(4)变量值的嵌套引用
一个变量名之中可以包含对其它变量的引用
套嵌引用的本质是使用一个变量表示另外一个变量
x := y
y := z
z := $($(x))a := $(y) a := z
命令行变量:
运行make时,在命令行定义变量
命令行变量默认覆盖makefile中定义的变量
hm := hello makefile
test:@echo "hm => $(hm)"make hm=cmd hm => cmd
(5)override关键字
用于指示makefile中定义的变量不能被覆盖
变量的定义和赋值都需要使用override关键字
override hm := hello makefile
test:@echo "hm => $(hm)"make hm=cmd hm => hello makefile
(6)define关键字
用于在makefile中定义多行变量
多行变量的定义从变量名开始到 endef 结束
可使用 override 关键字防止变量被覆盖
define定义的变量等价于使用 = 定义的变量
define foo
I am fool!
endefoverride define cmd@echo "run cmd is ..."@ls
endef
(7)环境变量(全局变量)
makefile中能够直接使用环境变量的值
定义了同名变量,环境变量将被覆盖
运行make时指定 “e” 选项,优先使用环境变量
为什么要在makefile中使用环境变量?
优势:环境变量可以在所有makefile中使用
劣势:过多的依赖于环境变量会导致移植性降低
变量在不同makefile之间的传递方式
直接在外部定义环境变量进行传递
使用export定义变量进行传递(定义临时环境变量)
定义make命令行变量进行传递(推荐)
(8)目标变量(局部变量)
作用域只在指定目标及连带规则中
target : name value
target : override name calue
var := CKY
test : var := test_var //作用域只在指定目标及连带规则中,test是目标
test:@echo "test:"@echo "var => $(var)"
模式变量:
模式变量是目标变量的扩展
作用域只在符合模式的目标及连带规则中
pattern : name value
pattern : override name value
new := CKY
%e : override new := test_new //%e,通配符,以e结尾的目标
rule:@echo "rule:"@echo "new => $(new)"
小结:
makefile中的三种变量:
(1)全局变量:makefile外部定义的环境变量
(2)文件变量:makefile中定义的变量
(3)局部变量:指定目标的变量