makefile学习之实验楼

2.4.3 变量的分类与赋值

根据变量定义时所使用的赋值操作符的不同,可以将变量分成两种类型(或者说是两种风格):

递归展开式变量和直接展开式变量;

使用赋值操作符= 、 += 和 ?=定义的变量都是递归展开式变量,使用赋值操作符 :=定义的变量为直接展开式变量 。

两种变量类型的的最根本区别在于:变量值的求值时机,递归式变量的求值时机在于变量被引用时,直接展开式的求值时机在于变量被定义时。

我们来编写makefile 文件 /home/shiyanlou/Code/makefile_sample/variabletype.mk:

foo1 = $(bar) #递归展开式变量
foo2 := $(bar) #直接展开式变量
bar = $(ugh)
ugh = Huh?

all:
echo “foo1 is $(foo1), foo2 is $(foo2)”

然后,使用 $ make -f variabletype.mk 执行variabletype.mk,演示及结果如下:

1-2.4.3-1

由于变量foo1的变量值是在执行echo命令时才求的值,所以foo1的值被递归的展开为Huh?; 而变量foo2的变量值在定义时就被求值了,此时由于变量bar的值为空,因此foo2的值也为空。

注意:使用递归展开式的变量定义,可能会由于出现变量的递归定义而导致make陷入到无限的变量展开过程中,最终使make执行失败

+= 和 ?=是基于=扩展而来的两种变量赋值操作符;

+= 称为追加赋值操作符,它实现对于一个已经存在定义的变量进行追加赋值,如下例子:

bar = foo1   
bar += foo2  #追加赋值,bar的值将为 foo1 foo2

all:
    echo $(bar)

?=称为条件赋值的赋值操作符,被称为条件赋值为:只有此变量在之前没有赋值的情况下才会对这个变量进行赋值。看一下例子:

bar1 = foo1
bar1 ?= foo2  # bar1 的值还是foo1
bar2 ?= foo2  # bar2 的值为foo2

all:  
    echo "bar1 is $(bar1), bar2 is $(bar2)" 

2.4.4 特殊的变量

在makefile 中用户除了可以自定义变量外,还可以使用make工具为我们提供的一些特殊的变量及用法。

自动化变量

所谓自动化变量,就是在每条规则中,make自动为我们提供的用于指定规则各个组成部分的变量,一般情况下常用的有以下几个自动化变量:

$@ -- 代表规则中的目标文件名

$< -- 代表规则的第一个依赖的文件名

$^ -- 代表规则中所有依赖文件的列表,文件名用空格分割

看例子,编写makefile 文件 /home/shiyanlou/Code/makefile_sample/auto_var.mk:

all: first second third
echo “$$@ = @ &quot; e c h o &quot; @&quot; echo &quot; @"echo"$< = &lt; &quot; e c h o &quot; &lt;&quot; echo &quot; <"echo"$^ = $^”

first second third:

这里有几点需要说明一下:

    $字符在makefile中有特殊用途,因此如果要取消其特殊用途当成一个普通字符传递给echo命令执行,需要使用$$
    $@在bash shell中也有特殊用途,因此如果希望echo命令在bash中正常输出$@, 需要加上\字符
    该makefile的最后一行first second third: 看起来有点奇怪,这是一条没有依赖和命令的多目标规则,读者可自行将它删除看有什么效果,并思考原因。

演示及结果如下:

1-2.4.4-1
2.4.5 变量的替换引用

变量的分类与赋值

对于一个已经定义的变量,可以使用“替换引用”将其值使用指定的字符(字符串)进行替换。格式为 ( V A R : A = B ) 或 者 (VAR:A=B)或者 (VAR:A=B){VAR:A=B},意思是,将变量“VAR”所表示的值中所有字符串“A”结尾的字符替换为“B”的字。“结尾”的含义是空格之前(变量值的多个字以空格分开)。而对于变量其它部分的“A”字符不进行替换。例如:

sources := a.c b.c c.c d.d
objects := $(sources:.c=.o)
all:
    echo "objects = $(objects)"

在这个定义中,变量“objects”的值就为“a.c b.c c.c d.d”。使用变量的替换引用将变量“sources”以空格分开的值中的所有的字的尾字符“o”替换为“c”,其他部分不变,注意这里的d.d并不会被替换。

使用变量改进我们complicated项目的makefile(v1.2):

描述:complicated 项目 makefile文件

版本:v1.2

修改记录:

1. 为complicated项目makefile添加注释

2. 使用变量改进我们complicated项目的makefile

定义可执行文件变量

executbale := complicated

定义源文件列表变量

sources := main.c complicated.c

使用变量的引用替换,定义object文件列表

objects := $(sources:.c=.o)

定义编译命令变量

CC := gcc

终极目标规则,生成complicated可执行文件

$(executbale): $(objects)

使用自动化变量改造我们的编译命令

$(CC) -o $@ $^

子规则1, main.o的生成规则

main.o: main.c
$(CC) -o $@ -c $<

子规则2,complicated.o的生成规则

complicated.o: complicated.c
$(CC) -o $@ -c $<

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值