Autoconf, Automake, and Libtool: 14.3 Install hooks

| ## 14.3 Install hooks As with `dist`, the install process allows for generic targets which can be used when the existing install functionality is not enough. There are two types of targets which can be used: local rules and hooks. A local rule is named either `install-exec-local` or `install-data-local`, and is run during the course of the normal install procedure. This rule can be used to install things in ways that Automake usually does not support. For instance, in `libgcj` we generate a number of header files, one per Java class. We want to install them in ``pkgincludedir'`, but we want to preserve the hierarchical structure of the headers (e.g., we want ``java/lang/String.h'` to be installed as ``$(pkgincludedir)/java/lang/String.h'`, not ``$(pkgincludedir)/String.h'`), and Automake does not currently support this. So we resort to a local rule, which is a bit more complicated than you might expect:
    install-data-local:
            @for f in $(nat_headers) $(extra_headers); do \
    ## Compute the install directory at runtime.
              d="echo $$f | sed -e s,/[^/]*$$,,'"; \
    ## Make the install directory.
              $(mkinstalldirs) $(DESTDIR)$(includedir)/$$d; \
    ## Find the header file -- in our case it might be in srcdir or
    ## it might be in the build directory.  "p" is the variable that
    ## names the actual file we will install.
              if test -f $(srcdir)/$$f; then p=$(srcdir)/$$f; else p=$$f; fi; \
    ## Actually install the file.
              $(INSTALL_DATA) $$p $(DESTDIR)$(includedir)/$$f; \
            done
A hook is guaranteed to run after the install of objects in this directory has completed. This can be used to modify files after they have been installed. There are two install hooks, named `install-data-hook` and `install-exec-hook`. For instance, suppose you have written a program which must be `setuid` root. You can accomplish this by changing the permissions after the program has been installed:
    bin_PROGRAMS = su
    su_SOURCES = su.c

    install-exec-hook:
            chown root $(bindir)/su
            chmod u+s $(bindir)/su
Unlike an install hook, and install rule is not guaranteed to be after all other install rules are run. This lets it be run in parallel with other install rules when a parallel `make` is used. Ordinarily this is not very important, and in practice you almost always see local hooks and not local rules. The biggest caveat to using a local rule or an install hook is to make sure that it will work when the source and build directories are not the same--many people forget to do this. This means being sure to look in ``$(srcdir)'` when the file is a source file. It is also very important to make sure that you do not use a local rule when install order is important -- in this case, your ``Makefile'` will succeed on some machines and fail on others.

This document was generated by Gary V. Vaughan on February, 8 2006 using texi2html