Handling of shell builtins in make(1)

Max Okumoto okumoto at ucsd.edu
Mon May 23 17:21:08 PDT 2005


Harti Brandt <hartmut.brandt at dlr.de> writes:

> Hi all,
>
> I think I found a problem in the shell code in make(1), but I'm not
> sure whether to fix it or not and how. The problem is as follows: in
> compat mode (this is the default mode when make(1) is not called with
> -j) the command lines of a target are executed by one shell per line
> (this is also how Posix wants it). To reduce the number of shells make
> does an optimisation: when the command line does not contain one of a
> pre-defined set of meta characters and does not start with one of a
> predefined set of shell builtins, make directly exec's the command
> instead of using an intermediate shell. The problem is that the
> current list of builtins is limited to:
>
>    alias cd eval exec exit read set ulimit unalias umask unset wait
>
> Obviously this is not the full set of shell builtins and does also not
> contain the shell reserved words.
>
> The result of this is that for one and the same command you can get
> different behaviour whether you execute it via make(1) or via sh -c
> '...'.
> As an example take echo(1). When called via the sh -c you get the builtin
> echo which supports the -e option, when executed by make(1) you get
> /bin/echo which doesn't. If you suddenly include a shell meta
> character in the command line:
>
> foo:
>  	echo "MAKEFLAGS: ${MAKEFLAGS}"
>
> you suddenly get also the builtin (':' is a meta character).
>
> For the reserved words the situation is almost the same. With the
> following makefile:
>
> foo:
>  	if
>
> one gets:
>
> if:No such file or directory, while
>
> foo:
>  	if [ -x /bin/sh ] ; then echo hey ; fi
>
> you get what you expect.
>
> I think all this may be very confusing. The question is what to do. I
> see the following options:
>
> 1. leave it as it is.
>
> 2. include the Posix reserved words and builtins into the list.
>
> 3. include all reserved words and builtins of our shell into the list.

4. Extend .SHELL: to allow specifing a list of built-in.  And then
   we should define them in bsd.sys.mk or some other config file.


> Option (3) is probably best. With (2) you still get different
> behaviour for the two command lines in:
>
> foo:
>  	bind -h
>  	bind -h *
>
> (the first line will try to find bind in the path while the second
> will execute the shell builtin).
>
> Opinions?

This will allow people to add keywords for their shells, and
remove that stuff from the make source code.  Hard coding it
in the binary is wrong.

                 Max Okumoto
>
> harti
> _______________________________________________
> freebsd-arch at freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/freebsd-arch
> To unsubscribe, send any mail to "freebsd-arch-unsubscribe at freebsd.org"


More information about the freebsd-arch mailing list