make-alpha
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: .ONESHELL enhancement?


From: Paul Smith
Subject: Re: .ONESHELL enhancement?
Date: Wed, 23 Sep 2009 09:48:34 -0400

On Tue, 2009-09-22 at 18:43 -0400, David Boyce wrote:
> On Tue, Sep 22, 2009 at 3:34 PM, Paul Smith <address@hidden> wrote:
> > I can't speak to the Windows implementation, but why do you need to do
> > any translation of the script on POSIX systems?  You can pass a string
> > containing a newline to the shell and it will work; you don't have to
> > add in "&&" or ";" or anything.
> 
> Because the semantics are different. Newline behaves more like ; than
> &&, and for .ONESHELL too work we need && semantics.

What you mean here is that to make .ONESHELL behavior be identical to
current GNU make behavior, except that you get a potential performance
boost and some simplicity in scripting, you would need && semantics.

It would still WORK without them, it's just that error handling would be
different.

However, I'm not necessarily convinced by this argument.  First, note
that the latest POSIX standard mandates that make invoke shells with
"set -e" enabled by default (a change, and a very serious one, from
previous standards).  If you follow the standard here then adding "&&"
is NOT required, since the script will error out immediately anyway due
to -e.  Thus I don't think the standard intends that we should add "&&"
at all.

Unfortunately, GNU make does not (any longer) follow the standard here,
so we're kind of stuck.


I'm actually quite uneasy about attempts to interpret and modify the
recipe string, even with something as ostensibly simple as concatenating
logical lines with "&&".  IME, it's always very dangerous and difficult
to make these kinds of changes without incurring nasty side-effects.

I think some of the examples Matt gives are quite telling: if a stated
goal of .ONESHELL is to reduce the need for many continued lines then
adding "&&" can cause problems: really instead of the fairly
straightforward "the entire recipe is passed, as-is, to the shell", we
have to discuss that each logical line in the recipe must be a
self-enclosed shell statement.  Take Matt's example here:

> foo: bar
>         if test -s $<
>         then
>                 echo 'nonempty' >$@
>         else
>                 echo 'empty' >$@
>         fi

This cannot work; ALL of these must use backslashes:

        foo: bar
                if test -s $<; then \
                        echo 'nonempty' >$@; \
                else \
                        echo 'empty' >$@; \
                fi

I really don't see how you simplify your recipe writing in this
situation: any complex recipe must continue to use backslashes to be
sure that "&&" is not introduced where it's not wanted/valid.

That's not even mentioning what happens if SHELL is set to something
that's not a POSIX shell; if we have .ONESHELL it becomes (IMO) more
likely someone will want to use a separate script interpreter like Perl
or whatever (yes, I remember the -c flag problem but this can be worked
around).  Do we only add "&&" if we know we have a POSIX shell (similar
to the fastpath computation)?  This gets more and more complex.

Instead, I would prefer to keep this simple.  It's not identical in
behavior to just pass the string unmodified, but it's very easy to
understand what will happen and what make will do.

People who want identical behavior add "set -e" in their scripts, maybe?


At the same time I'd like to figure out what to do about this new POSIX
requirement that we use -e: maybe if we can solve this, then the
previous issue will not be such a problem.  The last time this came up
we discussed changing the shell invocation to "-e" by default if
the .POSIX pseudo-target was set; I think this is the least we should
do.

I don't really like that the behavior changes in this somewhat magical
way when you set .POSIX though.  I do wonder how many makefiles will
actually break if we make this change permanent even without .POSIX set.

Another thing I've wanted to do for a long time was introduce a variable
that controls the flags used with the shell.  Right now we have
hard-coded "-c" as the flag, but it would be really great if people
could change this.  Maybe a make variable like .SHELLFLAGS with a
default value of "-c" (no quotes of course)?  Then people could set it
to "-ec" to get POSIX behavior, or even "-xec" for debugging.  And, if
they wanted to set SHELL to /usr/bin/perl they could set .SHELLFLAGS to
"-e".

Alternatively along with this flag we could introduce POSIX behavior as
the default, then people whose makefiles didn't work that way could
set .SHELLFLAGS to just "-c".

-- 
-------------------------------------------------------------------------------
 Paul D. Smith <address@hidden>          Find some GNU make tips at:
 http://www.gnu.org                      http://make.mad-scientist.net
 "Please remain calm...I may be mad, but I am a professional." --Mad Scientist




reply via email to

[Prev in Thread] Current Thread [Next in Thread]