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 13:57:37 -0400

On Wed, 2009-09-23 at 10:50 -0400, David Boyce wrote:
> I do remember this fuss and it is a painful problem. Doesn't seem
> POSIX-like to make such a significant change at this late date, and
> they may not have realized what they were doing, but it's done and
> yes, it's a problem. And also an opportunity, as you note below, for
> the .ONESHELL behavior.

Actually from what I've read it seems more likely to me that they always
intended the -e to be specified, but didn't realize they had explicitly
disallowed this when they wrote the original standard.  The -e flag was
added by applying Austin Group Interpretation 1003.1-2001 #131:
https://www.opengroup.org/austin/interps/uploads/40/14353/AI-131.txt

I do agree it's pretty sucky that they made this change without
considering what it might mean for instances of make that were written
to conform to the old behavior.

> I have to say that this line of argument makes no sense to me. First,
> ISTM that the bit about reducing the need for many continued lines is
> just a slightly sloppy way of saying it reduces the need to type "
> &&\" at the end of each line. In other words I don't think any seismic
> semantic change is being considered here; it's a throwaway line saying
> "we could save some typing if we had this". Second, and more
> important, isn't it already the case that "each logical line in the
> recipe must be a self-enclosed shell recipe"?

I think the miscommunication we are having is that you are proposing a
very specific thing (as your subsequent email says--thanks!), which is a
flag that can be added to an existing, correctly functioning GNU make
makefile which results in identical behavior as before, except with a
single shell to invoke all the commands.  In that environment your
comments above are all correct (although Matt's point about requiring
{...;} is well-taken as well--and you will need to do something about
"@", "-", and "+" prefixes on "internal" lines): if the recipe worked
before then it already contained all the necessary ;\ or &&\ etc.
characters and the issues I raised don't make sense.

What I was thinking about was something that actually added a new
capability to make, that it didn't have before.  Currently, writing
complex recipes is really annoying, since you need to continuously
insert semicolons etc. at the right spots.  I've seen makefiles where
the recipes were 20-30 lines (or more) long, and getting all the syntax
right for that is painful.  If .ONESHELL simply passed the entire recipe
to the shell, unmolested, then these recipes could be written as normal
scripts, then just TAB-indented.

Also, as I alluded to and Eric gave explicit examples of, .ONESHELL is
the second step needed to allow SHELL to be set to something completely
different.  The last step would be something like .SHELLFLAGS.

Obviously these recipes would never work if you removed .ONESHELL, but
that's OK; they wouldn't be intended to work with other versions of
make.

> I assume that line continuations are taken care of early in recipe
> parsing, so that what shows up in file->cmds->commands shows no
> backslash-newline combos.

Actually that's not quite correct (as of 3.81).  Backslash/newline
combos are actually preserved and passed to the shell.  I don't know
that this makes any difference to you, but FYI.  Check out "Splitting
Recipe Lines" in the GNU make manual.

>From your subsequent email:

> Anyway, I hope this clarifies my proposal. From what I see now, it
> seems likely that when the dust settles on the POSIX/set -e issue my
> feature will be trivial to implement. The question would be whether to
> use the .ONESHELL name or something else. So my work here may devolve
> to helping Paul implement the -e stuff.

I hear your requirements.  As I mentioned to Boris earlier today, it
really irks me to implement lots of customization stuff which is only
marginally different.  Keeping track of all the ways these things can be
set, unset, interact with each other, both in the code and during
testing, etc. is just a major hassle.  So, personally, I feel it would
be suboptimal to implement
both .PASS_ALL_LINES_TO_A_SINGLE_SHELL_WITH_AMPERSANDS and .ONESHELL.

I would be much happier if we could find a way to implement .ONESHELL so
it satisfies both your requirements (that it be usefully applied to
existing makefiles without changing their semantics), plus makes it
possible to do things other people would like to do (simplified recipe
creation, and even replacing POSIX sh with some other interpreter).

It seems to me that we might be able to get close to this, with the
following changes:

     1. Add -e to the shell invocation by default if .POSIX is set.
     2. Use the simple "pass the entire thing to the shell, unmodified"
        version of the .ONESHELL implementation.

After this, adding both .POSIX and .ONESHELL (could be easily done by
setting a MAKEFILES environment variable to a file containing those
targets, before invoking make) will get you very nearly what you are
looking for, I think.

What are the issues we still face here?  I think they are:

     1. Adding -e impacts not just the "connections" between (what used
        to be) individual recipe lines, but also the content of those
        recipe lines, which might change some behavior.  However,
        mitigating this is that no portable makefile can assume that -e
        is or is not present, because common implementations of make
        exist with it both ways.  So this MIGHT cause a change in
        behavior in a few GNU make-only makefiles, but it should not be
        widespread at all.
     2. We still have to decide what to do about control characters on
        2nd and subsequent recipe lines ("@", "-", and "+").  Even
        though I argued for not modifying ANYTHING in the recipe
        if .ONESHELL was set, we may need to make an exception here; I
        can't see any good way to allow your requirements for .ONESHELL
        (that it can work on existing makefiles without changes) without
        handling this problem.






reply via email to

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