Subject: Re: make -j and failure modes
To: Robert Elz <kre@munnari.OZ.AU>
From: James Chacon <jmc@NetBSD.org>
List: tech-userlevel
Date: 12/10/2003 12:53:24
On Thu, Dec 11, 2003 at 01:26:35AM +0700, Robert Elz wrote:
> Date: Wed, 10 Dec 2003 10:45:04 -0600
> From: James Chacon <jmc@NetBSD.org>
> Message-ID: <20031210164503.GA6589@netbsd.org>
>
> | Both of these are excluded from -e tests anyways. It lists exceptions for
> | AND and OR.
>
> Yes, it also explicitly says just "simple commands".
> Then it goes on and excludes even some of those, so it isn't
> even all simple commands (but certainly nothing which isn't simple
> counts, and a compound command certainly is not simple).
This is where the syntax is non-exact. If it only applies to simple commands,
why bother to list exceptions for things that aren't even simple commands
to begin with (ala the IF/WHILE etc tests).
> | For what reason? The command in question exited non-zero for some reason.
> | Whatever the reason was it's concern. The parent process though is set to
> | exit (via -e) for anything that returns non-zero and this would meet that
> | criteria since it isn't in the exception list for -e.
>
> Then how would you handle a Makefile that happened to contain
>
> (cd dir && test -f file && cat file)
>
> If file doesn't exist, that will exit 1, as the last command
> executed is te test, which failed (same if dir doesn't exist).
>
> But that isn't what is wanted - the intent there is simply to cat
> the file, if it exists, and do nothing if it doesn't.
>
Hmmm..Ok. I buy this one. I agree where you're going now. Just took a better
example to get me there :-)
> This is why the && exception exists in the rules - nothing else makes
> sense. How can doing it in a sub-shell (needed so the cd doesn't
> change the parent shell) possibly be intended to change the result?
> That makes no sense.
Based on the above I see this now.
>
> | No. It was the subshell exiting non-zero that's being ignored.
> | Run a make rule of
> |
> | all:
> | (false)
> | echo foo
> |
> | via make -j (which feeds that into sh -ev) and echo foo will be printed.
> | Not exactly expected behavior from make at all.
>
> No. But that is make's problem.
> Not the shells - make is using sh incorrectly.
Due to the feeding into sh, yes.
>
> Make -j is simply broken (in yet another way) - just avoid it.
Actually I can't find other ways it's not working correctly (as long as
proper analysis of your Makefiles has been done and .WAIT's added
appropriately).
This is fixed via adding '|| exit $?' as Ben suggested so I'll probably start
reviewing Makefiles for this shortly. In addition the man page for make
needs a much clearer explanation of the implications of -j and command
execution (since non-compat mode is different than traditional make in this
respect with all the commands flowing through 1 shell instance).
James