Previous: Standard Targets, Up: Makefile Conventions


7.2.6 Install Command Categories

When writing the install target, you must classify all the commands into three categories: normal ones, pre-installation commands and post-installation commands.

Normal commands move files into their proper places, and set their modes. They may not alter any files except the ones that come entirely from the package they belong to.

Pre-installation and post-installation commands may alter other files; in particular, they can edit global configuration files or data bases.

Pre-installation commands are typically executed before the normal commands, and post-installation commands are typically run after the normal commands.

The most common use for a post-installation command is to run install-info. This cannot be done with a normal command, since it alters a file (the Info directory) which does not come entirely and solely from the package being installed. It is a post-installation command because it needs to be done after the normal command which installs the package's Info files.

Most programs don't need any pre-installation commands, but we have the feature just in case it is needed.

To classify the commands in the install rule into these three categories, insert category lines among them. A category line specifies the category for the commands that follow.

A category line consists of a tab and a reference to a special Make variable, plus an optional comment at the end. There are three variables you can use, one for each category; the variable name specifies the category. Category lines are no-ops in ordinary execution because these three Make variables are normally undefined (and you should not define them in the makefile).

Here are the three possible category lines, each with a comment that explains what it means:

             $(PRE_INSTALL)     # Pre-install commands follow.
             $(POST_INSTALL)    # Post-install commands follow.
             $(NORMAL_INSTALL)  # Normal commands follow.

If you don't use a category line at the beginning of the install rule, all the commands are classified as normal until the first category line. If you don't use any category lines, all the commands are classified as normal.

These are the category lines for uninstall:

             $(PRE_UNINSTALL)     # Pre-uninstall commands follow.
             $(POST_UNINSTALL)    # Post-uninstall commands follow.
             $(NORMAL_UNINSTALL)  # Normal commands follow.

Typically, a pre-uninstall command would be used for deleting entries from the Info directory.

If the install or uninstall target has any dependencies which act as subroutines of installation, then you should start each dependency's commands with a category line, and start the main target's commands with a category line also. This way, you can ensure that each command is placed in the right category regardless of which of the dependencies actually run.

Pre-installation and post-installation commands should not run any programs except for these:

     [ basename bash cat chgrp chmod chown cmp cp dd diff echo
     egrep expand expr false fgrep find getopt grep gunzip gzip
     hostname install install-info kill ldconfig ln ls md5sum
     mkdir mkfifo mknod mv printenv pwd rm rmdir sed sort tee
     test touch true uname xargs yes

The reason for distinguishing the commands in this way is for the sake of making binary packages. Typically a binary package contains all the executables and other files that need to be installed, and has its own method of installing them—so it does not need to run the normal installation commands. But installing the binary package does need to execute the pre-installation and post-installation commands.

Programs to build binary packages work by extracting the pre-installation and post-installation commands. Here is one way of extracting the pre-installation commands (the -s option to make is needed to silence messages about entering subdirectories):

     make -s -n install -o all \
           PRE_INSTALL=pre-install \
           POST_INSTALL=post-install \
           NORMAL_INSTALL=normal-install \
       | gawk -f pre-install.awk

where the file pre-install.awk could contain this:

     $0 ~ /^(normal-install|post-install)[ \t]*$/ {on = 0}
     on {print $0}
     $0 ~ /^pre-install[ \t]*$/ {on = 1}