Next: Command Variables, Previous: Makefile Basics, Up: Makefile Conventions
We have to segregate between installer goals and
maintainer goals in Makefiles. The same division
applies to shell scripts. I think GNU maintainers should make every
effort so all
, install
and uninstall
be fully
portable. Those Makefile rules representing an installer goal,
as well as configure files or subsidiary scripts, may not use
non-sh
commands, nor programs outside a specific set.
Installer goals and installer scripts satisfy the needs of
any straight out-of-the-box configuration, compilation,
checking and installation of a GNU package. We should also try making
honest efforts so installers be able to do modify genuine C sources,
or other simple source files, and complete a reinstallation by using
nothing else than installer goals.
However, some other goals require special tools. For example,
dvi
requires TeX
and texi2dvi
. Goals meant
specifically meant for maintainers, like dist
, may rely on many
GNU programs, like GNU tar
, GNU date
, GNU make
maybe, who knows, and surely, a proper shell. The maintainer has a
lot of freedom, here. If your shell is improper while dist
works for the maintainer using GNU bash
, this should not be
perceived as a bug. Installers may have to acquire and install proper
tools. dist
is surely not a goal meant for usual installers of
GNU packages, and does not need to show the same level of portability
as usual goals, it does not have to take care for all and every broken
situation out there. If a script or rule uses commands or programs
outside the prescribed set, it has to be related to a maintainer goal.
Maintainer goals and maintainer scripts allow for
modification of a Texinfo source, a Bison grammar,
configure.in, any Makefile.am, or in fact, any other
kind of genuine source from which distributed files were derived by
the maintainer. Installers may not just modify anything in a
GNU distribution, and still expect a reinstallation without any
special tools pre-installed first.
GNU packages might show unequal complexity in the source dependencies. It would be preferrable that all goals be available to all installer, of course, yet maintainer goals should not be redesigned as installer goals at the expense of the maintainability of the package.
A few shell constructs call for further comments, given a bit randomly, here.
echo
false
true
The allowable set of programs is repeated in full below, as most of these programs call for further comments.
cat
cmp
cp
mv
diff
echo
echo
s. In particuler, never
use `\c' for preventing the new line at the end of echoed text.
There is a feature by which, when echo
has many arguments, they
are all echoed one after the other, separated by a single space. It
looks neater to us when this feature is not abused. Prefer using a
single argument with the proper spacing included, even if this means
using surrouding quotes. It also better prepares scripts for later
internationalization. For example, the second line below should be
preferred:
echo Some famous last words: echo 'Some famous last words:'
If you really need to control suppression new lines, you might have to
configure out explicitly how echo
behaves. This surely
requires some doing, so it might often be simple to just avoid the
need if you can. Here is how shar
does it in its generated
archive scripts (the trick originated in Autoconf):
if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then shar_n= shar_c=' ' else shar_n=-n shar_c= fi else shar_n= shar_c='\c' fi
and usage of echo
, once configuration done, looks like:
echo $shar_n 'Question [no, yes] (no)?' $shar_c
Internationalization of shell scripts is closely related to usage of
echo
.
expr
expr
,
which are not as universal as its arithmetic capabilities. If you
need matching only for recognizing patterns, without any substitution,
merely base your code on the case
construct of Bourne shells.
If you need pattern matching with substitution, rather use sed
.
grep
egrep
install-info
ln
ls
mkdir
rmdir
pwd
rm
rm
call in a Makefile action (for suppressing the examination of
the return code).
sed
sed
scripts for separating successive
sed
commands is explicitely allowed. Autoconf already use this
feature, bearing the experience that this is portable.
sleep
sort
tar
test
[
form of the test
program or shell
construct in portable scripts or Makefiles.
Allowable options for testing strings are `-n', `-z', `!=' and `='. It is not allowable to have `-n' implied by the mere presence of a string, the `-n' has to be explicitly written. Allowable options for testing files are `-f', `-r' and `-w'.
Option `-x', for checking if a file is executable, is not available on all systems; use `-f' instead and not `-r', as executable files are not even necessarily readable.
Options `-a' and `-o', implementing logical connectives, are not universally available either, and not always implemented the same way respective to priorities. Use shell logical connectives instead. For example, the two following lines are usually equivalent, yet the second form should always be preferred:
if test -f README -a -f NEWS; then if test -f README && test -f NEWS; then
touch
true
false
true
is not really needed, and the sh
construct `:' does just as well, so true
is to be avoided
in practice. Automake complies with this part of Gnits Standards.
We also think that false
can be completely avoided. Please try
avoiding it.