在Makefile中我们可能遇到过$$,开始的时候不明白这是什么意思,在这里做一下笔记来记录一下。


例子:

define func

#$(1) is foo
$(1)_test = taget_val

$($(1)_test) = taget_val2


$$($(1)_test) = taget_val3
endef

$(info $(call func,foo))

all:
@echo end ...



执行一下Make看一结果和我们想象的是否一样 (info 函数用来打印call的执行结果)

hhp@Lenovo:~/mk$ make

#foo is foo
foo_test = taget_val

= taget_val2


$(foo_test) = taget_val3
end ...


call 是一个展开和替换的过程,奇怪的是执行结果好像和想想的不太一样,来分析一下。

(1 )

#$(1) is foo

这句话我们想写成注释,但是call函数遇到$元字符就会被展开,所以也就变成了

#foo is foo

如果想展开成

#$(1) is foo

我们应该写成:

#$$(1) is foo

在$ 前面在加一个$,这就$就只表示不同字符$而不是元字符或关键字$了,那么call也就不会在进行展开了。


(2)

$(1)_test = taget_val

这句话同样$(1)被展开成foo了,展开结果如下

foo_test = taget_val


(3)

$($(1)_test) = taget_val2

这个很多人想不明包了,那我们来分析一下。

我们一步一步进行展开,

第一步:替换$(1),展开结果如下:

$(foo_test)=taget_val2

第二步:展开替换$(foo_test)结果如下

 = taget_val2

有人说不对呀,应该是

taget_val=taget_val2

这样是错误的,因为call只是展开而不执行,$(1)_test = taget_val这句话只是展开而没有真正的执行,如果将展开执行,就是需要用到常用的eval函数了。。

所以$(foo_test)应该是空,而不是taget_val

(4)

$$($(1)_test) = taget_val3

第一步:替换$(1),结果如下:

$$(foo_test)=taget_val3

第二步比较关键,$(foo_test)并不会被展开,因为这里$已经不是元字符$,因为$前面还有一个$,也就是说在Makefile中想使用$为普通$字符,就需要写成$$所以真正的展开结果

应该是:

$(foo_test)=taget_val3


如果以上分析不对,请高手留言批评指正