Handling of shell builtins in make(1)

Harti Brandt hartmut.brandt at dlr.de
Tue May 24 00:34:54 PDT 2005


On Mon, 23 May 2005, Scott Long wrote:

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

Would there be other uses for this?

harti


More information about the freebsd-arch mailing list