Check out my first novel, midnight's simulacra!
GNU Make: Difference between revisions
From dankwiki
No edit summary |
(fix link to bash) |
||
(2 intermediate revisions by the same user not shown) | |||
Line 19: | Line 19: | ||
** 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 | * [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) | ** Unlike most variables, it cannot be inherited from the environment (except on Windows, where it is) | ||
Line 25: | Line 25: | ||
* Arguments to the shell can be specified via <tt>.SHELLFLAGS</tt> | * 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 | ** 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 | * Remember that errors in the body of a shell loop don't set the overall return value: | ||
target: | <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. |
Latest revision as of 17:52, 17 February 2012
Important 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.
- 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.
- By adding .DELETE_ON_ERROR to the Makefile, this becomes the default behavior.
- kill -9'ing make will prevent this from happening! :/
- gcc and some other tools will clean up on error, for some cases. Use .DELETE_ON_ERROR to be safe.
.PHONY:
- GNU Make manual section 4.6, "Phony Targets"
- clean, all, test targets ought almost always be .PHONY
.DEFAULT:
- GNU Make manual section 10.6, "Defining Last Resort Rules"
Make and subversion
- After running make in a pristine tree, the output of svn status ought be empty. Use svn:ignore properties to ignore your generated files.
- Most importantly, svn status 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 svn:ignore is properly used, the following rule suffices as a project-independent clean target, assuming the presence of xmlstarlet:
svn --xml --no-ignore status | xmlstarlet sel -t -m //entry -i "wc-status[@item='ignored']" -v @path -n | xargs rm -rf
bash interactions
- The shell to use can be specified via $(SHELL). By default, /bin/sh 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 it can be
- Arguments to the shell can be specified via .SHELLFLAGS
- By default, it's -c, or -ec in POSIX mode
- Remember that errors in the body of a shell loop don't set the overall return value:
target: while true ; do false ; done
This recipe cannot be successfully completed! You can use
target: set -e ; while true ; do false ; done
or
target: while true ; do false || exit ; done
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.