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