GNU Make递归扩展变量的例子

时间:2015-05-13 11:30:01

标签: makefile gnu-make

有人可以提供使用递归扩展变量(REV)的真实示例吗?在文档或各种博客文章中,人们只提供无用的玩具示例,例如

foo = $(bar)
bar = $(ugh)
ugh = Huh?

除了使用$(call)创建自定义函数之外,我找不到REV的实际用途。我还发现,过去人们使用REV为特定目标的编译器提供额外的参数,但这个技巧现在被认为是过时的,因为GNU Make具有特定于目标的变量。

3 个答案:

答案 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