Reputation: 253
In a makefile, I got the target all
and its dependency all-recursive
.
I search the whole Makefile, but I don't see all-recursive
defined. I think all-recursive
must also be a target, or how can make execute
all: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) all-recursive
I don't see the definition of all-recursive
.
if I delete it, the make program will continuously deal with the all target. Is all-recursive
built-in?
Upvotes: 24
Views: 9548
Reputation: 471
I spent hours finding them too. No, it's not a built-in feature of make
; it turned out that this is a characteristic of Autotools-generated Makefile.
Those THING-recursive
targets are actually defined in that very Makefile, but in a complicated way that you cannot use simple grep
to find them.
It starts from RECURSIVE_TARGETS
variable definition in the Makefile, which goes like this:
RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
html-recursive info-recursive install-data-recursive \
install-dvi-recursive install-exec-recursive \
install-html-recursive install-info-recursive \
install-pdf-recursive install-ps-recursive install-recursive \
installcheck-recursive installdirs-recursive pdf-recursive \
ps-recursive uninstall-recursive
Followed by a real definition of those targets somewhere below:
$(RECURSIVE_TARGETS):
@fail= failcom='exit 1'; \
for f in x $$MAKEFLAGS; do \
case $$f in \
*=* | --[!k]*);; \
*k*) failcom='fail=yes';; \
esac; \
done; \
dot_seen=no; \
target=`echo $@ | sed s/-recursive//`; \
list='$(SUBDIRS)'; for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| eval $$failcom; \
done; \
if test "$$dot_seen" = "no"; then \
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
fi; test -z "$$fail"
Which resolves into this:
all-recursive check-recursive dvi-recursive \
html-recursive info-recursive install-data-recursive \
install-dvi-recursive install-exec-recursive \
install-html-recursive install-info-recursive \
install-pdf-recursive install-ps-recursive install-recursive \
installcheck-recursive installdirs-recursive pdf-recursive \
ps-recursive uninstall-recursive:
@fail= failcom='exit 1'; \
for f in x $$MAKEFLAGS; do \
case $$f in \
*=* | --[!k]*);; \
*k*) failcom='fail=yes';; \
esac; \
done; \
dot_seen=no; \
target=`echo $@ | sed s/-recursive//`; \
list='$(SUBDIRS)'; for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| eval $$failcom; \
done; \
if test "$$dot_seen" = "no"; then \
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
fi; test -z "$$fail"
This target's recipe's is essentially a boilerplate code to loop through each subdirectory found in current folder and start make
inside it, using the same target name but with "-recursive" stripped out.
Note that these THING-recursive
targets are not meant to be called directly by user; it will be run automatically as a part of normal THING
target (without "-recursive"), as a mechanism to trigger same-target building in subprojects' tree.
Addendum: The example code is taken from configured root Makefile of GNU Flash Player (version e9eb84e).
Upvotes: 35