summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorPaul Smith <psmith@gnu.org>2022-09-10 16:21:23 -0400
committerPaul Smith <psmith@gnu.org>2022-09-10 16:27:47 -0400
commit70ba0357a080f72b9f5912f16b3ffc095db381e6 (patch)
treefef33bac04c3d9c8708b7dee86341ffb358ba99a /doc
parent7d484017077089ac2642b89da8984ca46a07323d (diff)
downloadmake-git-70ba0357a080f72b9f5912f16b3ffc095db381e6.tar.gz
[SV 63040] shell: Fall back to the callers environment
If we detect a recursive variable reference when constructing the environment for the shell function, return the original value from the caller's environment. Other options such as failing, returning the empty string, or returning the unexpanded make variable value have been shown to not behave well in real-world environments. If the variable doesn't exist in the caller's environment, return the empty string. Found by Sergei Trofimovich <slyich@gmail.com> when testing older versions of autoconf. * NEWS: Clarify this behavior. * doc/make.texi (Shell Function): Ditto. Also add info about !=. * src/expand.c (recursively_expand_for_file): Search the caller's environment if we detect a recursive variable expansion. * tests/scripts/functions/shell: Add tests for this behavior.
Diffstat (limited to 'doc')
-rw-r--r--doc/make.texi44
1 files changed, 28 insertions, 16 deletions
diff --git a/doc/make.texi b/doc/make.texi
index 6fb8bb8c..1598ef65 100644
--- a/doc/make.texi
+++ b/doc/make.texi
@@ -8629,21 +8629,25 @@ The @code{shell} function is unlike any other function other than the
(@pxref{Wildcard Function, ,The Function @code{wildcard}}) in that it
communicates with the world outside of @code{make}.
-The @code{shell} function performs the same function that backquotes
-(@samp{`}) perform in most shells: it does @dfn{command expansion}.
-This means that it takes as an argument a shell command and evaluates
-to the output of the command. The only processing @code{make} does on
-the result is to convert each newline (or carriage-return / newline
-pair) to a single space. If there is a trailing (carriage-return
-and) newline it will simply be removed.@refill
+The @code{shell} function provides for @code{make} the same facility that
+backquotes (@samp{`}) provide in most shells: it does @dfn{command expansion}.
+This means that it takes as an argument a shell command and expands to the
+output of the command. The only processing @code{make} does on the result is
+to convert each newline (or carriage-return / newline pair) to a single space.
+If there is a trailing (carriage-return and) newline it will simply be
+removed.
The commands run by calls to the @code{shell} function are run when the
-function calls are expanded (@pxref{Reading Makefiles, , How
-@code{make} Reads a Makefile}). Because this function involves
-spawning a new shell, you should carefully consider the performance
-implications of using the @code{shell} function within recursively
-expanded variables vs.@: simply expanded variables (@pxref{Flavors, ,The
-Two Flavors of Variables}).
+function calls are expanded (@pxref{Reading Makefiles, , How @code{make} Reads
+a Makefile}). Because this function involves spawning a new shell, you should
+carefully consider the performance implications of using the @code{shell}
+function within recursively expanded variables vs.@: simply expanded variables
+(@pxref{Flavors, ,The Two Flavors of Variables}).
+
+An alternative to the @code{shell} function is the @samp{!=} assignment
+operator; it provides a similar behavior but has subtle differences
+(@pxref{Setting, , Setting Variables}). The @samp{!=} assignment operator is
+included in newer POSIX standards.
@vindex .SHELLSTATUS
After the @code{shell} function or @samp{!=} assignment operator is
@@ -8682,9 +8686,17 @@ When @code{make} wants to run the recipe it must add the variable @var{HI} to
the environment; to do so it must be expanded. The value of this variable
requires an invocation of the @code{shell} function, and to invoke it we must
create its environment. Since @var{HI} is exported, we need to expand it to
-create its environment. And so on. In this obscure case @code{make} will not
-add recursively-expanded variables to the @code{shell} environment rather than
-fail with an error.
+create its environment. And so on. In this obscure case @code{make} will use
+the value of the variable from the environment provided to @code{make}, or
+else the empty string if there was none, rather than looping or issuing an
+error. This is often what you want; for example:
+
+@example
+export PATH = $(shell echo /usr/local/bin:$$PATH)
+@end example
+
+However, it would be simpler and more efficient to use a simply-expanded
+variable here (@samp{:=}) in the first place.
@node Guile Function, , Shell Function, Functions
@section The @code{guile} Function