[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [bug #52028] Preventing infinite recursions when make is invoked fro
From: |
Reinier Post |
Subject: |
Re: [bug #52028] Preventing infinite recursions when make is invoked from recipes |
Date: |
Fri, 15 Sep 2017 13:39:08 +0200 |
User-agent: |
Mutt/1.5.21 (2010-09-15) |
On Fri Sep 15 01:47:31 2017, address@hidden (anonymous) wrote:
[...]
> Summary: Preventing infinite recursions when make is invoked from recipes
[...]
> Details:
>
> 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))"; \
> fi
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.
https://ftp.gnu.org/old-gnu/Manuals/make-3.79.1/html_chapter/make_5.html#SEC50
Finally,
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.
https://www.microsoft.com/en-us/research/wp-content/uploads/2016/03/hadrian.pdf
--
Reinier Post
TU Eindhoven