Next: , Previous: Makefile Basics, Up: Makefile Conventions


7.2.2 Utilities in Makefiles

See Utilities in Makefiles.

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
These may be processed especially by some shells, and also available as separate programs. We consider the later hypothesis, and rather discuss these in the table following this one, below.

The allowable set of programs is repeated in full below, as most of these programs call for further comments.

cat
No options allowed.
cmp
Always use with option `-s' and depend on the return status, not on the fact output was produced or not.
cp
mv
No options allowed.
diff

echo
No options allowed. Do not depend on special escape sequences, which are not equally supported in all echos. 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
You should not use the pattern matching facilities of 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
The only allowable option is `-v'.
install-info

ln
No options allowed.
ls

mkdir
rmdir
No options allowed.
pwd
No options allowed.
rm
The only allowable option are `-f' and `-r'. The `-f' option should be preferred over using a `-' before the rm call in a Makefile action (for suppressing the examination of the return code).
sed
Usage of semi-colons in 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
Never, ever use the [ 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
No options allowed.
true
false
The program 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.