Next: , Previous: , Up: Functions for Transforming Text   [Contents][Index]


8.14 The shell Function

The shell function is unlike any other function other than the wildcard function (see The Function wildcard) 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 (see How make Reads a Makefile). 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 (see The Two Flavors of Variables).

An alternative to the shell function is the ‘!=’ assignment operator; it provides a similar behavior but has subtle differences (see Setting Variables). 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.


Next: The guile Function, Previous: Functions That Control Make, Up: Functions for Transforming Text   [Contents][Index]