autoconf: The Make Macro SHELL

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