有人可以提供使用递归扩展变量(REV)的真实示例吗?在文档或各种博客文章中,人们只提供无用的玩具示例,例如
foo = $(bar)
bar = $(ugh)
ugh = Huh?
除了使用$(call)
创建自定义函数之外,我找不到REV的实际用途。我还发现,过去人们使用REV为特定目标的编译器提供额外的参数,但这个技巧现在被认为是过时的,因为GNU Make具有特定于目标的变量。
答案 0 :(得分:3)
两个递归扩展变量和简单地扩展变量递归它们的扩展。当扩展发生时,主要的区别是。
因此,如果您反转分配,上面的示例可以很好地使用扩展变量:
'entity_report' => array(
array(
'field' => 'id',
'label' => 'id',
'rules' => 'trim|required|is_natural_no_zero|entity_exist'
)
)
因此,递归扩展变量的主要功能就是可以自由地按照您需要的顺序分配值(这意味着您不必担心包含的makefile的包含顺序等)。
在一个工作项目中,我们有十几个包含相互依赖关系的makefile。这些通过使用已知格式变量名来表示(例如,模块A生成ugh := Huh?
bar := $(ugh)
foo := $(bar)
变量等。)需要利用模块A提供的东西的模块然后可以在其makefile中列出A_provides
简单地扩展变量(我们直到最近才使用)这意味着包含生成的makefile需要手动排序的顺序,以强制在使用makefile之前包含赋值makefile(到其他变量中)。
使用递归扩展变量,此顺序无关紧要。 (如果变量在这些makefile中的任何立即评估的上下文中使用,情况就不会这样,但幸运的是它们不是,它们只设置稍后在主makefile中使用的变量。)
答案 1 :(得分:2)
嗯,一个简单的例子是包含食谱命令的变量;也许:
buildc = $(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $<
%.o: %.c
$(buildc)
我可能不会这样写这样的编译规则,但是如果你有一个更复杂的配方,它会非常有用。
就我个人而言,我不认为“特定目标的附加参数”(我假设你的意思是递归定义的变量,例如$($*_FLAGS)
)会被特定于目标的变量过时或过时伸展。如果没有其他任何递归定义的变量比目标特定的变量更便携。
答案 2 :(得分:0)
这仅意味着递归定义的变量仅在定义时设置!
我能找到的最好的例子是
x := foo
y := $(x) bar
x := later
并等同于
y := foo bar
x := later