At Fri, 5 Mar 2010 11:01:35 -0600, Eric Haszlakiewicz <erh%nimenees.com@localhost> wrote: Subject: Re: [ANALYSED] kernel object compilation failure unnoticed ? > > On Fri, Mar 05, 2010 at 05:33:33PM +0100, Joerg Sonnenberger wrote: > > On Fri, Mar 05, 2010 at 04:26:55PM +0000, David Holland wrote: > > > PEOPLE: YOU NEED "|| exit 1" WHEN WRITING COMPLEX SHELL STUFF IN MAKE > > > RECIPES. > > > > ...or prefix them with set -e. > > Perhaps it would be better to cause make to always run /bin/sh with -e? > (Or, for compatibility, only when a Makefile has some particular variable set) > I could have sworn it did that already, but maybe I'm thinking of something > other than bmake. Indeed I believe other versions of "make" do use "sh -e" (when using "sh", that is, as it isn't always used). Of course if "make -i" is used, then "sh" should not be passed "-e". But then there was this discussion: http://mail-index.netbsd.org/tech-toolchain/2004/05/05/0008.html So, NetBSD's did once too. See also FreeBSD PR # 66357 and the related discussion on their lists. FYI, apparently GNU Make does not use "sh -e" either. On the other hand David is 100% correct. Explicit tests for error codes in Makefile rules, and appropriate handling (eg. with "exit 1") is always the safest and most understandable and maintainable way to do things. The only problem I've had with both the elimination of "sh -e" and other trickery make uses to avoid using "sh" when possible is that this is all very confusing. It's hard sometimes even for an expert to understand the difference between a "complex shell" command and a simple one and to know intuitively when make will see a non-zero exit code from the rule and when it will not. To eliminate all possibility of surprises it seems to me that the same result should happen regardless of whether make executes a multi-line script one line at a time or all at once through a single shell invocation: all: all-1 all-2 all-1: true; \ false; \ true; \ echo "you should not see this! (but you will)" all-2: true; false; true; echo "you should not see this either!" Conceptually this is the same as if all rules were always passed wholesale to "sh" as if they were stand-alone scripts, complete with all the newlines so that insertion of semicolon separators would not be necessary. Indeed a naive user might expect "make" to do the same for both these rules, as from a shell script perspective they are identical: foo: true; false; true bar: true false true The whole idea of direct exec() of single-line rules and multiple direct exec()s of "simple" multi-line rules, all just to save a "sh" exec, seems a little bogus these days, even for huge projects. We already waste orders of magnitude more cycles on extremely over-bloated (obese) compilers and their redundant "lint"-like processing and nattering. It's also too bad that "sh -e" is perhaps too blunt a tool to use for this, though the rare examples I've seen of its failure usually result from extreme complexity and perhaps unnecessary fragility. FYI, one example of how confusing it can be to know when "sh" is used and when it is not, consider that NetBSD's "make" does not seem to know that "~" is a special shell character. Try the following Makefile with both NetBSD make and GNU Make and compare the output: all: echo HOME=$$HOME echo ~ echo ~/tmp true && echo ~ true && echo ~/tmp You'll see that GNU Make either knows that "~" is a shell special character, or it always uses "sh" to execute every shell rule; while NetBSD's make doesn't seem to see the tildes on the second and third lines and so they come out un-expanded. -- Greg A. Woods Planix, Inc. <woods%planix.com@localhost> +1 416 218 0099 http://www.planix.com/
Attachment:
pgpXcdCL3ysiG.pgp
Description: PGP signature