问题
I have a setup where the files I want to process with make are dependent on the output of another program. Building the program and all its prerequisites is also a complicated task so I would like to use make for this as well. Now my problem is, that it doesn't seem that one can generate rules and prerequisites in Makefile recipes. Consider the following code:
bar:
echo target1 target2 target3 > bar
foo: bar
$(eval BAR := $(shell cat bar))
define FUN
$(1):
touch a$(1)
endef
ifdef BAR
$(foreach i,$BAR,$(eval $(call FUN,$(i))))
endif
blub: foo $(BAR)
I replaced a big set of complicated recipes that lead to the generation of the list of files I want to have in the end by the bar recipe. In reality, producing the content of bar is very complicated and should be done by a set of Makefile recipes and cannot just be done by (as the above suggests):
BAR:=$(shell echo target1 target2 target3)
I would like to put the foreach loop into the recipe for foo but that fails with prerequisites cannot be defined in recipes which makes sense and is also explained in function define in makefile
But it seems that when I do make blub that at the time when foo eval's BAR to a different value, the prerequisites for blub are not re-evaluated.
So I think ultimately I'm looking for two things:
how do I generate recipes dynamically at runtime, based on (and dependent on) what another recipe (
barin this case) outputs?how do I update the prerequisites of a target (
blubin this case) dynamically at runtime, based on (and dependent on) what another recipe (barin this case) outputs?
Thank you!
EDIT: SOLUTION
With the help of @user657267 the following seems to solve my problem:
.PHONY: all
all: blub
-include bar.make
.PHONY: blub
blub: $(BAR)
echo $^
bar.make: Makefile
printf 'BAR=target1 target2 target3\n' > $@
printf 'target1 target2 target3:\n' >>$@
printf '\ttouch $$@' >> $@
.PHONY: clean
clean:
rm -f target1 target2 target3 bar.make
回答1:
Sounds like you should be using make's self-remaking features
-include bar.make
blub: $(BAR)
@echo $^
bar.make:
@echo BAR := target1 target2 target3 > $@
@echo target1 target2 target3: ; touch $$@ >> $@
Obviously the recipes for bar.make are contrived, in the real world they'd probably invoke some kind of script that outputs a valid makefile.
来源:https://stackoverflow.com/questions/39188323/makefile-defining-rules-and-prerequisites-in-recipes