manpagez: man pages & more
info make
Home | html | info | man

File: make.info,  Node: Shell Function,  Next: Guile Function,  Prev: Functions.php">Make Control Functions,  Up: Functions

8.14 The 'shell' Function
=========================

The 'shell' function is unlike any other function other than the
'wildcard' function (*note The Function 'wildcard': Wildcard Function.)
in that it communicates with the world outside of 'make'.

   The 'shell' function provides for 'make' the same facility that
backquotes ('`') provide in most shells: it does "command expansion".
This means that it takes as an argument a shell command and expands to
the output of the command.  The only processing '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 'shell' function are run when the
function calls are expanded (*note How 'make' Reads a Makefile: Reading
Makefiles.).  Because this function involves spawning a new shell, you
should carefully consider the performance implications of using the
'shell' function within recursively expanded variables vs. simply
expanded variables (*note The Two Flavors of Variables: Flavors.).

   An alternative to the 'shell' function is the '!=' assignment
operator; it provides a similar behavior but has subtle differences
(*note Setting Variables: Setting.).  The '!=' assignment operator is
included in newer POSIX standards.

   After the 'shell' function or '!=' assignment operator is used, its
exit status is placed in the '.SHELLSTATUS' variable.

   Here are some examples of the use of the 'shell' function:

     contents := $(shell cat foo)

sets 'contents' to the contents of the file 'foo', with a space (rather
than a newline) separating each line.

     files := $(shell echo *.c)

sets 'files' to the expansion of '*.c'.  Unless 'make' is using a very
strange shell, this has the same result as '$(wildcard *.c)' (as long as
at least one '.c' file exists).

   All variables that are marked as 'export' will also be passed to the
shell started by the 'shell' function.  It is possible to create a
variable expansion loop: consider this 'makefile':

     export HI = $(shell echo hi)
     all: ; @echo $$HI

   When 'make' wants to run the recipe it must add the variable HI to
the environment; to do so it must be expanded.  The value of this
variable requires an invocation of the 'shell' function, and to invoke
it we must create its environment.  Since HI is exported, we need to
expand it to create its environment.  And so on.  In this obscure case
'make' will use the value of the variable from the environment provided
to '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:

     export PATH = $(shell echo /usr/local/bin:$$PATH)

   However, it would be simpler and more efficient to use a
simply-expanded variable here (':=') in the first place.

© manpagez.com 2000-2024
Individual documents may contain additional copyright information.