Posix-compliant make internally uses the
macro to spawn shell processes and execute Make rules. This
is a builtin macro supplied by make, but it can be modified
by a makefile or by a command-line argument.
Not all make implementations define this
make is an example; this implementation always uses
/bin/sh. So it's a good idea to always define
your makefiles. If you use Autoconf, do
SHELL = @SHELL@
If you use Automake, this is done for you.
Do not force
SHELL = /bin/sh because that is not correct
everywhere. Remember, /bin/sh is not Posix compliant on many
systems, such as FreeBSD 4, NetBSD 3, AIX 3, Solaris 10, or Tru64.
Additionally, DJGPP lacks
/bin/sh, and when its
GNU make port sees such a setting it enters a
special emulation mode where features like pipes and redirections are
emulated on top of DOS's command.com. Unfortunately this
emulation is incomplete; for instance it does not handle command
@SHELL@ means that your makefile will
benefit from the same improved shell, such as bash or
ksh, that was discovered during configure, so that
you aren't fighting two different sets of shell bugs between the two
Posix-compliant make should never acquire the value of
$(SHELL) from the environment, even when
make -e is used
(otherwise, think about what would happen to your rules if
However not all make implementations have this exception.
For instance it's not surprising that Tru64 make doesn't
SHELL, since it doesn't use it.
$ cat Makefile SHELL = /bin/sh FOO = foo all: @echo $(SHELL) @echo $(FOO) $ env SHELL=/bin/tcsh FOO=bar make -e # Tru64 Make /bin/tcsh bar $ env SHELL=/bin/tcsh FOO=bar gmake -e # GNU make /bin/sh bar
Conversely, make is not supposed to export any changes to the
SHELL to child processes. Again, many implementations
break this rule:
$ cat Makefile all: @echo $(SHELL) @printenv SHELL $ env SHELL=sh make -e SHELL=/bin/ksh # BSD Make, GNU make 3.80 /bin/ksh /bin/ksh $ env SHELL=sh gmake -e SHELL=/bin/ksh # GNU make 3.81 /bin/ksh sh