曲径通幽论坛

 找回密码
 立即注册
搜索
查看: 6172|回复: 0
打印 上一主题 下一主题

call 函数 -- 传递参数到变量

[复制链接]

4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34397
跳转到指定楼层
楼主
发表于 2011-6-18 16:25:51 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
通过 call 函数可以将一个变量定义为一个复杂的表达式,它的语法格式为:
$(call VAR, 参数1, 参数2,...)
call 函数可以将 "参数1“ ,”参数2“ 传递到 VAR 中,然后 VAR 根据传递进来的参数进行展开成一个完整的表达式。

在函数执行时,参数1,参数2, 参数3, ... 等等会依次赋值到临时变量 $(1), $(2), $(3) ... 上,而这些临时变量则是定义在 VAR 中的。看下面例子演示:
[Plain Text] 纯文本查看 复制代码
reverse = $(2)$(1)

foo = $(call reverse, a, b)

all:
    @echo "foo = $(foo)"

运行输出:
$ make
foo =  b a
参数 a 传递到 $(1) 中,参数 b 传递到 $(2) 中;而在变量 reverse 中并不要求 $(1) ,$(2) 这些变量有一定的顺序。也可以说,$(1), $(2) 这些是形参,而 a, b 这种是实参。

下面再演示一个复杂的例子:
[Plain Text] 纯文本查看 复制代码
lsfirstpath = $(subst /ls, ,$(wildcard $(addsuffix /$(1),$(subst :, ,$(PATH)))))

lsPath := $(call lsfirstpath,ls)

all:
    @echo "command 'ls' is in \"$(call lsfirstpath,ls)\""

运行输出:
[beyes@beyes exp2]$ make
command 'ls' is in "/bin "
在上面的 Makefile 代码中,$(PATH) 是共有的环境变量,它存放各种路径名,这些路径名用冒号隔开。

$(subst :, ,$(PATH)) 这句用来去掉 $(PATH) 中的冒号。

$(addsuffix /$(1),$(subst :, ,$(PATH))) 这句为每个路径名后面添加上 "/$(1)",因为这里的 $(1) 其实就是 $(call lsfirstpath,ls) 中传递过去的 ls,所以此举执行之后会变成:
/usr/lib/ccache/ls /usr/local/bin/ls /usr/binls  ... ...
等等。

$(wildcard $(addsuffix /$(1),$(subst :, ,$(PATH)))) 这句中的 wildcard 函数是用来匹配文件是否存在,如果存在则保留下来,不存在就去掉。

$(subst /ls, ,$(wildcard $(addsuffix /$(1),$(subst :, ,$(PATH))))) 最后当我们找到了 ls 所在的路径后,去掉 ”/ls“ 后就得出了它所在的目录。


另外,还有 $(0) 这个变量,它代表的是 VAR 本身。

call 函数还可以嵌套的调用。在嵌套调用时,每一层都有自己特定的局部变量($(1), $(2)...等),这些局部变量不会传递到下一层去,如:
[Plain Text] 纯文本查看 复制代码
k = $(2)$(1)

map = $(foreach a,$(2),$(call $(1),$(a),good-))

o = $(call map,k,are you ok)

all:
    @echo "$(o)"

运行输出:
[beyes@beyes exp3]$ make
good-are good-you good-ok
在上面的 Makefile 文件中,第 1 层 call 是 $(call map,k,are you ok) ,在这里 $(1) 和 $(2) 分别为 kare you ok ,所以对已经定义的表达式 map 进行展开后得:
$(foreach a,are you ok,$(call k,$(a),good-))
第二层 call 为 $(call k,$(a),good-),在这里,它有自己的 $(1) 和 $(2);$(1) 就是 $(a) -- 就是 foreach 函数捡取的值(依次为 are you ok),$(2) 为 good- 。

要非常小心的是,在对 call 和 foreach 这些函数应用时,一定要注意空格,如果不小心多了空格,看到的结果基本上不是你所期望的。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|曲径通幽 ( 琼ICP备11001422号-1|公安备案:46900502000207 )

GMT+8, 2025-6-17 20:02 , Processed in 0.059047 second(s), 23 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表