bug-make
[Top][All Lists]
Advanced

[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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]