GNU Make: Difference between revisions
Created page with '==.DELETE_ON_ERROR== * Generally, if make fails to build a target, and the target corresponds to a file, you want that file removed. ** Why might this happen? Ctrl-c being presse...' |
fix link to bash |
||
| (4 intermediate revisions by the same user not shown) | |||
| Line 1: | Line 1: | ||
==.DELETE_ON_ERROR== | ==Important [http://www.gnu.org/software/autoconf/manual/make/Special-Targets.html#Special-Targets Special Targets]== | ||
===.DELETE_ON_ERROR=== | |||
* Generally, if make fails to build a target, and the target corresponds to a file, you want that file removed. | * Generally, if make fails to build a target, and the target corresponds to a file, you want that file removed. | ||
** Why might this happen? Ctrl-c being pressed during a build. Multiple statements in a build recipe. Memory allocation failure during build. Any number of things. | ** Why might this happen? Ctrl-c being pressed during a build. Multiple statements in a build recipe. Memory allocation failure during build. Any number of things. | ||
| Line 5: | Line 6: | ||
** <tt>kill -9</tt>'ing <tt>make</tt> will prevent this from happening! :/ | ** <tt>kill -9</tt>'ing <tt>make</tt> will prevent this from happening! :/ | ||
* [[gcc]] and some other tools will clean up on error, for some cases. Use <tt>.DELETE_ON_ERROR</tt> to be safe. | * [[gcc]] and some other tools will clean up on error, for some cases. Use <tt>.DELETE_ON_ERROR</tt> to be safe. | ||
===.PHONY:=== | |||
* GNU Make manual section 4.6, "[http://www.gnu.org/software/autoconf/manual/make/Phony-Targets.html#Phony-Targets Phony Targets]" | |||
* <tt>clean</tt>, <tt>all</tt>, <tt>test</tt> targets ought almost always be <tt>.PHONY</tt> | |||
===.DEFAULT:=== | |||
* GNU Make manual section 10.6, "[http://www.gnu.org/software/autoconf/manual/make/Last-Resort.html Defining Last Resort Rules]" | |||
==Make and [[subversion]]== | ==Make and [[subversion]]== | ||
| Line 10: | Line 18: | ||
** Most importantly, <tt>svn status</tt> should not show any entries in the 'M'odified state. This indicates either generated files being checked into source control, or the build process modifying source in-place (the same thing, really) | ** Most importantly, <tt>svn status</tt> should not show any entries in the 'M'odified state. This indicates either generated files being checked into source control, or the build process modifying source in-place (the same thing, really) | ||
** If <tt>svn:ignore</tt> is properly used, the following rule suffices as a project-independent <tt>clean</tt> target, assuming the presence of [[xmlstarlet]]:<pre>svn --xml --no-ignore status | xmlstarlet sel -t -m //entry -i "wc-status[@item='ignored']" -v @path -n | xargs rm -rf</pre> | ** If <tt>svn:ignore</tt> is properly used, the following rule suffices as a project-independent <tt>clean</tt> target, assuming the presence of [[xmlstarlet]]:<pre>svn --xml --no-ignore status | xmlstarlet sel -t -m //entry -i "wc-status[@item='ignored']" -v @path -n | xargs rm -rf</pre> | ||
==[[bash]] interactions== | |||
* [http://www.gnu.org/s/hello/manual/make/Choosing-the-Shell.html The shell to use] can be specified via $(SHELL). By default, <tt>/bin/sh</tt> is used | |||
** Unlike most variables, it cannot be inherited from the environment (except on Windows, where it is) | |||
** It is not exported by default to sub-Makes, but [http://www.gnu.org/s/hello/manual/make/Variables_002fRecursion.html#Variables_002fRecursion it can be] | |||
* Arguments to the shell can be specified via <tt>.SHELLFLAGS</tt> | |||
** By default, it's <tt>-c</tt>, or <tt>-ec</tt> in POSIX mode | |||
* Remember that errors in the body of a shell loop don't set the overall return value: | |||
<pre>target: | |||
while true ; do false ; done</pre> | |||
This recipe cannot be successfully completed! You can use<pre>target: | |||
set -e ; while true ; do false ; done</pre>or <pre>target: | |||
while true ; do false || exit ; done</pre> | |||
The former is probably nicer, since you can then use ; in the place of &&, but it deviates from expected gmake semantics. In general, you don't want to be doing this kind of thing anyway; it's useful for cases like running unit testing on a set of inputs, where outputs won't be generated. | |||