[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Variable expansion question
Re: Variable expansion question
Wed, 26 Oct 2022 15:43:41 +0200
Many thakns for your response, precious and helpful as usual.
Paul Smith (2022/10/24 12:33 -0400):
> On Mon, 2022-10-24 at 14:10 +0200, Sébastien Hinderer wrote:
> > define BUILD_MACRO
> > $(1): $$($$(basename $$(notdir $(1)))_OBJECTS:=.o)
> > @echo Building $$@ from $$^
> > endef # BUILD_MACRO
> > $(foreach PROGRAM, $(PROGRAMS),\
> > $(eval $(call BUILD_MACRO,$(PROGRAM))))
> > If progmod1.o and progmod2.o exist, then running `make
> > tools/prog.exe` displays:
> > Building tools/prog.exe from progmod1.o progmod2.o
> > Which is what I expect.
> > However, if prog_OBJECTS is defined after the call to foreach rather
> > than before, then the same command ran in the same context says:
> > Building tools/prog.exe from
> > In other words the evaluated list of prerequisites is empty and I am
> > wondering why this is so and whether there would be a way to defiine
> > BUILD_MACRO so that therelative positions of its invocation andthe
> > definition of the _OBJECTS variables does not matter.
> Short answer is "basically, no".
> Why does this happen? Because the targets and prerequisites of a rule
> are expanded in "immediate context" which means "as the makefile is
> read in".
Okay. Actually in the original Makefile (which is more complex than what
I showed above) I had added the ".SECONDEXPANSION:" target so because of
that and the doubled dollars I thought I did use secondary expansion
already but I realise with your repsonse that this was a wrong
assumption of mine. But then, just to make sure, is it because of eval
that all the double dollars were necessary? Because I think I wrote the
macro in the simplest way possible and it would not have worked if I had
used less dollars than I did, right?
> So when the makefile is parsed, the foreach loop is
> expanded, which expands the eval, which expands the call, etc. and the
> whole thing exists right there in the makefile as if you'd written it
> out by hand. If you replace the "eval" call in your loop with "info"
> it will print out the content of the makefile that make will then
> parse, as if you'd typed it in directly.
Ah, many thanks for explaining all this and reminding the info debugging
trick, I find both points very useful.
> See for example:
> But the longer answer is "yes there's a way to do it". You need to
> delay the expansion of the prerequisites until after you're sure that
> all the *_OBJECTS variables have been set.
> One straightforward way to do it is to put the foreach etc. into a
> variable, and expand the variable at the end of the makefile after all
> possible resetting of *_OBJECTS is complete.
Okay, makes sense. Except that I'd rather not impose any particular
style to the users of the macro.
> Another option is to use secondary expansion; this would require even
> more escaping than you have above. Probably the easiest thing to do is
> put the prerequisite into a separate variable and use that, something
> like this:
> BUILD_PREREQS = $($(basename $(notdir $@))_OBJECTS:=.o)
> define BUILD_MACRO
> $(1): $$$$(BUILD_PREREQS)
> @echo Building $$@ from $$^
> endef # BUILD_MACRO
Is it necessary to use a variable, here? If I wanted to change the
content of the macro itself so that secondary expansion takes place,
woudlnt it be enough to just add two more addition $ signs at the outer
level, so something like
$(1): $$$$($$(basename $$(notdir $(1)))_OBJECTS:=.o)