automake-1.16: Third-Party Makefiles

 
 22.2 Third-Party ‘Makefile’s
 ============================
 
 In most projects all ‘Makefile’s are generated by Automake.  In some
 cases, however, projects need to embed subdirectories with handwritten
 ‘Makefile’s.  For instance, one subdirectory could be a third-party
 project with its own build system, not using Automake.
 
    It is possible to list arbitrary directories in ‘SUBDIRS’ or
 ‘DIST_SUBDIRS’ provided each of these directories has a ‘Makefile’ that
 recognizes all the following recursive targets.
 
    When a user runs one of these targets, that target is run recursively
 in all subdirectories.  This is why it is important that even
 third-party ‘Makefile’s support them.
 
 ‘all’
      Compile the entire package.  This is the default target in
      Automake-generated ‘Makefile’s, but it does not need to be the
      default in third-party ‘Makefile’s.
 
 ‘distdir’
      Copy files to distribute into ‘$(distdir)’, before a tarball is
      constructed.  Of course this target is not required if the
      ‘no-dist’ option (⇒Options) is used.
 
      Hook::) will be passed from the outer package to the subpackage
      when the ‘distdir’ target is invoked.  These two variables have
      been adjusted for the directory that is being recursed into, so
      they are ready to use.
 
 ‘install’
 ‘install-data’
 ‘install-exec’
 ‘uninstall’
      Install or uninstall files (⇒Install).
 
 ‘install-dvi’
 ‘install-html’
 ‘install-info’
 ‘install-ps’
 ‘install-pdf’
      Install only some specific documentation format (⇒Texinfo).
 
 ‘installdirs’
      Create install directories, but do not install any files.
 
 ‘check’
 ‘installcheck’
      Check the package (⇒Tests).
 
 ‘mostlyclean’
 ‘clean’
 ‘distclean’
 ‘maintainer-clean’
      Cleaning rules (⇒Clean).
 
 ‘dvi’
 ‘pdf’
 ‘ps’
 ‘info’
 ‘html’
      Build the documentation in various formats (⇒Texinfo).
 
 ‘tags’
 ‘ctags’
      Build ‘TAGS’ and ‘CTAGS’ (⇒Tags).
 
    If you have ever used Gettext in a project, this is a good example of
 how third-party ‘Makefile’s can be used with Automake.  The ‘Makefile’s
 that ‘gettextize’ puts in the ‘po/’ and ‘intl/’ directories are
 handwritten ‘Makefile’s that implement all of these targets.  That way
 they can be added to ‘SUBDIRS’ in Automake packages.
 
    Directories that are only listed in ‘DIST_SUBDIRS’ but not in
 ‘SUBDIRS’ need only the ‘distclean’, ‘maintainer-clean’, and ‘distdir’
 rules (⇒Conditional Subdirectories).
 
    Usually, many of these rules are irrelevant to the third-party
 subproject, but they are required for the whole package to work.  It’s
 OK to have a rule that does nothing, so if you are integrating a
 third-party project with no documentation or tag support, you could
 simply augment its ‘Makefile’ as follows:
 
      EMPTY_AUTOMAKE_TARGETS = dvi pdf ps info html tags ctags
      .PHONY: $(EMPTY_AUTOMAKE_TARGETS)
      $(EMPTY_AUTOMAKE_TARGETS):
 
    To be clear, there is nothing special about the variable name
 ‘EMPTY_AUTOMAKE_TARGETS’; the name could be anything.
 
    Another aspect of integrating third-party build systems is whether
 they support VPATH builds (⇒VPATH Builds).  Obviously if the
 subpackage does not support VPATH builds the whole package will not
 support VPATH builds.  This in turns means that ‘make distcheck’ will
 not work, because it relies on VPATH builds.  Some people can live
 without this (indeed, many Automake users have never heard of ‘make
 distcheck’).  Other people may prefer to revamp the existing ‘Makefile’s
 to support VPATH.  Doing so does not necessarily require Automake; only
 Autoconf is needed (⇒Build Directories (autoconf)Build
 Directories.).  The necessary substitutions: ‘@srcdir@’, ‘@top_srcdir@’,
 and ‘@top_builddir@’ are defined by ‘configure’ when it processes a
 ‘Makefile’ (⇒Preset Output Variables (autoconf)Preset Output
 Variables.); they are not computed by the Makefile like the
 aforementioned ‘$(distdir)’ and ‘$(top_distdir)’ variables.
 
    It is sometimes inconvenient to modify a third-party ‘Makefile’ to
 introduce the above required targets.  For instance, one may want to
 keep the third-party sources untouched to ease upgrades to new versions.
 
    Here are two other ideas.  If GNU Make is assumed, one possibility is
 to add to that subdirectory a ‘GNUmakefile’ that defines the required
 targets and includes the third-party ‘Makefile’.  For this to work in
 VPATH builds, ‘GNUmakefile’ must lie in the build directory; the easiest
 way to do this is to write a ‘GNUmakefile.in’ instead, and have it
 processed with ‘AC_CONFIG_FILES’ from the outer package.  For example,
 if we assume ‘Makefile’ defines all targets except the documentation
 targets, and that the real ‘check’ target is named ‘test’, we could
 write ‘GNUmakefile’ (or ‘GNUmakefile.in’) like this:
 
      # First, include the real Makefile
      include Makefile
      # Then, define the other targets needed by Automake Makefiles.
      .PHONY: dvi pdf ps info html check
      dvi pdf ps info html:
      check: test
 
    A similar idea that does not use ‘include’ is to write a proxy
 ‘Makefile’ that dispatches rules to the real ‘Makefile’, either with
 ‘$(MAKE) -f Makefile.real $(AM_MAKEFLAGS) target’ (if it’s OK to rename
 the original ‘Makefile’) or with ‘cd subdir && $(MAKE) $(AM_MAKEFLAGS)
 target’ (if it’s OK to store the subdirectory project one directory
 deeper).  The good news is that this proxy ‘Makefile’ can be generated
 with Automake.  All we need are ‘-local’ targets (⇒Extending)
 that perform the dispatch.  Of course the other Automake features are
 available, so you could decide to let Automake perform distribution or
 installation.  Here is a possible ‘Makefile.am’:
 
      all-local:
              cd subdir && $(MAKE) $(AM_MAKEFLAGS) all
      check-local:
              cd subdir && $(MAKE) $(AM_MAKEFLAGS) test
      clean-local:
              cd subdir && $(MAKE) $(AM_MAKEFLAGS) clean
 
      # Assuming the package knows how to install itself
      install-data-local:
              cd subdir && $(MAKE) $(AM_MAKEFLAGS) install-data
      install-exec-local:
              cd subdir && $(MAKE) $(AM_MAKEFLAGS) install-exec
      uninstall-local:
              cd subdir && $(MAKE) $(AM_MAKEFLAGS) uninstall
 
      # Distribute files from here.
      EXTRA_DIST = subdir/Makefile subdir/program.c ...
 
    Pushing this idea to the extreme, it is also possible to ignore the
 subproject build system and build everything from this proxy
 ‘Makefile.am’.  This might sound very sensible if you need VPATH builds
 but the subproject does not support them.