Hey Paul, 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: > https://www.gnu.org/software/make/manual/html_node/Reading-Makefiles.html > > 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: > > .SECONDEXPANSION: > > BUILD_PREREQS = $($(basename $(notdir $@))_OBJECTS:=.o) > > define BUILD_MACRO > $(1): $$$$(BUILD_PREREQS) > @echo Building $$@ from $$^ > endef # BUILD_MACRO > > (untested) 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) Thanks, Sébastien. > >