[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [bug #52028] Preventing infinite recursions when make is invoked fro
Re: [bug #52028] Preventing infinite recursions when make is invoked from recipes
Fri, 15 Sep 2017 13:39:08 +0200
On Fri Sep 15 01:47:31 2017, address@hidden (anonymous) wrote:
> Summary: Preventing infinite recursions when make is invoked from recipes
> Consider this Makefile:
> a :
> echo a1
> $(MAKE) b
> echo a2
> b :
> echo b1
> $(MAKE) a
> echo b2
> Building either a or b will cause infinite recursion.
Yes, this is a potential issue with recursive $(MAKE) invocations,
but it is not a bug.
> It is possible to work around this with a template, similar to the following:
> SHELL := bash
> exportable = $(shell echo $(1) | sed 's%[^[:alnum:]_]%_%g')
> define make
> $(eval d := $(strip $(call exportable,$(1))))
> $(eval f := $(if $(strip $(2)), -f $(realpath $(strip $2))))
> if [ "$$_making_$(d)" != "$@" ]; then \
> export _making_$(d)="$@"; \
> $(MAKE) $(f) "$(strip $(1))"; \
This is a bad idea, for several reasons:
1. It uses nonportable functionality.
Some of that will go away when implemented directly in C code,
but not all of it. How to implement realpath for arbitrary
operating systems and arbitrary file systems? If it were easy
enough, GNU Make would have had it a long time ago.
2. It's a hack; there will always be cases slipping through.
It is fundamentally impossible to determine whether a call
to $(MAKE) is recursive just by looking at the calling syntax.
E.g., realpath doesn't look at hard links.
3. There is a better way.
A much simpler way to stop infinite recursion is to pass
a variable indicating the recursion depth and make recursive calls
conditional on its value.
The $(MAKELEVEL) variable is provided for that purpose,
and it has been in GNU Make for a long time, see e.g.
0. There are more reasons to avoid $(MAKE).
Nonrecursive make can be faster and can track dependencies better,
although it may not be wise to avoid $(MAKE) at all costs, see e.g.