Makefile: defining rules and prerequisites in recipes

假如想象 提交于 2019-12-11 01:22:33

问题


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 (bar in this case) outputs?

  • how do I update the prerequisites of a target (blub in this case) dynamically at runtime, based on (and dependent on) what another recipe (bar in 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

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