GNU Make recursively expanded variables examples

瘦欲@ 提交于 2020-01-14 03:40:29

问题


Could somebody provide a real-world example of using recursively expanded variables (REV)? In the docs or various blog posts people give only useless toy examples, like

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

I cannot find a real use for REV besides creating custom functions with $(call). I also found that in the past people were using REV to supply additional parameters to a compiler for specific targets but that trick is considered outdated now because GNU Make has target-specific variables.


回答1:


Both recursively expanded variables and simply expanded variables recurse their expansions. The major difference is when that expansion happens.

So your example above works just fine with simply expanded variables if you invert the assignments:

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

So the major thing that recursively expanded variables get you is the freedom to assign values in whatever order you need (which means you don't need to worry about inclusion order for included makefiles, etc.).

In a project at work we have a dozen or so included makefiles that have inter-dependent relationships. These are expressed through the usage of known-format variable names (e.g. module A generates an A_provides variable, etc.) Modules that need to utilize the things that module A provides can then list $(A_provides) in their makefiles.

With simply expanded variables (which we had been using until somewhat recently) this meant that the inclusion of the generated makefiles required a manually sorted order to force the inclusion of assigning makefiles before consuming makefiles (into other variables).

With recursively expanded variables this order does not matter. (This would not be the case if the variables were used in any immediately evaluated context in these makefiles but luckily they are not, they only set variables that are used later in the main makefiles.)




回答2:


Well, one simple example are variables which contain commands for recipes; perhaps:

buildc = $(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $<

%.o: %.c
        $(buildc)

I probably wouldn't write a compile rule like this this way, but if you have a much more complex recipe it can be very useful.

Personally I don't consider "additional parameters ... for specific targets" (by which I assume you mean recursively defined variables such as $($*_FLAGS)) to be outdated or obsoleted by target-specific variables, by any stretch. If nothing else recursively defined variables are much more portable than target-specific variables.




回答3:


It just means that recursively defined variables are set at the time of definition only!

The best example I can find is this

x := foo 
y := $(x) bar 
x := later

and is equivalent to

y := foo bar
x := later


来源:https://stackoverflow.com/questions/30213505/gnu-make-recursively-expanded-variables-examples

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!