Follow-up Comment #6, bug #65533 (group make): You don't have to use EXPORT_ALL_VARIABLES, that is just a simple way to suffer the problem because it's indiscriminate.
The real problem is (a) exporting make variables, which (b) are recursively
expanded, and (c) contain $(shell ...) function references.
EXPORT_ALL_VARIABLES is one way to do that. But using explicit "export" on
variables like this can also cause problems. And, even more subtly, if a
variable is inherited from the environment then it will be automatically
marked as "export", even if you don't explicitly export it.
Consider this makefile:
+verbose+
FOO = $(shell set -x; echo foo)
BAR = $(shell set -x; echo bar)
#export FOO
#export BAR
all:
: $(FOO)
: $(BAR)
-verbatim-
These exports are commented out. Running this gives:
+ foo
+ bar
: foo
: bar
which is what we expect.
Now, suppose we uncomment the export of FOO; then we get:
+ echo foo
+ echo foo
+ echo bar
: foo
+ echo foo
: bar
Now we've run the shell extra times, because we needed to expand the make
variable FOO every time we need to run the $(shell ...) function, and
expanding the variable FOO requires that we run the $(shell ...) function.
Since make won't expand the same variable recursively we don't get into an
infinite loop here but it still requires extra steps.
Now if we uncomment BOTH the exports we see that the number of invocations of
the shell function goes up exponentially:
+ echo bar
+ echo foo
+ echo foo
+ echo bar
: foo
+ echo bar
+ echo foo
+ echo foo
+ echo bar
: bar
The more of these exported variables there are the larger the problem
becomes.
Frustratingly you can get the same behavior without an explicit export, just
by exporting a variable with the same name in the shell before make is
invoked, because make will mark all incoming variables as exported. So, if
you comment out all the exports within the makefile, but then do this:
$ FOO=a BAR=b make
you'll see the same issue with lots of extra shells invoked.
If you have an interest in investigating your makefiles to understand what's
happening, you can do something like this:
First add a rule in your makefiles which shows the environment, like this:
showenv : ; env | sort
Then, run make:
$ make showenv
You should be able to look through the variables listed and see which ones
were exported by your makefiles (e.g., were not in the environment before make
was invoked). Those are the variables to investigate and find out their
values.
You can also do something like this if there are too many variables listed:
$ env -i PATH="$PATH" make showenv
> There seems to be seriously wrong here.
It depends on what you mean by that. There's definitely a problem in that
makefiles that used to run faster are now running more slowly, sometimes
significantly. But if you mean that there's a behavior which is more
mysteriously wrong than what is documented and discussed in this bug report,
so far I don't see evidence of that.
_______________________________________________________
Reply to this item at:
<https://savannah.gnu.org/bugs/?65533>
_______________________________________________
Message sent via Savannah
https://savannah.gnu.org/
signature.asc
Description: PGP signature
