Given a Makefile:
ifeq "$(MAKELEVEL)" "0"
0 ::
@$(MAKE)
else
1 ::
@echo 'foo is: "$(foo)"'
endif
And executing, we get:
$ make foo='$@'
make[1]: Entering directory '/home/myname'
foo is: "1"
make[1]: Leaving directory '/home/myname'
$ make foo='$@' --environment-overrides
make[1]: Entering directory '/home/myname'
foo is: "0"
make[1]: Leaving directory '/home/myname'
So we have here a recursive variable foo with the value: $@, which - of course - expands to the name of the target. Now, we have two options here:
- Either, Make expands first the variable, and then export the variable to a sub-make.
With this "logic", when Make runs the first makefile (MAKELEVEL = 0), it will build the target 0, Hence: expand the variablefoo(and its value:$@) to0, and then export - this already expanded value - to the sub-make.
This result, with the sub-make running its makefile, with a variablefoothat has the simple value:0.
This is in-fact the case, when we runmake --environment-overrides, as you can see in the second run of the makefile, in the example above. Another "logic" is, for Make to pass the value "verbatim". That means, with no expansion!
Hence all recursive variables will be still intact, when passed to the second Make.
For this logic, only the sub-make is allowed to expand its variables recursively, hence: any recursive-expansion will be done in the context of the sub-make.
In our example above, that we hadfoowith its value$@, if we are to follow this logic, Make will pass the value$@"verbatim", with no expansion at all, so the sub-make will effectively see a value$@for itsfoovariable, hence: when expanding in the context of its target, that happens to be 1, it will recursively expandfoo(and its value:$@) to 1.
Actually, this is the "normal" behaviour that is evident in the first run of makefile, as evident in the example above.
So, for a lack of clear methodology, we are left to conclude, that this behaviour of either expand and then export or export and then expand is inconsistent.
That is, sometimes Make will choose the first method, where sometimes it will chose the second.
In our example, it was a command-line option (--environment--overrides), that acted as a deciding factor, as to what method Make has to choose.
But, can we really justify, that these - seemingly - unrelated features (i.e export/recursive vs. environment-overrides), will end up to have such a dramatic effect on each-other?
(Versions note: 4.0 and up).