Assume I have a make rule:
.PHONY:gen
gen: auto.template
generate-sources auto.template
that creates a bunch of files, for example auto1.src
, auto2.src
, auto3.src
and so on.
If I now have rules to build targets from *.src
files, like this:
$(patsubst %.src,%.target,$(wildcard *.src)): %.target: %.src
build $< > $@
How can I tell make to first execute the gen
rule and then expand the preconditions for the second rule template? GNU extensions are welcome.
Note: I would like to keep it in one make
invocation; A trivial solution to this would be to put the second rule in a secondary Makefile.secondrun
and call $(MAKE) -f Makefile.secondrun
after gen
was processed. But I was wondering if there is a better option.
Building off Beta's answer, here's how you can do it using makefile remaking in GNU make, which is not the same thing as recursive make. Rather, it updates an included makefile using a rule in the main makefile, then restarts the original make instance. This is how *.d
dependency files are typically generated and used.
# Get the list of auto-generated sources. If this file doesn't exist, or if it is older
# than auto.template, it will get built using the rule defined below, according to the
# standard behavior of GNU make. If autosrcs.mk is rebuilt, GNU make will automatically
# restart itself after autosrcs.mk is updated.
include autosrcs.mk
# Once we have the list of auto-generated sources, getting the list of targets to build
# from them is a simple pattern substitution.
TARGETS=$(patsubst %.src,%.target,$(AUTO_SRCS))
all: $(TARGETS)
# Rule describing how to build autosrcs.mk. This generates the sources, then computes
# the list of autogenerated sources and writes that to autosrcs.mk in the form of a
# make variable. Note that we use *shell* constructs to get the list of sources, not
# make constructs like $(wildcard), which could be expanded at the wrong time relative
# to when the source files are actually created.
autosrcs.mk: auto.template
./generate-sources auto.template
echo "AUTO_SRCS=`echo *.src`" > autosrcs.mk
# How to build *.target files from *.src files.
%.target: %.src
@echo 'build $< > $@'
Short answer: you can't. Make determines all of the rules it will have to execute before it executes any rule.
Longer answer: maybe you can. As you say, you can use recursive Make explicitly, or surreptitiously by, say, building a file which your makefile will include
(I'm looking at you, Jack Kelly). Or if you could somehow obtain a list of the files which gen
will build, you could write a rule around that. Or you could take a leap of faith like this:
%.target: %.src
build $< > $@
%.src: gen;