On Wed, Oct 4, 2023 at 6:09 PM Till Backhaus <t...@backha.us> wrote:
> This rather short Makefile shows exponential runtime depending on the number 
> of variables.
> VAR_1 ?= $(shell echo 1)
...

VAR_1 is a recursively expanded variable. When make defines this
variable, the value is set to string '$(shell echo 1)'. No subshell is
spawned at this time. Each time make expands this variable, make
spawns a shell and has the shell execute 'echo 1' and the output of
the subshell is the result of the expansion.

This is in contrast with
VAR_X := $(shell echo 1)

VAR_X is a simply expanded variable. When make defines this variable,
make spawns a shell and has the shell execute 'echo 1' and sets the
value of the variable to the output of the subshell. Then each time
this variable is expanded, make won't spawn the shell again.

The difference is critical in this scenario. With variables exported
to subshell, each time make spawns a subshell, it has to expand all
these variables. E.g. in order to expand VAR_7, make has to spawn a
subshell. In order to spawn this subshell, make has to export VAR_6,
VAR_5, etc. Each of those requires its own subshell, which again
requires make to export these variables, etc.

Prefer simply expanded variables with $(shell).

regards, Dmitry

Reply via email to