Re: .ONESHELL enhancement?
David Boyce <[email protected]>
| Newsgroups | gmane.comp.gnu.make.devel |
|---|---|
| Message-ID | <[email protected]> |
I'm going to try to cut the Gordian knot on at least my little corner of this (the .ONESHELL suggestion) by clarifying and deepening the background. This does not necessarily address the bigger questions of set -e and POSIX and so on, though there seems a good chance of finding synergy. So, two points: 1. The thing I'm offering to work on is specifically the feature whereby lines get joined together with an implicit && (or newline in the presence of -e) without unduly changing makefile semantics. I referred to this feature as .ONESHELL because it seemed to me clear that they're the same thing, and it made sense to use the suggested name. However, if there's legitimate debate about the intended meaning of .ONESHELL I'd rather change the name than join the debate. I'm not offering to implement .ONESHELL regardless of its semantics, I'm offering to implement certain semantics regardless of the name, so I'm happy to call the feature .PASS_ALL_LINES_TO_A_SINGLE_SHELL_WITH_AMPERSANDS if need be. I think there is a legitimate reason for the feature I propose, as elucidated below. 2. Perhaps explaining some background will help focus the discussion. I'm developing a build-auditing tool which I hope to release under GPL quite soon. It's working nicely already, and in particular it works well with GNU make. But there's a misfeature of make programs in general which causes it to behave sub-optimally. I can't address this problem everywhere but I'd like to be able to address it in the most widespread version: GNU make. The following is a common make idiom (taken from a build of bash-3.2 FWIW): charset.alias: /bin/sh ./config.charset 'i386-pc-solaris2.10' > t-charset.alias mv t-charset.alias charset.alias Looking at the makefile, as a human would do, it's obvious that "t-charset.alias" is a temp file and that the result is the single file "charset.alias". Or to put it differently, it's clear from the makefile that the two lines are part of the same logical recipe. But when looking only at the process tree, as the build auditor does, there's no indication that the two commands are related at all. The process tree comes with no marking indicating "recipe boundaries", so we have to take these as two separate commands which are not known to be related. This doesn't break the auditing, by the way, it just causes the auditor to have a less intelligent understanding of what's going on. I've spent a little time trying to work out a solution for this. For instance, I considered trying to have make export $@ to the environment, so that each command in a recipe would know its final goal and their results could be collated based on that. But it seemed more elegant and less intrusive to implement (my conception of) .ONESHELL. For one thing, it provides benefits to the larger community, not just that subset which might use the auditor. The main point here is that though .ONESHELL may provide measurable performance benefits, my motivation is in the atomicity of treating a recipe as a logical unit. When the auditor sees in the process tree something like sh -c "touch foo && mv foo bar" it can figure out exactly what's going on. There's no magic in the &&; what matters is having a common and exclusive parent process. Of course a workaround is to "fix" your makefile: charset.alias: /bin/sh ./config.charset 'i386-pc-solaris2.10' > t-charset.alias &&\ mv t-charset.alias charset.alias which IMHO is almost always better anyway, but getting people to fix their makefiles is like bailing with a thimble. 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. DSB